Перейти к содержимому
Compvision.ru
Alex_grem

Работа с контурами

Recommended Posts

Ну так закрасьте полигон (поставьте толщину линии равной -1) и проверьте цвет точки :)

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Если есть возможность, не могли бы кинуть пример кода где изображение добавляется через ImplImage, контуры ищутся моим способом, и проверить какую либо координату внутри она контура или нет. Ищу уже какой день, но не нормальной документации ни примеров найти не могу. Спасибо огромное за помощь.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Я уже давно не использовал старый интерфейс и вспоминать его долго, да и незачем.

В качестве руководства найдите книжку: 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.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Да спасибо, посмотрел книжку.

Вот возник такой вот вопрос, что я не правильно делаю? Решил через 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, но у меня ничего не выходит (происходит прекращение работы программы в следствие ошибок). Подскажите, где моя ошибка, и что необходимо дописать или преобразовать чтобы у меня получилось.

Изменено пользователем cooller51190

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Использовать debug сборку, посмотреть, что за ошибка и сказать нам.

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Компиляция проходит нормально, но при запуске возникает вот такая информация в консоли.

Безымянный.jpg

Изменено пользователем cooller51190

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Этого мало. По приведённому исходнику не понятно, в каком конкретном месте возникает ошибка.

И, если всё таки использовать debug сборку, то можно в отладчике увидеть значения переменных. Ведь по тексту ошибки совершенно ясно, что проблема в самом контуре, не выполняется одно из трёх приведённых условий.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Просто до добавления этой строки, работало всё нормально. Что вообще это может быть и в какую сторону хотя бы искать? По дебагу конкретно сейчас выложить увы не могу.

Сейчас полный код выглядит следующим образом.

#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;
		}
			

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Просто до добавления этой строки, работало всё нормально. Что вообще это может быть и в какую сторону хотя бы искать? По дебагу конкретно сейчас выложить увы не могу.

Сейчас полный код выглядит следующим образом.

#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...что пошаговая отладка говорит?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Пошагово, нет возможности провести отладку пока что. Ранее у меня был представлен более маленький пример программы. где просто 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 внутри или нет. Но увы выдаёт вот такую ошибку. Прошу прощение за повторение одинаковых сообщений у администраторов.

Подскажите в чём я тут ошибаюсь? И что возможно необходимо добавить.

Безымянный.jpg

Или может проблема где-то в настройках или в самой студии?

 

Изменено пользователем cooller51190

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Пошагово, нет возможности провести отладку пока что. Ранее у меня был представлен более маленький пример программы. где просто MAT. Там аналогичная проблема. Не могли бы хотя бы просто кинуть пример программы где происходит открытие изображения поиск контура и проверка точки, внутри она или нет. Просто подобных примеров найти не могу.

 

Какого поведения программы вы ожидаете вот от этой строки:

cout << pointPolygonTest(contours, Point2f(250,300), false)<<std::endl; // Тут возникает ошибка

Вы передаете внутрь ф-ии контейнер вида std::vector<std::vector<cv::Point>>, тогда как ф-я ожидает на входе std::vector<cv::Point>...

Изменено пользователем BeS

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Ну судя по документации pointPolygonTest должен проверить точка находиться внутри контура, на граница, или в не контура, выдать соответственно 1 или 0 или -1

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Ну судя по документации pointPolygonTest должен проверить точка находиться внутри контура, на граница, или в не контура, выдать соответственно 1 или 0 или -1

 

Ну да, именно это она и делает. Другой вопрос в том, который из контуров вы передаете этой ф-ии?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

А вот с этим я увы не знаю. Подскажите как правильно ей передать тот или иной контур?

Я думал поставив в цикл при рисование контура,

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; // При добавление этой строки ошибка
    }

она будет проверять каждый контур. Но вот как правильно это сделать не знаю. Буду благодарен за вашу помощь если подскажите.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Сейчас проверить не могу, но есть сильное подозрение, что "каждый контур" это будет

contours[idx]
  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Всем привет! Есть такая проблема, в общем, нахожу контуры на изображении, потом фильтрую и для оставшихся нужно узнать цвет пикселей внутри них, т.е. контур вокруг белой области или вокруг чёрной. Подозреваю, что можно как-нибудь исхитриться с помощью hierarchy, но делаю поиск контуров без неё. Не хотелось бы делать поиск hierarchy для порядка 200-250 контуров, чтобы использовать только с 6-10.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Контур же есть, смотри на пиксели внутри. Ммм, а в чём конкретно проблема?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Может, конечно, глупый вопрос, но как посмотреть какие пиксели внутри?)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Да, с pointPolygonTest должно получиться, пока сделаю с ним наверное, правда придётся делать много лишних телодвижений. Т.е. с ним получается алгоритм такой, как я понимаю:

Берём первую точку контура (вообще любую, но первую удобно просто) и начинаем проверять 8 точек вокруг неё на факт вхождения в контур, пока не найдём. Когда нашли - проверяем цвет.

Спасибо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Можно просто нарисовать заполненный контур и использовать как маску для подсчета (countNonZero).

1) находим boundingRect для заданного контура, назначаем его областью интереса. Что бы не портиить исходное, можно скопировать в отдельное изображение и работать с ним.

2) создаем пустое изображение (по размеру равное области интереса), рисуем в нем контур (цветом заполнения 1, или 255 зависит от следующей операции ).

3) Логическое "И" или поэлементное умножение. Короче гасим все ненужное. 

4)  суммироем, или countNonZero, или что то еще.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
10 minutes ago, Smorodov said:

Можно просто нарисовать заполненный контур и использовать как маску для подсчета (countNonZero).

1) находим boundingRect для заданного контура, назначаем его областью интереса. Что бы не портиить исходное, можно скопировать в отдельное изображение и работать с ним.

2) создаем пустое изображение (по размеру равное области интереса), рисуем в нем контур (цветом заполнения 1, или 255 зависит от следующей операции ).

По-хорошему, пункт 2 - это и есть искомый ответ. То есть надо найти хотя бы 1 точку внутри контура, а после взять любой алгоритм заливки и вигаться вместе с ним, запоминая/суммируя/проверяя значения пикселей.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Как лучше сохранить изображение полученное в контуре для дальнейшего сравнения? 

1. Хранить исходное изображение и массив точек контура в файле и перед каждым сравнением получать из него фрагмент картинки.

2.Хранить изображение вырезанного прямоугольника с контуром в файле и перед каждым сравнением находить контур снова.

Оба варианта предполагают одни и те же операции с контуром до сохранения и после чтения. Может есть более оптимальное решение?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте учётную запись или войдите для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать учётную запись

Зарегистрируйтесь для создания учётной записи. Это просто!

Зарегистрировать учётную запись

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу

×