Smorodov 579 Жалоба Опубликовано October 4, 2011 А что, в таком случае, мешает сразу (в той же функции) поточечно перекинуть в глобальное хранилище (из единственного необходимого локального) контур за контуром в по мере их нахождения? Я именно это имел ввиду вначале. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Reegool 0 Жалоба Опубликовано October 4, 2011 А что, в таком случае, мешает сразу (в той же функции) поточечно перекинуть в глобальное хранилище (из единственного необходимого локального) контур за контуром в по мере их нахождения? Я именно это имел ввиду вначале. Мешает незнание алгоритма того как это сделать Как извлечь контур из одной последовательности и поместить его содержимое в другую последовательность, при этом, переместив не просто ссылку на содержимое во временном хранилище, а перенести именно сами данные из временного хранилища в основное? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано October 4, 2011 При создании sequence надо делать так: CvSeq* seq = cvCreateSeq( (CV_SEQ_FLAG_CLOSED|CV_SEQ_KIND_CURVE|CV_SEQ_ELTYPE_POINT), sizeof(CvContour), sizeof(CvPoint), storage ); [/code] Что делает ее полигоном! дальше запись точек в последовательность. [code] CvSeqWriter writer; int i; cvStartAppendToSeq( seq, &writer ); CvPoint pt = cvPoint(20,20); CV_WRITE_SEQ_ELEM( pt, writer ); printf("[%d,%d] is written\n", pt.x, pt.y ); pt = cvPoint(30,50); CV_WRITE_SEQ_ELEM( pt, writer ); printf("[%d,%d] is written\n", pt.x, pt.y ); pt = cvPoint(50,60); CV_WRITE_SEQ_ELEM( pt, writer ); printf("[%d,%d] is written\n", pt.x, pt.y ); pt = cvPoint(45,30); CV_WRITE_SEQ_ELEM( pt, writer ); printf("[%d,%d] is written\n", pt.x, pt.y ); cvEndWriteSeq( &writer ); Читать точки можно как здесь: CvMemStorage *storage = cvCreateMemStorage(0); CvContourScanner cscaner = cvStartFindContours(src1, storage, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_NONE); for (CvSeq *contour = cvFindNextContour(cscaner); contour; contour = cvFindNextContour(cscaner)) { CvSeqReader reader; cvStartReadSeq( contour, &reader, 0 ); CvPoint pt[2]; for (int i = 0; i < contour->total - 1; i += 2) { CV_READ_SEQ_ELEM(pt[0], reader); CV_READ_SEQ_ELEM(pt[1], reader); cvLine(img12, pt[0], pt[1], CV_RGB(255, 0, 0), 4); } } cvEndFindContours(&cscaner); cvReleaseMemStorage(&storage);[/code] Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Reegool 0 Жалоба Опубликовано October 4, 2011 Большое спасибо. Пошел пробовать Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано October 4, 2011 И еще, с С++ версией работать легче, там FindContours возвращает вектор векторов и работа с ними точно такая же как с std-шными векторами. Вот можно посмотреть здесь: http://www.compvision.ru/forum/index.php?showtopic=625&st=0&p=4027&hl=unicode&fromsearch=1&#entry4027 И здесь: http://opencv.willowgarage.com/documentation/cpp/structural_analysis_and_shape_descriptors.html#cv-findcontours Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Reegool 0 Жалоба Опубликовано October 4, 2011 Спасибо за подсказки. Обязательно посмотрю в этом направлении. Сейчас стоит цель хоть немного освоиться с OpenCV на примере решения конкретных (простеньких) задач. В частности, на данном этапе, работа с контурами. У меня будут еще вопросы. Точнее они уже есть, но пока сам поковыряюсь Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Reegool 0 Жалоба Опубликовано October 11, 2011 Здравствуйте все У меня снова вопрос. Интересовался ли кто-нибудь вопросом вычисления контуров с учетом цвета, то есть, поиском контуров в, например, RGB изображение? Измученный гугель выдал мне только один вразумительный ответ. Но пример написан на Java. Статья тут, код на Java тут. Речь там идет о детекторе границ Canny Для OpenCV ничего подобного нет. Проверял Есть ли у кого подобные решения? Или, может, всем миром перепишем это дело под C++ ? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Nuzhny 243 Жалоба Опубликовано October 11, 2011 Можно проще (меньше кода писать). Конвертируешь изображение в HSV (cvCvtColor), берёшь самый первый канал - hue, цветовой тон (cvSplit) и уже к нему применяешь Каннни. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Reegool 0 Жалоба Опубликовано October 12, 2011 Можно проще (меньше кода писать). Конвертируешь изображение в HSV (cvCvtColor), берёшь самый первый канал - hue, цветовой тон (cvSplit) и уже к нему применяешь Каннни. Мысль интересная. Спасибо. Будем попробовать. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
AuST 0 Жалоба Опубликовано November 8, 2011 Скажите пожалуйста, как можно определить угол поворота контура относительно исходного контур? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано November 8, 2011 Надо определить поворот главной оси инерции для отдельно для одного и для другого контуров, а затем, найти разницу. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
AuST 0 Жалоба Опубликовано November 9, 2011 А можно в функциях? )) Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано November 9, 2011 Здесь есть http://www.compvision.ru/forum/index.php?showtopic=6 ищите theta Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Ostis 1 Жалоба Опубликовано November 14, 2011 Доброго времени суток. Где можно почитать про код Фримена? В learning OpenCV ну очень непонятно. Суть такая: нужно с помощью cvFindContours получить код Фримена и переписать его, скажем, в одномерный масив Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано November 14, 2011 Вот тут, например: http://msabundo.blogspot.com/2010/03/freemans-silhouette.html А вообще, по картинке смысл должен быть понятен: В opencv cvFindContours выдает цепной код (он же код Фримана) если в качестве параметра metod передать константу "CV_CHAIN_CODE". Из руководства: CV_CHAIN_CODE outputs contours in the Freeman chain code. Пример чтения значений из cvSeq есть в этой теме. 1 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Ostis 1 Жалоба Опубликовано November 15, 2011 Спасибо, все получилось. Кому интересно, вот код: int i, total = contours->total; cvStartReadChainPoints((CvChain*) contours, &reader); for (i = 0; i < total; i++) { CV_READ_SEQ_ELEM(reader.code, (*((CvSeqReader*)&(reader)))); printf("%d \n", reader.code); } 1 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
kudukSweetone 3 Жалоба Опубликовано November 30, 2011 Добрый день! Подскажите, пожалуйста, у кого какие соображения как подсчитать количество контуров в слипшихся объектах? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано December 7, 2011 Это тот случай (случай 1) когда без дополнительной информации об объекте не обойтись. Если это окружности, то тут все просто, если какой то другой известный объект то тоже, а по такой картинке, без доп. информации и человек может ошибаться. Во втором случае, все контуры должны находиться нормально (однако и здесь, информация о том что мы ищем должны быть использована по-максимуму), нужно только правильно указать степень вложенности контуров, которые Вас интересуют. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано January 16, 2012 как можно "восстановить" контур от разрывов и убрать двойной контур т.е. если расстояние между контурами <eps то он считается за один контур. + еще вопрос как возможно сделать как бы "прямоугольный контур" , aproxpoly это не то, т.к. он делает ломаную, а мне надо именно чтобы контур состоял из вертикальных-горизонтальных линий. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано January 16, 2012 Может быть триангулировать? Это может помочь решить проблему корректного разделения контуров. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано January 16, 2012 не понял, как поможет триангуляция, это же что то типа деления на треугольники? не? http://qvision.sourceforge.net/opencv-delaunay.png Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано January 16, 2012 Да, она самая. Прикол в том, что мы получим плоский граф. Затем разорвем ребра (предполагаю что это наикратчайшие ребра каждого из треугольников), которые длиннее заданного порога и получим несколько подграфов, которые и будут нашими объектами. ЗЫ: Подумал еще немного, тут нужны какие то более сложные правила. Например коллинеарность смежных ребер. Может быть еще что-то. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано January 16, 2012 всё равно не понятно, область одного треугольника что собой являет? и зачем мне что то разбивать на объекты? я хотел подойти с той точки зрения, что если замнкнутый контур представляет собой "тонкую" фигуру, то каким то образом спрямить все это дело в линию. по большому счету, хотел просто пройтись по точкам контура и определить на нем группы точек которые вписываются в линию, т.е. на тонком контуре их будет 2 и затем если длина линий примерно одинаковая и расстояние достаточно мало, то объединить их в одну линию. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано January 16, 2012 Ну для преобразования "тонких контуров" в отрезки обычная линейная регрессия подойдет. Считаем регрессию, а потом ищем ошибку как тут, например (SSE) http://www.machinelearning.ru/wiki/index.php?title=%D0%9B%D0%B8%D0%BD%D0%B5%D0%B9%D0%BD%D0%B0%D1%8F_%D1%80%D0%B5%D0%B3%D1%80%D0%B5%D1%81%D1%81%D0%B8%D1%8F_(%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D1%80) если она меньше заданного порога, значит контур "тонкий" и его можно заменить на отрезок. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано January 16, 2012 имеется ввиду вписывание в точки линии наилучшим образом? еще нашел cvFindDominantPoints должна находить углы, т.е. области наибольшего закругления,но походу ф-ия не работает, у меня падает с ошибкой. код пробовал такой. #include "cv.h" #include "highgui.h" CvSeq* contours = 0; CvSeq* dps = 0; int main( int argc, char** argv ) { int i, idx; CvPoint p; CvMemStorage* storage_ct = cvCreateMemStorage(0); CvMemStorage* storage_dp = cvCreateMemStorage(0); IplImage* img = cvLoadImage("contour.bmp", CV_LOAD_IMAGE_GRAYSCALE); cvNamedWindow( "image" ); cvShowImage( "image", img ); cvFindContours( img, storage_ct, &contours, sizeof(CvContour), CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE ); dps = cvFindDominantPoints( contours, storage_dp, CV_DOMINANT_IPAN, 7, 20, 9, 150 ); contours = cvApproxPoly( contours, sizeof(CvContour), storage_ct, CV_POLY_APPROX_DP, 3, 1 ); printf("found %d DPs and %d Contours \n", dps->total, contours->total ); for ( i = 0; i < dps->total; i++) { idx = *(int *) cvGetSeqElem(dps, i); p = *(CvPoint *) cvGetSeqElem(contours, idx); cvDrawCircle( img, p , 1, cvScalarAll(255) ); printf("%d %d %d\n", idx, p.x, p.y); } cvDrawContours(img, contours, cvScalarAll(100), cvScalarAll(200), 100 ); cvNamedWindow( "contours" ); cvShowImage( "contours", img ); cvWaitKey(0); cvReleaseMemStorage( &storage_ct ); cvReleaseMemStorage( &storage_dp ); cvReleaseImage( &img ); return 0; } Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах