Smorodov 578 Report post Posted November 19, 2015 Ну так закрасьте полигон (поставьте толщину линии равной -1) и проверьте цвет точки Share this post Link to post Share on other sites
cooller51190 0 Report post Posted November 20, 2015 Если есть возможность, не могли бы кинуть пример кода где изображение добавляется через ImplImage, контуры ищутся моим способом, и проверить какую либо координату внутри она контура или нет. Ищу уже какой день, но не нормальной документации ни примеров найти не могу. Спасибо огромное за помощь. Share this post Link to post Share on other sites
Smorodov 578 Report post Posted November 20, 2015 Я уже давно не использовал старый интерфейс и вспоминать его долго, да и незачем.В качестве руководства найдите книжку: http://www.amazon.com/gp/product/0596516134/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=0596516134&linkCode=as2&tag=opencv00-20она есть в сети. В ней много полезного и все для IplImage. Share this post Link to post Share on other sites
cooller51190 0 Report post Posted November 23, 2015 (edited) Да спасибо, посмотрел книжку.Вот возник такой вот вопрос, что я не правильно делаю? Решил через MAT попробовать.Имеется вот такой код который находит мне этот контур (виде окружности)int main(int argc, const char * argv[]) { cv::Mat image= cv::imread("Image0.jpg"); if (!image.data) { std::cout << "Image file not found\n"; // return 1; } //Prepare the image for findContours cv::cvtColor(image, image, CV_BGR2GRAY); cv::threshold(image, image, 128, 255, CV_THRESH_BINARY); //Find the contours. Use the contourOutput Mat so the original image doesn't get overwritten std::vector<std::vector<cv::Point> > contours; cv::Mat contourOutput = image.clone(); cv::findContours( contourOutput, contours, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE ); //Draw the contours cv::Mat contourImage(image.size(), CV_8UC3, cv::Scalar(0,0,0)); cv::Scalar colors[3]; colors[0] = cv::Scalar(255, 0, 0); colors[1] = cv::Scalar(0, 255, 0); colors[2] = cv::Scalar(0, 0, 255); for (size_t idx = 0; idx < contours.size(); idx++) { cv::drawContours(contourImage, contours, idx, colors[idx % 3]); } cv::imshow("Input Image", image); cvMoveWindow("Input Image", 0, 0); cv::imshow("Contours", contourImage); cvMoveWindow("Contours", 200, 0); cv::waitKey(0); return 0; }Судя по функции pointPolygonTest перед выводом изображений я могу вызвать следующееcout << pointPolygonTest(contours, Point2f(250,300), false)<<std::endlИ мне должен показаться результат либо -1, либо 0, либо 1, но у меня ничего не выходит (происходит прекращение работы программы в следствие ошибок). Подскажите, где моя ошибка, и что необходимо дописать или преобразовать чтобы у меня получилось. Edited November 23, 2015 by cooller51190 Share this post Link to post Share on other sites
cooller51190 0 Report post Posted November 30, 2015 Подскажите, кто знает. В какую сторону мне копать? Share this post Link to post Share on other sites
Nuzhny 243 Report post Posted November 30, 2015 Использовать debug сборку, посмотреть, что за ошибка и сказать нам. 1 Share this post Link to post Share on other sites
cooller51190 0 Report post Posted November 30, 2015 (edited) Компиляция проходит нормально, но при запуске возникает вот такая информация в консоли. Edited November 30, 2015 by cooller51190 Share this post Link to post Share on other sites
Nuzhny 243 Report post Posted November 30, 2015 Этого мало. По приведённому исходнику не понятно, в каком конкретном месте возникает ошибка.И, если всё таки использовать debug сборку, то можно в отладчике увидеть значения переменных. Ведь по тексту ошибки совершенно ясно, что проблема в самом контуре, не выполняется одно из трёх приведённых условий. Share this post Link to post Share on other sites
cooller51190 0 Report post Posted November 30, 2015 Просто до добавления этой строки, работало всё нормально. Что вообще это может быть и в какую сторону хотя бы искать? По дебагу конкретно сейчас выложить увы не могу.Сейчас полный код выглядит следующим образом.#include "stdafx.h" #include "stdio.h" #include "cv.h" #include "highgui.h" #include "stdlib.h" #include "math.h" #include "sstream" #include "string" using std::cout; using namespace cv; #ifndef min #define min(a,b) (((a) < (b)) ? (a) : (b)) #endif //анализ контуров void ConturAnaliz (cv::Mat image) {//cv::Mat image= cv::imread(_image); if (!image.data) { // std::cout << "Image file not found\n"; // return 1; } //Prepare the image for findContours cv::cvtColor(image, image, CV_BGR2GRAY); cv::threshold(image, image, 128, 255, CV_THRESH_BINARY); //Find the contours. Use the contourOutput Mat so the original image doesn't get overwritten std::vector<std::vector<cv::Point> > contours; cv::Mat contourOutput = image.clone(); cv::findContours( contourOutput, contours, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE ); //Draw the contours cv::Mat contourImage(image.size(), CV_8UC3, cv::Scalar(0,0,0)); cv::Scalar colors[3]; colors[0] = cv::Scalar(255, 0, 0); colors[1] = cv::Scalar(0, 255, 0); colors[2] = cv::Scalar(0, 251, 255); int k1=0; for (size_t idx = 0; idx < contours.size(); idx++, ++k1) { cv::drawContours(contourImage, contours, idx, colors[idx % 3]); }cout << "The number of analyzed contours - " << k1; cout << pointPolygonTest(contours, Point2f(250,300), false)<<std::endl; // Тут возникает ошибка cv::imshow("ConturAnaliz", contourImage); cvMoveWindow("ConturAnaliz", 200, 0); } int main(int argc, char* argv[]) { IplImage *img1=0, *img2=0, *diff=0, *sub=0, *strela=0, *crugi=0, *crugi1=0, *crugi2=0, *gray=0, *crugi_contur=0, *dst=0, *bin=0; int c=0;//переменная для отмены последующего вывода координат int w=0, v=0;//переменнтая для отображения результата временно координаты // дефолтные названия картинок для обработки char file1[] = "Image0.jpg"; char file2[] = "Image1.jpg"; // имя картинки задаётся первым параметром char* filename1 = argc >= 2 ? argv[1] : file1; // получаем картинку img1 = cvLoadImage(filename1); printf("[i] first image: %s\n", filename1); // имя картинки задаётся первым параметром char* filename2 = argc >= 3 ? argv[2] : file2; // получаем картинку img2 = cvLoadImage(filename2); printf("[i] second image: %s\n", filename2); //Создаём однокональное изображение crugi = cvCreateImage( cvGetSize(img1), IPL_DEPTH_8U, 1 ); bin = cvCreateImage( cvGetSize(img1), IPL_DEPTH_8U, 1 ); // получаем границы cvCanny(img1, crugi, 200, 220, 3); cvShowImage("crugi cvCanny",crugi); // покажем первоначальные изображения // cvNamedWindow( "image1"); // cvShowImage( "image1", img1 ); // cvNamedWindow( "image2"); // cvShowImage( "image2", img2 ); //Разница изображений // создаём картинку для хранения разницы diff = cvCloneImage(img1); sub = cvCloneImage(img1); cvZero(diff); // пробегаемся по всем пикселям изображения for( int y=0; y<diff->height; y++ ) { uchar* ptr1 = (uchar*) (img1->imageData + y * img1->widthStep); uchar* ptr2 = (uchar*) (img2->imageData + y * img2->widthStep); uchar* ptr = (uchar*) (diff->imageData + y * diff->widthStep); for( int x=0; x<diff->width; x++ ) { // 3 канала: // B ptr[3*x] = ptr1[3*x] + ptr2[3*x] - 2 * min(ptr1[3*x], ptr2[3*x]); // G ptr[3*x+1] = ptr1[3*x+1] + ptr2[3*x+1] - 2 * min(ptr1[3*x+1], ptr2[3*x+1]); // R ptr[3*x+2] = ptr1[3*x+2] + ptr2[3*x+2] - 2 * min(ptr1[3*x+2], ptr2[3*x+2]); } } // вычитаем cvSub(img1, img2, sub); strela = cvCreateImage( cvGetSize(img1), IPL_DEPTH_8U, 1 ); // выводим результат вычитания cvNamedWindow( "diff"); cvShowImage( "diff", diff ); // cvNamedWindow( "sub"); // cvShowImage( "sub", sub ); // Находим границы вычтенного изображения cvCanny(diff, strela, 300, 320, 3); cvNamedWindow( "strela"); cvShowImage( "strela", strela ); //Поиск первого белого пикселя (конец стрелы) // пробегаемся по всем пикселям изображения c низу вверх, с права на лево // width - ширина изображение height - высота изображения for( int x=0; x<strela->width; x++ ) { // widthStep - расстояние между соседними по вертикали точками изображения (число байт в одной строчке картинки). // Соответственно, для данного случая (при image->imageData == начало массива данных) по арифметике указателей // ptr будет указывать на начало каждой строки массива данных картинки for( int y=0; y<strela->height; y++ ) { int nChan = strela->nChannels; // Определить количество каналов, чтобы реализация не зависела от пользователя. uchar* ptr = (uchar*) (strela->imageData + y * strela->widthStep); // количество каналов вложили в nChan // пробегаемся по всем каналам каждого пикселя // конкретно здесь устанавливаются значения каналов каждого пикселя :) if (c<1){ if (ptr[nChan*x] == 255 && ptr[nChan*x + 1] == 255 && ptr[nChan*x + 2] == 255) { cout << "Pixel is: x -"<< x << " y - " << y << "\n" ; c=1;//переменная для отмены последующего вывода w=x; v=y; } } } } //функция для вывода результатов на изображение char str[11]; sprintf(str, "%d", w);//преобразование числа в строку // задаём точку для вывода текста CvPoint pt = cvPoint(10, 50 ); // инициализация шрифта CvFont font; cvInitFont( &font, CV_FONT_HERSHEY_COMPLEX,1.0, 1.0, 0, 1, CV_AA); // используя шрифт выводим на картинку текст cvPutText(img1, str , pt, &font, CV_RGB(150, 150, 150) ); cvShowImage("Final", img1); //вывод координат найденного конца стрелы (временно, в конце убрать) cout << w; cout << v; //находим контуры //создаём массив для контуров CvMemStorage* storage = cvCreateMemStorage(0); CvSeq* contours=0; //создание изображения для вывода контуров CvSize ImageSize = cvSize(713, 713); crugi_contur = cvCreateImage(ImageSize, IPL_DEPTH_8U, 3); //поиск контуров int contoursCont = cvFindContours( crugi, storage,&contours,sizeof(CvContour),CV_CHAIN_CODE,CV_CHAIN_APPROX_NONE, cvPoint(0,0)); // double pointPolygonTest(contours,160,160,false); //присвоение переменной 0 для подсчёта количества контуров int k = 0; // рисуем контур if(contours!=0){ for(CvSeq* seq0 = contours; seq0!=0;seq0 = seq0->h_next, ++k){ // рисуем контур cvDrawContours(crugi_contur, seq0, CV_RGB(255,216,0), CV_RGB(255,216,0), 3, 2, 8); } } // выводит количество контуров cout << " " << k; // сглаживаем исходную картинку cvSmooth(crugi_contur, crugi_contur, CV_MEDIAN, 3, 3); cvShowImage("crugi_contur", crugi_contur); //Сохраняем полученные контуры для дальнейшей обработки cvSaveImage("ConturAnaliz.jpg", crugi_contur); //вызов функции анализа изображения ConturAnaliz (crugi_contur); cvWaitKey(0); //освобождаем ресурсы cvReleaseImage(&img1); cvReleaseImage(&img2); cvReleaseImage(&diff); cvReleaseImage(&sub); // удаляем окна cvDestroyAllWindows(); return 0; } Share this post Link to post Share on other sites
BeS 53 Report post Posted November 30, 2015 Просто до добавления этой строки, работало всё нормально. Что вообще это может быть и в какую сторону хотя бы искать? По дебагу конкретно сейчас выложить увы не могу.Сейчас полный код выглядит следующим образом.#include "stdafx.h" #include "stdio.h" #include "cv.h" #include "highgui.h" #include "stdlib.h" #include "math.h" #include "sstream" #include "string" using std::cout; using namespace cv; #ifndef min #define min(a,b) (((a) < (b)) ? (a) : (b)) #endif //анализ контуров void ConturAnaliz (cv::Mat image) {//cv::Mat image= cv::imread(_image); if (!image.data) { // std::cout << "Image file not found\n"; // return 1; } //Prepare the image for findContours cv::cvtColor(image, image, CV_BGR2GRAY); cv::threshold(image, image, 128, 255, CV_THRESH_BINARY); //Find the contours. Use the contourOutput Mat so the original image doesn't get overwritten std::vector<std::vector<cv::Point> > contours; cv::Mat contourOutput = image.clone(); cv::findContours( contourOutput, contours, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE ); //Draw the contours cv::Mat contourImage(image.size(), CV_8UC3, cv::Scalar(0,0,0)); cv::Scalar colors[3]; colors[0] = cv::Scalar(255, 0, 0); colors[1] = cv::Scalar(0, 255, 0); colors[2] = cv::Scalar(0, 251, 255); int k1=0; for (size_t idx = 0; idx < contours.size(); idx++, ++k1) { cv::drawContours(contourImage, contours, idx, colors[idx % 3]); }cout << "The number of analyzed contours - " << k1; cout << pointPolygonTest(contours, Point2f(250,300), false)<<std::endl; // Тут возникает ошибка cv::imshow("ConturAnaliz", contourImage); cvMoveWindow("ConturAnaliz", 200, 0); } int main(int argc, char* argv[]) { IplImage *img1=0, *img2=0, *diff=0, *sub=0, *strela=0, *crugi=0, *crugi1=0, *crugi2=0, *gray=0, *crugi_contur=0, *dst=0, *bin=0; int c=0;//переменная для отмены последующего вывода координат int w=0, v=0;//переменнтая для отображения результата временно координаты // дефолтные названия картинок для обработки char file1[] = "Image0.jpg"; char file2[] = "Image1.jpg"; // имя картинки задаётся первым параметром char* filename1 = argc >= 2 ? argv[1] : file1; // получаем картинку img1 = cvLoadImage(filename1); printf(" first image: %s\n", filename1); // имя картинки задаётся первым параметром char* filename2 = argc >= 3 ? argv[2] : file2; // получаем картинку img2 = cvLoadImage(filename2); printf(" second image: %s\n", filename2); //Создаём однокональное изображение crugi = cvCreateImage( cvGetSize(img1), IPL_DEPTH_8U, 1 ); bin = cvCreateImage( cvGetSize(img1), IPL_DEPTH_8U, 1 ); // получаем границы cvCanny(img1, crugi, 200, 220, 3); cvShowImage("crugi cvCanny",crugi); // покажем первоначальные изображения // cvNamedWindow( "image1"); // cvShowImage( "image1", img1 ); // cvNamedWindow( "image2"); // cvShowImage( "image2", img2 ); //Разница изображений // создаём картинку для хранения разницы diff = cvCloneImage(img1); sub = cvCloneImage(img1); cvZero(diff); // пробегаемся по всем пикселям изображения for( int y=0; y<diff->height; y++ ) { uchar* ptr1 = (uchar*) (img1->imageData + y * img1->widthStep); uchar* ptr2 = (uchar*) (img2->imageData + y * img2->widthStep); uchar* ptr = (uchar*) (diff->imageData + y * diff->widthStep); for( int x=0; x<diff->width; x++ ) { // 3 канала: // B ptr[3*x] = ptr1[3*x] + ptr2[3*x] - 2 * min(ptr1[3*x], ptr2[3*x]); // G ptr[3*x+1] = ptr1[3*x+1] + ptr2[3*x+1] - 2 * min(ptr1[3*x+1], ptr2[3*x+1]); // R ptr[3*x+2] = ptr1[3*x+2] + ptr2[3*x+2] - 2 * min(ptr1[3*x+2], ptr2[3*x+2]); } } // вычитаем cvSub(img1, img2, sub); strela = cvCreateImage( cvGetSize(img1), IPL_DEPTH_8U, 1 ); // выводим результат вычитания cvNamedWindow( "diff"); cvShowImage( "diff", diff ); // cvNamedWindow( "sub"); // cvShowImage( "sub", sub ); // Находим границы вычтенного изображения cvCanny(diff, strela, 300, 320, 3); cvNamedWindow( "strela"); cvShowImage( "strela", strela ); //Поиск первого белого пикселя (конец стрелы) // пробегаемся по всем пикселям изображения c низу вверх, с права на лево // width - ширина изображение height - высота изображения for( int x=0; x<strela->width; x++ ) { // widthStep - расстояние между соседними по вертикали точками изображения (число байт в одной строчке картинки). // Соответственно, для данного случая (при image->imageData == начало массива данных) по арифметике указателей // ptr будет указывать на начало каждой строки массива данных картинки for( int y=0; y<strela->height; y++ ) { int nChan = strela->nChannels; // Определить количество каналов, чтобы реализация не зависела от пользователя. uchar* ptr = (uchar*) (strela->imageData + y * strela->widthStep); // количество каналов вложили в nChan // пробегаемся по всем каналам каждого пикселя // конкретно здесь устанавливаются значения каналов каждого пикселя :) if (c<1){ if (ptr[nChan*x] == 255 && ptr[nChan*x + 1] == 255 && ptr[nChan*x + 2] == 255) { cout << "Pixel is: x -"<< x << " y - " << y << "\n" ; c=1;//переменная для отмены последующего вывода w=x; v=y; } } } } //функция для вывода результатов на изображение char str[11]; sprintf(str, "%d", w);//преобразование числа в строку // задаём точку для вывода текста CvPoint pt = cvPoint(10, 50 ); // инициализация шрифта CvFont font; cvInitFont( &font, CV_FONT_HERSHEY_COMPLEX,1.0, 1.0, 0, 1, CV_AA); // используя шрифт выводим на картинку текст cvPutText(img1, str , pt, &font, CV_RGB(150, 150, 150) ); cvShowImage("Final", img1); //вывод координат найденного конца стрелы (временно, в конце убрать) cout << w; cout << v; //находим контуры //создаём массив для контуров CvMemStorage* storage = cvCreateMemStorage(0); CvSeq* contours=0; //создание изображения для вывода контуров CvSize ImageSize = cvSize(713, 713); crugi_contur = cvCreateImage(ImageSize, IPL_DEPTH_8U, 3); //поиск контуров int contoursCont = cvFindContours( crugi, storage,&contours,sizeof(CvContour),CV_CHAIN_CODE,CV_CHAIN_APPROX_NONE, cvPoint(0,0)); // double pointPolygonTest(contours,160,160,false); //присвоение переменной 0 для подсчёта количества контуров int k = 0; // рисуем контур if(contours!=0){ for(CvSeq* seq0 = contours; seq0!=0;seq0 = seq0->h_next, ++k){ // рисуем контур cvDrawContours(crugi_contur, seq0, CV_RGB(255,216,0), CV_RGB(255,216,0), 3, 2, 8); } } // выводит количество контуров cout << " " << k; // сглаживаем исходную картинку cvSmooth(crugi_contur, crugi_contur, CV_MEDIAN, 3, 3); cvShowImage("crugi_contur", crugi_contur); //Сохраняем полученные контуры для дальнейшей обработки cvSaveImage("ConturAnaliz.jpg", crugi_contur); //вызов функции анализа изображения ConturAnaliz (crugi_contur); cvWaitKey(0); //освобождаем ресурсы cvReleaseImage(&img1); cvReleaseImage(&img2); cvReleaseImage(&diff); cvReleaseImage(&sub); // удаляем окна cvDestroyAllWindows(); return 0; } А что тут за адов кабздец с использованием ANSI C / C++ интерфейсов? О_О Особенно радует приведение IplImage* к cv::Mat...не удивлюсь, что где-то там маты криво мапятся на память, тем более что assert намекает на какой-то невалидный cv::Mat...что пошаговая отладка говорит? Share this post Link to post Share on other sites
cooller51190 0 Report post Posted November 30, 2015 (edited) Пошагово, нет возможности провести отладку пока что. Ранее у меня был представлен более маленький пример программы. где просто MAT. Там аналогичная проблема. Не могли бы хотя бы просто кинуть пример программы где происходит открытие изображения поиск контура и проверка точки, внутри она или нет. Просто подобных примеров найти не могу.Вот мой пример (упрощенный до минимума)#include "stdafx.h" #include "stdio.h" #include "cv.h" #include "highgui.h" #include "stdlib.h" #include "math.h" #include "sstream" #include "string" using std::cout; using namespace cv; int main(int argc, const char * argv[]) { cv::Mat image= cv::imread("Image2.jpg"); if (!image.data) { std::cout << "Image file not found\n"; // return 1; } //Prepare the image for findContours cv::cvtColor(image, image, CV_BGR2GRAY); cv::threshold(image, image, 128, 255, CV_THRESH_BINARY); //Find the contours. Use the contourOutput Mat so the original image doesn't get overwritten std::vector<std::vector<cv::Point> > contours; cv::Mat contourOutput = image.clone(); cv::findContours( contourOutput, contours, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE ); //Draw the contours cv::Mat contourImage(image.size(), CV_8UC3, cv::Scalar(0,0,0)); cv::Scalar colors[3]; colors[0] = cv::Scalar(255, 0, 0); colors[1] = cv::Scalar(0, 255, 0); colors[2] = cv::Scalar(0, 0, 255); for (size_t idx = 0; idx < contours.size(); idx++) { cv::drawContours(contourImage, contours, idx, colors[idx % 3]); cout << cv::pointPolygonTest(contours,Point2f(250,300), false)<<std::endl; // При добавление этой строки ошибка } cv::imshow("Input Image", image); cvMoveWindow("Input Image", 0, 0); cv::imshow("Contours", contourImage); cvMoveWindow("Contours", 200, 0); cv::waitKey(0); return 0; }На сколько я понимаю при каждом проходе контура он проверяет находиться ли точка с координатой 250, 300 внутри или нет. Но увы выдаёт вот такую ошибку. Прошу прощение за повторение одинаковых сообщений у администраторов.Подскажите в чём я тут ошибаюсь? И что возможно необходимо добавить.Или может проблема где-то в настройках или в самой студии? Edited November 30, 2015 by cooller51190 Share this post Link to post Share on other sites
BeS 53 Report post Posted November 30, 2015 (edited) Пошагово, нет возможности провести отладку пока что. Ранее у меня был представлен более маленький пример программы. где просто MAT. Там аналогичная проблема. Не могли бы хотя бы просто кинуть пример программы где происходит открытие изображения поиск контура и проверка точки, внутри она или нет. Просто подобных примеров найти не могу. Какого поведения программы вы ожидаете вот от этой строки:cout << pointPolygonTest(contours, Point2f(250,300), false)<<std::endl; // Тут возникает ошибкаВы передаете внутрь ф-ии контейнер вида std::vector<std::vector<cv::Point>>, тогда как ф-я ожидает на входе std::vector<cv::Point>... Edited November 30, 2015 by BeS Share this post Link to post Share on other sites
cooller51190 0 Report post Posted November 30, 2015 Ну судя по документации pointPolygonTest должен проверить точка находиться внутри контура, на граница, или в не контура, выдать соответственно 1 или 0 или -1 Share this post Link to post Share on other sites
BeS 53 Report post Posted November 30, 2015 Ну судя по документации pointPolygonTest должен проверить точка находиться внутри контура, на граница, или в не контура, выдать соответственно 1 или 0 или -1 Ну да, именно это она и делает. Другой вопрос в том, который из контуров вы передаете этой ф-ии? Share this post Link to post Share on other sites
cooller51190 0 Report post Posted November 30, 2015 А вот с этим я увы не знаю. Подскажите как правильно ей передать тот или иной контур?Я думал поставив в цикл при рисование контура,for (size_t idx = 0; idx < contours.size(); idx++) { cv::drawContours(contourImage, contours, idx, colors[idx % 3]); cout << cv::pointPolygonTest(contours,Point2f(250,300), false)<<std::endl; // При добавление этой строки ошибка }она будет проверять каждый контур. Но вот как правильно это сделать не знаю. Буду благодарен за вашу помощь если подскажите. Share this post Link to post Share on other sites
Smorodov 578 Report post Posted November 30, 2015 Сейчас проверить не могу, но есть сильное подозрение, что "каждый контур" это будетcontours[idx] 1 Share this post Link to post Share on other sites
cooller51190 0 Report post Posted November 30, 2015 Спасибо огромное. Действительно не хватало [idx]. Share this post Link to post Share on other sites
APXANGEL 0 Report post Posted December 17, 2015 Всем привет! Есть такая проблема, в общем, нахожу контуры на изображении, потом фильтрую и для оставшихся нужно узнать цвет пикселей внутри них, т.е. контур вокруг белой области или вокруг чёрной. Подозреваю, что можно как-нибудь исхитриться с помощью hierarchy, но делаю поиск контуров без неё. Не хотелось бы делать поиск hierarchy для порядка 200-250 контуров, чтобы использовать только с 6-10. Share this post Link to post Share on other sites
Nuzhny 243 Report post Posted December 17, 2015 Контур же есть, смотри на пиксели внутри. Ммм, а в чём конкретно проблема? Share this post Link to post Share on other sites
APXANGEL 0 Report post Posted December 18, 2015 Может, конечно, глупый вопрос, но как посмотреть какие пиксели внутри?) Share this post Link to post Share on other sites
Nuzhny 243 Report post Posted December 18, 2015 Можно pointPolygonTest попробовать, как в этом примере. 1 Share this post Link to post Share on other sites
APXANGEL 0 Report post Posted December 18, 2015 Да, с pointPolygonTest должно получиться, пока сделаю с ним наверное, правда придётся делать много лишних телодвижений. Т.е. с ним получается алгоритм такой, как я понимаю: Берём первую точку контура (вообще любую, но первую удобно просто) и начинаем проверять 8 точек вокруг неё на факт вхождения в контур, пока не найдём. Когда нашли - проверяем цвет. Спасибо. Share this post Link to post Share on other sites
Smorodov 578 Report post Posted December 18, 2015 Можно просто нарисовать заполненный контур и использовать как маску для подсчета (countNonZero). 1) находим boundingRect для заданного контура, назначаем его областью интереса. Что бы не портиить исходное, можно скопировать в отдельное изображение и работать с ним. 2) создаем пустое изображение (по размеру равное области интереса), рисуем в нем контур (цветом заполнения 1, или 255 зависит от следующей операции ). 3) Логическое "И" или поэлементное умножение. Короче гасим все ненужное. 4) суммироем, или countNonZero, или что то еще. Share this post Link to post Share on other sites
Nuzhny 243 Report post Posted December 18, 2015 10 minutes ago, Smorodov said: Можно просто нарисовать заполненный контур и использовать как маску для подсчета (countNonZero). 1) находим boundingRect для заданного контура, назначаем его областью интереса. Что бы не портиить исходное, можно скопировать в отдельное изображение и работать с ним. 2) создаем пустое изображение (по размеру равное области интереса), рисуем в нем контур (цветом заполнения 1, или 255 зависит от следующей операции ). По-хорошему, пункт 2 - это и есть искомый ответ. То есть надо найти хотя бы 1 точку внутри контура, а после взять любой алгоритм заливки и вигаться вместе с ним, запоминая/суммируя/проверяя значения пикселей. Share this post Link to post Share on other sites
field 0 Report post Posted October 14, 2016 Как лучше сохранить изображение полученное в контуре для дальнейшего сравнения? 1. Хранить исходное изображение и массив точек контура в файле и перед каждым сравнением получать из него фрагмент картинки. 2.Хранить изображение вырезанного прямоугольника с контуром в файле и перед каждым сравнением находить контур снова. Оба варианта предполагают одни и те же операции с контуром до сохранения и после чтения. Может есть более оптимальное решение? Share this post Link to post Share on other sites