В этом проекте, я должен соответствовать много различных изображений листьев (по одному за раз) внутри эллипса, чтобы получить следующую информацию:OpenCV - Установка листьев внутри контура fitEllipse()
1) Соотношение сторон;
2) Средний диаметр, измеряющий диаметр на каждые 2 градуса;
3) Радиус действия;
4) округлость;
5) Средний Фере.
Проблема заключается в следующем: когда я пытаюсь поместить объект внутри эллипса, эллипс действительно нарисован внутри него, и из-за этого высота и ширина объекта неверны. Я не могу понять, что я делаю неправильно, так как я использую findNonZero(), чтобы получить только части изображения, на самом деле есть пиксели.
Вот мой код:
/*Load the image*/
Mat img_bgr = imread("image path", 1);
if (img_bgr.empty()){
cout << "No image found..." << endl;
return -1;
}
/*Display the image*/
namedWindow("Original Image", WINDOW_NORMAL);
imshow("Original Image", img_bgr);
waitKey(0);
/*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);
/*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);
waitKey(0);
//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);
waitKey(0);
//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);
waitKey(0);
destroyAllWindows;
// 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;
EDIT 1:
В ответ на вопрос, сделанные пользователем, я» я решил отредактировать главный пост вместо простого ответа без новых изображений, чтобы проиллюстрировать ситуацию.
Маска после findCountours() выглядит следующим образом:
С или без контуров, конечный результат всегда один и тот же.
EDIT 2:
После решения данного пользователя sietschie, я пытался реализовать свой код, который доступен here, но получается, что я всегда получаю ошибку при линия 105. сообщение, показанная в командной строке:
OpenCV Ошибка: Неправильный размер входного массива (количество точек должно быть> = 5) в cvFitEllipse2, файл с: \ \ строит 2_4_Pac kSlave-win64-VC12-Shared \ OpenCV \ модули \ imgproc \ src.cpp, строка 799
Я до сих пор не могу понять, что я сделал неправильно, так как это то же самое случилось, что он писал и работал, как он показал результат. Для того, чтобы попытаться понять, что происходит, я получил изображение контура (строка 104), и это на самом деле выглядит довольно странно:
ли вы посмотрите на то, что 4 Маты выглядеть после этой строки: 'Mat1b маски = желтый | зеленый | коричневый цвет; '? ** findContours (...) ** изменяет входное изображение неопределенным способом. –