Я пытаюсь найти значения для Height и Width для восстановления Aspect Ration объекта, используя контур изображения с приведенным ниже кодом, но не имеющий успеха, поскольку код создает много прямоугольников по всему изображению, когда я намерен создать единый прямоугольник вокруг объекта. Я пытаюсь создать этот прямоугольник, потому что я не знаю, есть ли другой способ получить Height и Width (или даже Aspect Ratio), кроме этого.OpenCV - Поиск высоты и ширины контурного изображения
*** 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:
Так как я должен найти некоторые характеристики листа, которые я не могу найти с прямоугольником (например, соотношение сторон, средний диаметр, отношение радиуса, округлость и среднее Фере) я должен был изменить подход поиска листа от прямоугольника до эллипса. Дело в том, что эллипс рисуется внутри листовой интуиции контура.
Вот мой код:
/*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 дал, и это действительно работает отлично.
Вам нужно * «одна большая коробка, чтобы управлять ими» * ... – karlphillip
Привет Карл. Я вижу, что вы являетесь автором решения, упомянутого в ссылке, которую я опубликовал. Пожалуйста, не стесняйтесь делиться своим опытом и знаниями с нами. – Nicholas