iskees 32 Жалоба Опубликовано April 15, 2013 Есть контура в них прямоугольники и еще сбоку сверху или еще где-то прилипший другой контур, причем не факт что там вообще есть прямоугольник. Как проверить есть ли там прямоугольник и выделить его? условия на все дело не больше 3-5мс Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Nuzhny 243 Жалоба Опубликовано April 16, 2013 Найти контуры сразу в аппроксимированном отрезками виде и проверить отрезки на параллельность и точки их пересечения. Сравнить с определением прямоугольника из учебника геометрии. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
stanley_goodspeed 0 Жалоба Опубликовано May 21, 2013 Здравствуйте, подскажите пожалуйста, как можно извлечь точки из контура. Контур найден таким образом: cvFindContours( binI, storage, &contoursI, sizeof(CvContour), CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0)); Далее я пробегаю по всем контурам и нахожу самый похожий на свой заданный контур: CvSeq* seqM=0; double matchMax=1000; // обходим контуры изображения counter=0; i=0; float rad; CvPoint2D32f point; if(contoursI!=0){ // поиск лучшего совпадения контуров по их моментам for(CvSeq* seq0 = contoursI;seq0!=0;seq0 = seq0->h_next){ double match0 = cvMatchShapes(seq0, seqT, 3); if(match0<matchMax){ matchMax = match0; seqM = seq0; } cvMinEnclosingCircle(seq0,&point,&rad); // получим окружность содержащую контур } } Теперь я хочу пробежаться по всем точкам своего найденного контура. Что то типа: CvPoint* pt; for(int i=0; i<seqM->total;i++){ pt=seqM->Point; } Подскажите пожалуйста, как это можно сделать Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
stanley_goodspeed 0 Жалоба Опубликовано May 21, 2013 Здравствуйте, подскажите пожалуйста, как можно извлечь точки из контура. Контур найден таким образом: cvFindContours( binI, storage, &contoursI, sizeof(CvContour), CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0)); Далее я пробегаю по всем контурам и нахожу самый похожий на свой заданный контур: CvSeq* seqM=0; double matchMax=1000; // обходим контуры изображения counter=0; i=0; float rad; CvPoint2D32f point; if(contoursI!=0){ // поиск лучшего совпадения контуров по их моментам for(CvSeq* seq0 = contoursI;seq0!=0;seq0 = seq0->h_next){ double match0 = cvMatchShapes(seq0, seqT, 3); if(match0<matchMax){ matchMax = match0; seqM = seq0; } cvMinEnclosingCircle(seq0,&point,&rad); // получим окружность содержащую контур } } Теперь я хочу пробежаться по всем точкам своего найденного контура. Что то типа: CvPoint* pt; for(int i=0; i<seqM->total;i++){ pt=seqM->Point; } Подскажите пожалуйста, как это можно сделать Попробовал таким образом: CvPoint* pt; std::cout<<seqM->total<<std::endl; for(int i=0; i<seqM->total;i++){ CvPoint* point = reinterpret_cast<CvPoint*>(cvGetSeqElem(seqM, i)); //std::cout<<point->x; printf("x = %d y = %d\n ",point->x, point->y); } Но непонятно те ли это точки вообще? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано May 22, 2013 используйте std::vector новый opencv его поддерживает. http://docs.opencv.org/doc/tutorials/imgproc/shapedescriptors/find_contours/find_contours.html Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
stanley_goodspeed 0 Жалоба Опубликовано May 22, 2013 используйте std::vector новый opencv его поддерживает. http://docs.opencv.org/doc/tutorials/imgproc/shapedescriptors/find_contours/find_contours.html Спасибо большое! А тот способ которым я пользовался он вообще правильный? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mell 0 Жалоба Опубликовано September 2, 2013 Добрый день! Имеется следующая задача: на двух изображениях, с интервалом в секунду находятся контуры: findContours( gebiet, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) ); Sleep(1000); findContours( gebiet, contours2, hierarchy2, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) ); Вопрос следующий: Можно ли как нибудь быстро и просто сравнить массивы найденных контуров contours и contours2. Если они отличаются например на 10-20 процентов то сигнал есть. Если равны, то сигнала нет. Перебрать моменты каждого контура в каждом массиве и потом анализировать нет возможности да и это превосходит мою задачу, мне просто нужно знать отличаются сильно, не сильно или вообще не отличаются Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано September 2, 2013 Если они отличаются например и что это значит? можно просто пройтись по контурам и посмотреть их длину и кол-во или посчитать несколько простых моментов. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mell 0 Жалоба Опубликовано September 2, 2013 и что это значит? можно просто пройтись по контурам и посмотреть их длину и кол-во или посчитать несколько простых моментов. Там вообщем есть площадка, где рука человеческая ходит 10 на 400 точек, я должен ее положение определять, когда человек руку в ящик засунет, но нужна опция, которая позволит человеку дать время на "подумать" тоесть если он просто рукой водит перед ящиками, как бы выбирая, в какой засунуть (ищет что нибудь). А если он например больше секунды не двигал, то этот этот контур считать действительным. Длина будет одинаковая приммерно Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
skullhead 0 Жалоба Опубликовано November 19, 2014 Добрый день.Подскажите пожалуйста,как из последовательности контуров сформировать новую последовательность контуров,удовлетворяющих определенным критериям? Можно ли просто обходя исходную последовательность (найденную функцией CvFindContours),добавлять соответствующие условию контуры в новую? //создаем новую последовательность и выделяем под нее памятьCvMemStorage* storage_1 = cvCreateMemStorage(0);CvSeq* contours_1=cvCreateSeq( CV_SEQ_KIND_CURVE,sizeof(CvSeq),sizeof(CvContour),storage_1);if(contours!=0){// поиск совпадения контуров по их моментам и отсеивание по периметруfor(CvSeq* seq0 = contours;seq0!=0;seq0 = seq0->h_next){ double match0 = cvMatchShapes(seq0, seqT, CV_CONTOURS_MATCH_I3);if(match0<0.5&&seq0->total>=200) {cvSeqPush( contours_1,seq0);}printf(" %d match: %.2f\n", ++counter, match0);}} Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано November 19, 2014 Можно, но лучше использовать новый интерфейс (использующий cv::Mat , а не IplImage* ), как в старом делается уже не помню (откопать можно, но очень лень ). В новом используются обычные stl-овские векторы. Можно проверять критерии и собирать контуры, которые подходят. Пример работы с контурами есть в стандартных OpenCV-шных примерах. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
skullhead 0 Жалоба Опубликовано November 19, 2014 Можно, но лучше использовать новый интерфейс (использующий cv::Mat , а не IplImage* ), как в старом делается уже не помню (откопать можно, но очень лень ). В новом используются обычные stl-овские векторы. Можно проверять критерии и собирать контуры, которые подходят. Пример работы с контурами есть в стандартных OpenCV-шных примерах. перерыл все примеры,но не нашел моего случая,а именно заполнения новой пустой последовательности элементами из другой последовательности(не пойму почему не работает функция cvseqPush.полагаю дело в неверных аргументах при создании пустой последовательности cvCreateSeq. то есть находить контуры функцией cvFindContours и потом в цикле вытаскивать нужные и помещать их в массив? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано November 19, 2014 Ну вот например отсеивание по площади (это просто кусок вырванный из проекта, может быть тут есть что-нибудь лишнее): //---------------------------------------------- // Get contours centers //---------------------------------------------- vector<cv::Point> DetectContour(Mat& img, Mat& image) { vector<cv::Point> pts; Mat drawing( img.size(), CV_8UC3 ); cvtColor(image,drawing,cv::COLOR_GRAY2BGR); Mat img8U( img.size(), CV_8UC3 ); cv::normalize(img,img,0,255,CV_MINMAX); img.convertTo(img8U,CV_8UC1); vector<vector<Point> > contours; // Массив найденных контуров vector<Vec4i> hierarchy; findContours(img8U,contours, hierarchy, cv::RETR_LIST,cv::CHAIN_APPROX_SIMPLE, Point()); if(contours.size()>0) { for( int i = 0; i < contours.size(); i++ ) { if(contourArea(contours[i])>20) { // contours - просто массив с точками (можете собирать как хотите) } } } return pts; } Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
skullhead 0 Жалоба Опубликовано November 19, 2014 Ну вот например отсеивание по площади (это просто кусок вырванный из проекта, может быть тут есть что-нибудь лишнее): //---------------------------------------------- // Get contours centers //---------------------------------------------- vector<cv::Point> DetectContour(Mat& img, Mat& image) { vector<cv::Point> pts; Mat drawing( img.size(), CV_8UC3 ); cvtColor(image,drawing,cv::COLOR_GRAY2BGR); Mat img8U( img.size(), CV_8UC3 ); cv::normalize(img,img,0,255,CV_MINMAX); img.convertTo(img8U,CV_8UC1); vector<vector<Point> > contours; // Массив найденных контуров vector<Vec4i> hierarchy; findContours(img8U,contours, hierarchy, cv::RETR_LIST,cv::CHAIN_APPROX_SIMPLE, Point()); if(contours.size()>0) { for( int i = 0; i < contours.size(); i++ ) { if(contourArea(contours[i])>20) { // contours - просто массив с точками (можете собирать как хотите) } } } return pts; } весьма благодарен)буду разбираться. так контур нельзя перенести как "контур"?только заново собирать из точек? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано November 19, 2014 Ну почему же нельзя? Контур - массив точек ( vector<Point> ), копируем его, в новый массив, вот и перенесли контур, и незачем тут мудрить. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
barbados.88 0 Жалоба Опубликовано November 22, 2014 Здравствуйте, такая задачка, отделяю объекты от фона, и обвожу их контуром но результат хороший только когда контраст цвета посоветуйте фильтры или как можно улучшить выделение нужного контура вот преобразования IplImage *r = cvCreateImage(cvGetSize(imggray3), 8, 1); IplImage *g = cvCreateImage(cvGetSize(imggray3), 8, 1); IplImage *b = cvCreateImage(cvGetSize(imggray3), 8, 1); IplImage *diff = cvCreateImage(cvGetSize(imggray3), 8, 3); cvSplit(imggray3, b, g, r, 0); IplImage *tr, *tg, *tb; // для промежуточного хранения tr = cvCreateImage(cvGetSize(imggray3), IPL_DEPTH_8U, 1); tg = cvCreateImage(cvGetSize(imggray3), IPL_DEPTH_8U, 1); tb = cvCreateImage(cvGetSize(imggray3), IPL_DEPTH_8U, 1); cvThreshold(r, tr, 40, 255, CV_THRESH_BINARY); cvThreshold(g, tg, 40, 255, CV_THRESH_BINARY); cvThreshold(b, tb, 40, 255, CV_THRESH_BINARY); cvMerge(tb, tg, tr, 0, diff); IplImage *clearedImage = cvCreateImage(cvGetSize(diff), IPL_DEPTH_8U, 3); IplImage *temp = cvCreateImage(cvGetSize(diff), IPL_DEPTH_8U, 3); IplConvKernel *element = cvCreateStructuringElementEx(10,10,1,1,CV_SHAPE_RECT); cvMorphologyEx(clearedImage, clearedImage, temp, element, 5); cvErode(diff, clearedImage, element); cvDilate(clearedImage, clearedImage, element); IplImage *dest = cvCreateImage(cvGetSize(diff), IPL_DEPTH_8U, 1); cvCvtColor(diff, dest, CV_RGB2GRAY); //find contours CvMemStorage *storage = cvCreateMemStorage(0); CvSeq *contours = 0; CvSeq *biggestOne; double area = 0, biggest = 0; cvFindContours( dest, storage, &contours, sizeof(CvContour), CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE ); if(contours != 0){ biggestOne = contours; for(CvSeq *c = contours; c != 0; c = c->h_next) { area = cvContourArea(c, CV_WHOLE_SEQ); if(fabs(area) > 1000) { if (area > biggest) { biggest = area; biggestOne = c; } } } cvApproxPoly(biggestOne, sizeof(CvContour), storage, CV_POLY_APPROX_DP,3,1); cvDrawContours(&img2, biggestOne, CV_RGB(0,255,0), CV_RGB(0,255,0),0,2,8); } Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано November 22, 2014 Ну например, equalizeHist или CLAHE. И то и другое есть в OpenCV, CLAHE лучше, но чтобы его использовать, как и многие другие новые функции, Вам нужно перейти на новый интерфейс (C++ a не С, как сейчас). Примеры есть в папке samples/cpp. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
barbados.88 0 Жалоба Опубликовано November 24, 2014 Ну например, equalizeHist или CLAHE. И то и другое есть в OpenCV, CLAHE лучше, но чтобы его использовать, как и многие другие новые функции, Вам нужно перейти на новый интерфейс (C++ a не С, как сейчас). Примеры есть в папке samples/cpp. пишу на Objective-C, с opencv впервые, много не знаю через cv::Mat не получается, вылетает приложение, поэтому все делаю через IplImage, хотелось бы добиться результата как в этом коде int main() { // Load test images Mat a; Mat b; if (a.empty() || b.empty()) return -1; bool isFirstFrame = true; VideoCapture stream(-1); while (true) { if(isFirstFrame){ stream.read(a); isFirstFrame = false; } else { if(!(stream.read(b ) //get one frame from video break; Mat a_blurred, b_blurred; blur(a, a_blurred, Size(4,4)); blur(b, b_blurred, Size(4,4)); // Get absolute difference image Mat c; absdiff(b_blurred, a_blurred, c); // Split image to each channels vector<Mat> channels; split(c, channels); // Apply threshold to each channel and combine the results Mat d = Mat::zeros(c.size(), CV_8UC1); for (int i = 0; i < channels.size(); i++) { Mat thresh; threshold(channels[i], thresh, 45, 255, CV_THRESH_BINARY); d |= thresh; } // Perform morphological close operation to filling in the gaps Mat kernel, e; getStructuringElement(MORPH_RECT, Size(10,10)); morphologyEx(d, e, MORPH_CLOSE, kernel, Point(-1,-1), 5); // Find all contours vector<vector<Point> > contours; findContours(e.clone(), contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE); // Select only large enough contours vector<vector<Point> > intruders; for (int i = 0; i < contours.size(); i++) { double area = contourArea(contours[i]); if (area > 10000) intruders.push_back(contours[i]); } // Use the filtered blobs above to create a mask image to // extract the foreground object Mat mask = Mat::zeros(b.size(), CV_8UC3); drawContours(mask, intruders, -1, CV_RGB(255,255,255), -1); // Highlight the foreground object by darken the rest of the image if (intruders.size()) { b = (b/4 & ~mask) + (b & mask); drawContours(b, intruders, -1, CV_RGB(255,255,255), 2); } imshow("b", b ); waitKey(27); } } return 0; } Подскажите в чем разница? int main(){ bool isFirstFrame = true; VideoCapture stream(-1); IplImage *imggray1 = nullptr; Mat a, b; while (true) { if(isFirstFrame){ stream.read(a); IplImage img1 = a; imggray1 = cvCreateImage(cvGetSize(&img1), 8, 3); cvConvertImage(&img1, imggray1, CV_GRAY2BGR); cvSmooth(imggray1, imggray1, CV_BLUR,4,4); isFirstFrame = false; } else { if(!(stream.read(b ) //get one frame from video break; IplImage img2 = b; IplImage *imggray2 = cvCreateImage( cvGetSize( &img2 ), IPL_DEPTH_8U, 3); cvConvertImage(&img2, imggray2, CV_GRAY2BGR); cvSmooth(imggray2, imggray2, CV_BLUR, 4, 4); IplImage *imggray3 = cvCreateImage( cvGetSize( &img2 ), IPL_DEPTH_8U, 3); cvAbsDiff(imggray2, imggray1, imggray3); IplImage *r = cvCreateImage(cvGetSize(imggray3), 8, 1); IplImage *g = cvCreateImage(cvGetSize(imggray3), 8, 1); IplImage *b = cvCreateImage(cvGetSize(imggray3), 8, 1); IplImage *diff = cvCreateImage(cvGetSize(imggray3), 8, 3); cvSplit(imggray3, b, g, r, 0); IplImage *tr, *tg, *tb; // для промежуточного хранения tr = cvCreateImage(cvGetSize(imggray3), IPL_DEPTH_8U, 1); tg = cvCreateImage(cvGetSize(imggray3), IPL_DEPTH_8U, 1); tb = cvCreateImage(cvGetSize(imggray3), IPL_DEPTH_8U, 1); cvThreshold(r, tr, 45, 255, CV_THRESH_BINARY); cvThreshold(g, tg, 45, 255, CV_THRESH_BINARY); cvThreshold(b, tb, 45, 255, CV_THRESH_BINARY); cvMerge(tb, tg, tr, 0, diff); IplImage *clearedImage = cvCreateImage(cvGetSize(diff), IPL_DEPTH_8U, 3); IplImage *temp = cvCreateImage(cvGetSize(diff), IPL_DEPTH_8U, 3); IplConvKernel *element = cvCreateStructuringElementEx(10,10,1,1,CV_SHAPE_RECT); cvMorphologyEx(clearedImage, clearedImage, temp, element, 5); cvErode(diff, clearedImage, element); cvDilate(clearedImage, clearedImage, element); IplImage *dest = cvCreateImage(cvGetSize(diff), IPL_DEPTH_8U, 1); cvCvtColor(diff, dest, CV_RGB2GRAY); cvEqualizeHist(dest, dest); cvShowImage("Dest", dest); //find contours CvMemStorage *storage = cvCreateMemStorage(0); CvSeq *contours = 0; double area = 0; cvFindContours( dest, storage, &contours, sizeof(CvContour), CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE ); if(contours != 0){ for(CvSeq *c = contours; c != 0; c = c->h_next) { area = cvContourArea(c, CV_WHOLE_SEQ); if(fabs(area) > 1000) { cvApproxPoly(c, sizeof(CvContour), storage, CV_POLY_APPROX_DP,3,1); cvDrawContours(&img2, c, CV_RGB(0,255,0), CV_RGB(0,255,0),0,2,8); } } } cvShowImage("Original2", &img2); cvReleaseImage(&temp); cvReleaseImage(&r); cvReleaseImage(&g); cvReleaseImage(&b ); cvReleaseImage(&tr); cvReleaseImage(&tg); cvReleaseImage(&tb); cvReleaseImage(&clearedImage); cvReleaseImage(&dest); cvReleaseImage(&diff); cvReleaseImage(&imggray2); cvReleaseImage(&imggray3); cvReleaseMemStorage(&storage); waitKey(27); } } return 0; } Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано November 27, 2014 Мне сейчас трудно вспомнить что там да как, давно это было. Можете поковырять этот код: http://www.compvision.ru/forum/index.php/topic/1242-%D1%80%D0%B0%D1%81%D0%BF%D0%BE%D0%B7%D0%BD%D0%B0%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5-%D0%B3%D0%B5%D0%BE%D0%BC%D0%B5%D1%82%D1%80%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D1%85-%D1%84%D0%BE%D1%80%D0%BC/?hl=cvseq#entry9493 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
annaosipova 0 Жалоба Опубликовано April 2, 2015 Здравствуйте! Я хотела бы узнать. После того как найдены контуры с помощью cvFindContours, как можно узнать центр фигуры, которую каждый контур обводит? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано April 2, 2015 Если центр масс, тогда смотрите здесь: Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
annaosipova 0 Жалоба Опубликовано April 2, 2015 Если центр масс, тогда смотрите здесь: Спасибо! Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
cooller51190 0 Жалоба Опубликовано November 13, 2015 Добрый день. Интересует следующий вопроса. Как определить входит ли определённая координата в этот контур или она за его пределами. Например в окружности стоит точка с определёнными координатами, хотелось бы узнать она внутри контура или же нет. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано November 13, 2015 http://docs.opencv.org/2.4/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=pointpolygontest#pointpolygontest Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
cooller51190 0 Жалоба Опубликовано November 19, 2015 На сколько я понял pointPolygonTest работает с cv:Mat. а для IplImage есть что-то подобное? Или как мне использовать это в моём случае. Контур у меня ищется вот таким образом//находим контуры CvMemStorage* storage = cvCreateMemStorage(0); CvSeq* contours=0; //IplImage* crugi_contur= NULL; CvSize ImageSize = cvSize(713, 713); crugi_contur = cvCreateImage(ImageSize, IPL_DEPTH_8U, 3); int contoursCont = cvFindContours( crugi, storage,&contours,sizeof(CvContour),CV_RETR_EXTERNAL,CV_CHAIN_APPROX_TC89_L1, cvPoint(0,0)); // нарисуем контуры cvDrawContours( crugi_contur, contours,CV_RGB(0,255,0) ,CV_RGB(0,255,0),1, 2, CV_AA, cvPoint(0,0) ); cvShowImage("crugi_contur", crugi_contur);Уважаемые знатоки, подскажите пожалуйста. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах