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

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

Recommended Posts

А если на картинке несколько объектов как найти нужное?

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


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

Посмотрите пример с блобами, там моменты для каждого блоба находятся, вернее там не находятся, но библиотека блоб-анализа позволяет это делать.

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


Ссылка на сообщение
Поделиться на других сайтах
Функция может искать моменты не только контуров, но и двоичных изображений

Тогда такое решение, конечно не красивое, но работает

cvFindContours(Image, storage_img,&img_contour,sizeof(CvContour),CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE,cvPoint(0,0));

cvZero(mask);

for (contours!=0;contours=contours-h_next)

{

	  if ... //параметры нужных контуров объекта

	  {

			CvPoint* p = (CvPoint*)cvGetSeqElem(contours,0);

			int total = contours->total;

			CvFillPoly(mask, &p, &total, 1, cvScalar(1,0,0,0));

	  }

}

cvMoments(mask,&moments)

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


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

Всем привет! Сижу разбираюсь с OpenCV. Задача думаю простая. На черном фоне несколько различных объектов. Надо их найти и объвести контуром. Потом найденный контур вписать в прямоугольник. Как-то так... Контур я так понимаю искать с помощью cvFindContours() ? Как ее применить эту функцию...

Заранее спасибо ))))

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


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

так задача упрощается.... контуры я нашел, осталось вписать в прямоугольник )))))

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


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

cvMinAreaRect2 можно как-нить прикрутить или для этого другая функция нужна?

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


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

Исходное изображение:

52131858.jpg

Результат программы:

resultg.jpg

Тока чёто буковку У плохо обвел, он ее зачем то разделил на 2 контура =)

Если будут какие то замечания, то пишите.

#include "stdafx.h"

#include <stdio.h>

#include "cv.h"

#include "highgui.h"



int main()

{

	CvMemStorage* image_storage = cvCreateMemStorage(0);

	CvSeq* image_contours;


	cvNamedWindow( "Window1", 1 );

	IplImage *image = 0;

	IplImage *clone = cvCreateImage(cvSize(227,42), IPL_DEPTH_8U, 3);

	image = cvLoadImage( "ex.jpg", 1 );

	IplImage *image_gray = cvCreateImage(cvSize(227,42), IPL_DEPTH_8U, 1);

	cvCvtColor( image, image_gray, CV_BGR2GRAY );

	IplImage *image_canny = cvCreateImage(cvSize(227,42), IPL_DEPTH_8U, 1);

	cvCanny( image_gray, image_canny, 50, 255, 3 );

	cvFindContours( image_canny, image_storage, &image_contours, sizeof(CvContour), 

		CV_RETR_TREE);


		while(image_contours)

		{

		cvZero( clone );

		cvDrawContours( image, image_contours, CV_RGB(255,0,0), CV_RGB(0,255,0), 0, 0, CV_AA, cvPoint(0,0) );

		CvRect rect = cvBoundingRect(image_contours);

		printf("%d %d %d %d\n", rect.x, rect.y, rect.width, rect.height);

		if(rect.width > 10 && rect.width < 60 && rect.height > 20 && rect.height < 60)

		{

		cvRectangle(image, cvPoint(rect.x, rect.y), cvPoint(rect.x+rect.width,rect.y+rect.height),

			CV_RGB(0,255,0), 0);

		}

		image_contours = image_contours ->h_next;


		cvShowImage( "Window1", image );

		cvWaitKey(0);

		}



	cvDestroyWindow( "Window1" );

	cvReleaseImage( &image );

	cvReleaseImage( &image_gray );

	cvReleaseImage( &image_canny );

	cvReleaseImage( &clone );

	cvClearMemStorage( image_storage );


	return 0;

}

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


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

Здравствуйте.

Задача состоит в том чтобы выделить всего 1 контур, тот что расположен в центре кадра, по нажатию какой-либо кнопки(пробел например).

От вас хочу услышать как его найти быстрее?

Перебирать все найденые с помощью cvFindContours как-то не круто.

Контур нужно выдерить на видео. Слежение за ним пока в задачу не входит, нужно лишь обвести контур.

Также требуется как-то сгладить контур, удалить все ярковыраженные диффекты.

Всем большое спасибо.

PS код писать не обязательно :) просто советы...

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


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

Если объект однотонный, cvFloodFill с начальной координатой в центре кадра, дальше работать с маской.

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


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

Здравствуйте господа.

Изучаю OpenCV. Необходимо решить следующую задачу:

1.выделить все контуры на изображении

2.посчитать уголки для контуров

3.методом деформирующих графов найти искомый контур на изображении сравнивая его с эталоном (если конткретно то контур человека)

Столкнулся с многими проблемами.Почитал форум но ничего конкретного чисто по сравнению контуров не нашел.Задача еще усложняется тем что изображение не получается нормально отфильтровать и получаются прерывистые контуры.

Задачу решал следующим способом:

1.Преобразовал картинку в серые тона,наложил фильтр гаусса (пробовал еще медианный фильтр,но мало что получалось,никак не подобрать параметры)

2.выделял контуры с помощью cvCanny и затем cvFindContours (если смотерть параметр контура total то контуров всего 2,но все равно выделяется много лишних фоновых элементов)

Вообщем вопросы следующие:

1.как сделать нормальные замкнутые контуры,которые можно свободно выбрать и работать с ними? Нашел пример в сети http://horus20.habrahabr.ru/blog/61048/

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

Возможно надо как то поработать с фильтрами,но в каком направлении я не понял...

2.как мне посчитать уголки контура и в каком виде их можно получить? возможно с помощью cvPreCornerDetect,но эта функция вроде как со всем изображением работает

3.как получить доступ,через какую структуру,непосредственно к коду контура хотя бы в виде чейн кода...просто я думал что можно не замкнутые контуры как то самому замкнуть достраивая их

вот пример функции которая работает с изображением,которая у меня получилась на данный момент:

void processFrameKontur(IplImage* image,)  

{

 IplImage* newImage;

 IplImage* CannyOut;

 CvSeq* contours = 0;


 CvMemStorage* storage = cvCreateMemStorage(0);

 cvFlip(image,image,1);

 CvSize size = cvSize(image->width, image->height);     


 newImage = cvCreateImage(size,image->depth, 1);

 CannyOut = cvCreateImage(size,image->depth, 1);


 cvCvtColor(image,newImage,CV_RGB2GRAY);


 cvSmooth(newImage,newImage,CV_GAUSSIAN,11,3,3);//использовал эти фильтры,но сомневаюсь в их необходимости,хотя без 

 cvSmooth(newImage,newImage,CV_MEDIAN,3);//них вообще ничего толкового не выходит,ведь на самом деле в алгоритме канни и так 

                                                                                            //используется фильтр гаусса

 cvCanny(newImage,CannyOut,50,255,3);

 cvFindContours( CannyOut, storage, &contours, sizeof(CvContour), CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0) );

// contours =   cvApproxPoly(contours, sizeof(CvContour), storage, CV_POLY_APPROX_DP, 3,1 );//пытался использовать эту функцию для апроксимации 

                                                                                       //контуров,но при использовании cvCanny она просто выдает не понятные ошибки

 cvDrawContours(image, contours, CV_RGB(0,255,0), CV_RGB(255,0,0),3, 1, CV_AA, cvPoint(0,0) );

}

Вроде все должно быть просто, а проблем куча, даже с этим маленьким кодом...Вообщем буду безмерно благодарен за любую подсказку=))

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


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

Есть один ответ и один вопрос :blink:

Ответ: На Вашей ссылке в кадре только кайма знака содержит красныйс цвет, дальше думайте сами :)

Вопрос: Зачем в контуре человека находить углы ?

ЗЫ: А Вы пытались как-то отделять фон? Кстати, на углах резко уменьшается радиус кривизны контура, и еще если построите график расстояния от центра фигуры до границы, то максимумы и минимумы будут в некоторой степени углами (надо проверять еще значение производной).

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


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

Ответ: На Вашей ссылке в кадре только кайма знака содержит красныйс цвет, дальше думайте сами :)

Вопрос: Зачем в контуре человека находить углы ?

ЗЫ: А Вы пытались как-то отделять фон?

С дорожным знаком понял, спасибо :blink:

Если я правильно понимаю то углы это точки искривления контура,они необходимы для того чтобы построить граф,который как раз и будет представлять из себя шаблон...тоесть из контура вытаскиваются углы,строится граф и по положению углов относительно друг друга полученный граф сравнивается с эталонным.

А на счет фона, я даже и не пытался потому что подразумевается что фон не будет статичен,ну в том плане что камера может переносится...но если можно отделить фон в моем случае,то хотелось бы узнать как этого добиться...

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


Ссылка на сообщение
Поделиться на других сайтах
С дорожным знаком понял, спасибо :blink:

Если я правильно понимаю то углы это точки искривления контура,они необходимы для того чтобы построить граф,который как раз и будет представлять из себя шаблон...тоесть из контура вытаскиваются углы,строится граф и по положению углов относительно друг друга полученный граф сравнивается с эталонным.

А на счет фона, я даже и не пытался потому что подразумевается что фон не будет статичен,ну в том плане что камера может переносится...но если можно отделить фон в моем случае,то хотелось бы узнать как этого добиться...

Ну так её же не будут таскать с собой постоянно, первые несколько кадров снимаем, усредняем, и потом вычитаем из поступающих картинок. Можно какую нибудь кнопку сделать для этого, или по количеству измененной информации - если некоторое количество кадров (нужно определиться сколько) не отличаются друг от друга, то принять это за фон.

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


Ссылка на сообщение
Поделиться на других сайтах
Ну так её же не будут таскать с собой постоянно, первые несколько кадров снимаем, усредняем, и потом вычитаем из поступающих картинок. Можно какую нибудь кнопку сделать для этого, или по количеству измененной информации - если некоторое количество кадров (нужно определиться сколько) не отличаются друг от друга, то принять это за фон.

Согласен,спасибо!!!

А не посоветуете чем это лучше делать? а то в мануале к библиотеке есть функции,но их смысл не особо понятен...я так понимаю что мне надо выделить фон,а все объекты,которые не будут относится к фону будут представлятся как объект на пустом фоне?

И еще можно пару вопросов по вашему примеру программы сравнения контуров http://www.compvision.ru/forum/index.php?showtopic=6

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

для картинки,которая была нарисована в пэинте,и когда я запросил contours->total он мне вывел 93 контура,хотя их там явно 4 и функция cvDrawContours

их вполне нормально прорисовала с чем это может быть связано?

post-1036-1276109465_thumb.jpg

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


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

А не посоветуете чем это лучше делать? а то в мануале к библиотеке есть функции,но их смысл не особо понятен...я так понимаю что мне надо выделить фон,а все объекты,которые не будут относится к фону будут представлятся как объект на пустом фоне?

И еще можно пару вопросов по вашему примеру программы сравнения контуров http://www.compvision.ru/forum/index.php?showtopic=6

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

для картинки,которая была нарисована в пэинте,и когда я запросил contours->total он мне вывел 93 контура,хотя их там явно 4 и функция cvDrawContours

их вполне нормально прорисовала с чем это может быть связано?

post-1036-1276109465_thumb.jpg

По первому вопросу посмотрите cvRunningAvg, cvSub, cvAbsDiff.

Что касается второго - просто там очень много слабо отличающихся контуров, отсейте контуры с примерно одинаковой площадью и центром.

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


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

У меня еще одна просьба,не могли бы вы посоветовать,какими функциями можно найти угли,дуги и линии в контуре, чтобы их потом в граф добавить?

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


Ссылка на сообщение
Поделиться на других сайтах
У меня еще одна просьба,не могли бы вы посоветовать,какими функциями можно найти угли,дуги и линии в контуре, чтобы их потом в граф добавить?

Посмотрите cvHoughLines и cvHoughCircles, по поводу углов писал выше, придется делать руками.

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


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

Ага,спасибо!

Только еще одна проблема как добраться до координат точек контура,чтобы вычислить углы,т.е. мне нужны X и Y координаты каждой точки чтобы в цикле по ним пробежаться,и будут ли эти координаты соответствовать координатам в окошке где выводиться изображение? и что будет с координатами если есть разрывы в контуре? ну тоесть будут ли эти разрывы учитываться в последовательности координат? или просто пропускаться?

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


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

Только еще одна проблема как добраться до координат точек контура,чтобы вычислить углы,т.е. мне нужны X и Y координаты каждой точки чтобы в цикле по ним пробежаться,и будут ли эти координаты соответствовать координатам в окошке где выводиться изображение? и что будет с координатами если есть разрывы в контуре? ну тоесть будут ли эти разрывы учитываться в последовательности координат? или просто пропускаться?


// Объявление читалки точек
CvSeqReader reader;
// Инициализация читалки точек
cvStartReadSeq( result, &reader, 0 );
// Две точки
CvPoint pt[2];

// Достаем точки из хранилища точек и рисуем линии
for (int i=0;i<result->total-1;i++)
{
CV_READ_SEQ_ELEM( pt[0], reader );
CV_READ_SEQ_ELEM( pt[1], reader );
cvLine(img,pt[0],pt[1],CV_RGB(255,0,0));
}[/code]

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


Ссылка на сообщение
Поделиться на других сайтах
...когда я запросил contours->total он мне вывел 93 контура,хотя их там явно 4 и функция cvDrawContours

их вполне нормально прорисовала с чем это может быть связано?

Коллега, я так понимаю, что запросив contours->total Вы получили количество точек в первом контуре вместо количества контуров. Дальше в цикле надо обходить по всем контурам и считать сколько их всего:

for(;contours!=0;contours = contours->h_next, contours++){...

Четыре контура всего и получается, я даже не поленился проверить:

Shapes.png

Андрей.

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


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

Блин, ошибся я, а отредактировать пост не получается...

В общем как-то так

for(nContours = 0; contours!=0; contours = contours->h_next, nContours++){...

Извиняйте за двойной пост,

Андрей.

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


Ссылка на сообщение
Поделиться на других сайтах
Блин, ошибся я, а отредактировать пост не получается...

В общем как-то так

for(nContours = 0; contours!=0; contours = contours->h_next, nContours++){...

Извиняйте за двойной пост,

Андрей.

До этого у меня стоят строчки:

for(;contours!=0;contours = contours->h_next)

{

// Аппр. контуров полигонами

result = cvApproxPoly( contours, sizeof(CvContour), storage,CV_POLY_APPROX_DP, cvContourPerimeter(contours)*0.001, 0 );

// Площадь полигона

double area=fabs(cvContourArea(result,CV_WHOLE_SEQ));

А полный текст есть на форуме в примере сравнения контуров.

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


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

for(;contours!=0;contours = contours->h_next)

{

// Аппр. контуров полигонами

result = cvApproxPoly( contours, sizeof(CvContour), storage,CV_POLY_APPROX_DP, cvContourPerimeter(contours)*0.001, 0 );

// Площадь полигона

double area=fabs(cvContourArea(result,CV_WHOLE_SEQ));

А полный текст есть на форуме в примере сравнения контуров.

Да, спасибо, пример хороший.

Только там двумя строчками выше вот какая конструкция:

cvFindContours( gray, storage,&contours,sizeof(CvContour),CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE,cvPoint(0,0))

;

//--------------

if(contours!=0)

{

NumCont=contours->total; // количество найденных контуров

}

Если я правильно понимаю тип CvSeq, то в NumCont попадает не общее количество найденных контуров, а количество точек в первом контуре (ну, у меня во всяком случае) - я это имел ввиду.

Андрей.

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


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

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

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

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

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

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

Войти

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

Войти сейчас


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

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

×