问题:
有这样一幅图:
- 我们希望抠出手掌mask,
- 并用findContours找到上下左右的极值点。
代码实现:
cv::Mat src = cv::imread("C:\\D\\opencv\\hand.jpg", -1);
cv::Mat gray;
cv::cvtColor(src, gray, cv::COLOR_BGR2GRAY);
// GaussianBlur
cv::GaussianBlur(gray, gray, cv::Size(5, 5), 0);
cv::Mat binary, erode_mat, dilate_mat;
cv::threshold(gray, binary, 45, 255, cv::THRESH_BINARY);
cv::erode(binary, erode_mat, cv::Mat(), cv::Point(-1, -1), 2);
cv::dilate(erode_mat, dilate_mat, cv::Mat(), cv::Point(-1, -1), 2);
std::vector<std::vector<Point>> contours;
cv::findContours(dilate_mat, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
//计算最大轮廓面积
int maxarea_index = 0;
float maxarea = 0;
for (auto i = 0; i < contours.size(); i++) {
float area = cv::contourArea(contours[i]);
if (maxarea < area) {
maxarea = area;
maxarea_index = i;
}
}
int top_num(0), down_num(0), left_num(0), right_num(0);
Point2f top_p, down_p, left_p, right_p;
for (auto i = 0; i < contours[maxarea_index].size(); i++) {
Point2f tep_p = contours[maxarea_index][i];
if (i == 0) {
left_num = tep_p.x;
left_p = tep_p;
top_num = tep_p.y;
top_p = tep_p;
}
// 极左点
if (tep_p.x < left_num) {
left_num = tep_p.x;
left_p = tep_p;
}
//极下点
else if (tep_p.y > down_num) {
down_num = tep_p.y;
down_p = tep_p;
}
//极上点
else if (tep_p.y < top_num) {
top_num = tep_p.y;
top_p = tep_p;
}
//极右点
else if (tep_p.x > right_num) {
right_num = tep_p.x;
right_p = tep_p;
}
}
cv::circle(src, left_p, 7, cv::Scalar(0, 0, 255));
cv::circle(src, right_p, 7, cv::Scalar(0, 0, 255));
cv::circle(src, top_p, 7, cv::Scalar(0, 0, 255));
cv::circle(src, down_p, 7, cv::Scalar(0, 0, 255));
left_num = contours[maxarea_index][0].x;
left_p = contours[maxarea_index][0];
top_num = contours[maxarea_index][0].y;
top_p = contours[maxarea_index][0];
for (auto point : contours[maxarea_index]) {
// 极左点
if (point.x < left_num) {
left_num = point.x;
left_p = point;
}
//极下点
else if (point.y > down_num) {
down_num = point.y;
down_p = point;
}
//极上点
else if (point.y < top_num) {
top_num = point.y;
top_p = point;
}
//极右点
else if (point.x > right_num) {
right_num = point.x;
right_p = point;
}
}
|