【发布时间】:2016-08-09 10:13:09
【问题描述】:
我试图找到高度和宽度的值,以使用下面代码的图像轮廓恢复对象的纵横比,但没有成功,因为代码在整个图像上创建了许多矩形,当我的意图是在对象周围创建一个矩形时。 我正在尝试创建这个矩形,因为我不知道除了这个之外是否还有其他方法可以获取高度和宽度(甚至是纵横比)。
***RNG rng(12345); //全局变量,用于为图像的轮廓绘制矩形和圆形。
/*Load the image*/
Mat img_bgr = imread("img.jpg", 1);
if (img_bgr.empty()){
cout << "No image..." << endl;
return -1;
}
/*Display the image*/
namedWindow("Original Image", WINDOW_NORMAL);
imshow("Original Image", img_bgr);
/*Conversion to HSV*/
Mat img_hsv;
cvtColor(img_bgr, img_hsv, CV_BGR2HSV);
/*Extracting colors - HSV*/
Mat green, yellow, brown;
//Yellow
inRange(img_hsv, Scalar(25, 0, 0), Scalar(36, 255, 255), yellow); //until 33 - consider "yellow" - from there up to 36 - consider for chlorosis
imwrite("c:\\test\\results\\yellow.jpg", yellow);
//Green
inRange(img_hsv, Scalar(37, 0, 0), Scalar(70, 255, 255), green); //Consider lower as 37
imwrite("c:\\test\\results\\green.jpg", green);
//Brown
inRange(img_hsv, Scalar(10, 0, 0), Scalar(20, 255, 255), brown);
imwrite("c:\\test\\results\\brown.jpg", brown);
namedWindow("Yellow", WINDOW_NORMAL);
imshow("Yellow", yellow);
namedWindow("Green", WINDOW_NORMAL);
imshow("Green", green);
namedWindow("Brown", WINDOW_NORMAL);
imshow("Brown", brown);
/*Finding Contours of the Thresholded images*/
vector<std::vector<Point>>green_cnt;
vector<std::vector<Point>>yellow_cnt;
vector<std::vector<Point>>brown_cnt;
//Green Contour
findContours(green, green_cnt, CV_RETR_TREE, CV_CHAIN_APPROX_NONE);
//Draw the Contours - Green
Mat green_cnt_draw(green.size(), CV_8UC3, Scalar(0, 0, 0));
Scalar green_cnt_colors[3];
green_cnt_colors[0] = Scalar(0, 255, 0);
green_cnt_colors[1] = Scalar(0, 255, 0);
green_cnt_colors[2] = Scalar(0, 255, 0);
for (size_t idx_green = 0; idx_green < green_cnt.size(); idx_green++){
drawContours(green_cnt_draw, green_cnt, idx_green, green_cnt_colors[idx_green % 3]);
}
namedWindow("Green - Contours", CV_WINDOW_NORMAL);
imshow("Green - Contours", green_cnt_draw);
//Yellow Contour
findContours(yellow, yellow_cnt, CV_RETR_TREE, CV_CHAIN_APPROX_NONE);
//Draw the Contours - Yellow
Mat yellow_cnt_draw(yellow.size(), CV_8UC3, Scalar(0, 0, 0));
Scalar yellow_cnt_colors[3];
yellow_cnt_colors[0] = Scalar(0, 255, 255);
yellow_cnt_colors[1] = Scalar(0, 255, 255);
yellow_cnt_colors[2] = Scalar(0, 255, 255);
for (size_t idx_yellow = 0; idx_yellow < yellow_cnt.size(); idx_yellow++){
drawContours(yellow_cnt_draw, yellow_cnt, idx_yellow, yellow_cnt_colors[idx_yellow % 3]);
}
namedWindow("Yellow - Contours", CV_WINDOW_NORMAL);
imshow("Yellow - Contours", yellow_cnt_draw);
//Brown Contour
findContours(brown, brown_cnt, CV_RETR_TREE, CV_CHAIN_APPROX_NONE);
//Draw the Contours - Brown
Mat brown_cnt_draw(brown.size(), CV_8UC3, Scalar(0, 0, 0));
Scalar brown_cnt_colors[3];
brown_cnt_colors[0] = Scalar(42, 42, 165);
brown_cnt_colors[1] = Scalar(42, 42, 165);
brown_cnt_colors[1] = Scalar(42, 42, 165);
for (size_t idx_brown = 0; idx_brown < brown_cnt.size(); idx_brown++){
drawContours(brown_cnt_draw, brown_cnt, idx_brown, brown_cnt_colors[idx_brown % 3]);
}
namedWindow("Brown - Contours", CV_WINDOW_NORMAL);
imshow("Brown - Contours", brown_cnt_draw);
/*Creating rectangles around the contours*/
//Green
vector<vector<Point>>green_contours_poly(green_cnt.size());
vector<Rect>green_boundRect(green_cnt.size());
vector<Point2f>green_center(green_cnt.size());
vector<float>green_radius(green_cnt.size());
for (int i = 0; i < green_cnt.size(); i++){
approxPolyDP(Mat(green_cnt[i]), green_contours_poly[i], 3, true);
green_boundRect[i] = boundingRect(Mat(green_cnt[i]));
minEnclosingCircle((Mat)green_contours_poly[i], green_center[i], green_radius[i]);
}
//Green - Draw polygonal contour AND bounding rects + circles
Mat green_drawRecAndCirc = Mat::zeros(green.size(), CV_8UC3);
for (int i = 0; i < green_cnt.size(); i++){
Scalar green_drawRecAndCircColor = Scalar(rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255));
rectangle(green_drawRecAndCirc, green_boundRect[i].tl(), green_boundRect[i].br(), green_drawRecAndCircColor, 2, 8, 0);
//circle(green_drawRecAndCirc, green_center[i], (int)green_radius[i], green_drawRecAndCircColor, 2, 8, 0);
}
imwrite("c:\\testeimagem\\theeye\\resultados\\green_rectangle_and_circle.jpg", green_drawRecAndCirc);
namedWindow("Green - Rectangle and Circle", CV_WINDOW_NORMAL);
imshow("Green - Rectangle and Circle", green_drawRecAndCirc);
/*Creating rectangles around the contours*/
//Yellow
vector<vector<Point>>yellow_contours_poly(yellow_cnt.size());
vector<Rect>yellow_boundRect(yellow_cnt.size());
vector<Point2f>yellow_center(yellow_cnt.size());
vector<float>yellow_radius(yellow_cnt.size());
for (int i = 0; i < yellow_cnt.size(); i++){
approxPolyDP(Mat(yellow_cnt[i]), yellow_contours_poly[i], 3, true);
yellow_boundRect[i] = boundingRect(Mat(yellow_cnt[i]));
minEnclosingCircle((Mat)yellow_contours_poly[i], yellow_center[i], yellow_radius[i]);
}
//Yellow - Draw polygonal contour AND bounding rects + circles
Mat yellow_drawRecAndCirc = Mat::zeros(yellow.size(), CV_8UC3);
for (int i = 0; i < yellow_cnt.size(); i++){
Scalar yellow_drawRecAndCircColor = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
rectangle(yellow_drawRecAndCirc, yellow_boundRect[i].tl(), yellow_boundRect[i].br(), yellow_drawRecAndCircColor, 2, 8, 0);
//circle(green_drawRecAndCirc, green_center[i], (int)green_radius[i], green_drawRecAndCircColor, 2, 8, 0);
}
waitKey(0);
destroyAllWindows;
return 0;
原图在这里:
最终结果的例子在这里:
我尝试了以下链接 (OpenCV Bounding Box) 中描述的示例,但我也无法使其工作。
编辑 2:
由于我必须找到用矩形找不到的叶子的一些特征(例如纵横比、平均直径、半径比、圆度和平均 feret),我不得不改变从矩形中找到叶子的方法到一个椭圆。问题是,椭圆是在叶子内部绘制的,而不是对其进行轮廓绘制。
这是我的代码:
/*Load the image*/
Mat img_bgr = imread("image path", 1);
if (img_bgr.empty()){
cout << "No image found..." << endl;
return -1;
}
/*Conversion to HSV*/
Mat img_hsv;
cvtColor(img_bgr, img_hsv, CV_BGR2HSV);
/*Extracting colors - HSV*/
Mat yellow, green, brown;
//Yellow
inRange(img_hsv, Scalar(25, 80, 80), Scalar(36, 255, 255), yellow);
//Green
inRange(img_hsv, Scalar(37, 80, 80), Scalar(70, 255, 255), green);
//Brown
inRange(img_hsv, Scalar(10, 80, 80), Scalar(30, 200, 200), brown);
// logical OR mask
Mat1b mask = yellow | green | brown;
// Find non zero pixels
vector<Point> pts;
findNonZero(mask, pts);
// Compute ellipse
RotatedRect elipse = fitEllipse(pts);
//ELLIPSE - Heigth, Width and Center of Mass
cout << "ELLIPSE:" << endl;
cout << "\nHeight and Width: " << elipse.size; //Height and Width
cout << "\nCenter of Mass: " << elipse.center << endl; //Center of mass (probably given in X and Y coordinates)
// Show Ellipse
ellipse(img_bgr, elipse, Scalar(0, 0, 255), 3);
namedWindow("Ellipse", CV_WINDOW_NORMAL);
imshow("Ellipse", img_bgr);
waitKey(0);
destroyAllWindows;
return 0;
结果如下图:
我不明白自己做错了什么,因为我刚刚更改了用户 Miki 提供的代码,并且实际上运行良好。
【问题讨论】:
-
你需要“一个大盒子来统治他们”...
-
你好,卡尔。我看到您是我发布的链接中提到的解决方案的作者。请随时与我们分享您的经验和知识。
标签: c++ opencv image-processing shape image-recognition