KNCH 0 Жалоба Опубликовано January 15, 2011 Здравствуйте! Прошу дать совет по фильтрам/алгоритмам (а лучше подходящие функции, если такие имеются), при помощи которых можно выделить объект, приведённый на прикреплённых снимках (на втором изображении объект обведён красным). Пробую вариировать параметры threshold(), inRange(), GaussianBlur(), но, к сожалению безуспешно. Так же пробовал использовать HoughCircles(), но опять же безуспешно (либо много кругов, либо вообще нет, либо ошибочно). Буду очень рад Вашей помощи. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано January 15, 2011 Здравствуйте! Прошу дать совет по фильтрам/алгоритмам (а лучше подходящие функции, если такие имеются), при помощи которых можно выделить объект, приведённый на прикреплённых снимках (на втором изображении объект обведён красным). Пробую вариировать параметры threshold(), inRange(), GaussianBlur(), но, к сожалению безуспешно. Так же пробовал использовать HoughCircles(), но опять же безуспешно (либо много кругов, либо вообще нет, либо ошибочно). Буду очень рад Вашей помощи. Боюсь просто не отделаетесь. Можно попробовать натренировать каскад Хаара на эти объекты. Или активные модели применить, и то и другое потребует изрядных усилий. Но более простого ничего в голову не приходит. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Nuzhny 243 Жалоба Опубликовано January 15, 2011 Согласен, что выделение простым не будет. Вообще говоря, перед началом решения подобной задачи нужно на естественном (русском) языке выделить отличительные признаки объекта, как его можно однозначно классифицировать, отделить от других. Если это удаётся (например круг от прямоугольника или изображение единицы от нуля), то можно пошагово реализовывать словесную классификацию в программе. Если не удаётся (а для многих сложных объектов это так), то создавай выборку изображений, выбирай классификатор и тренируй его. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
KNCH 0 Жалоба Опубликовано January 15, 2011 Боюсь просто не отделаетесь. Можно попробовать натренировать каскад Хаара на эти объекты. Или активные модели применить, и то и другое потребует изрядных усилий. Но более простого ничего в голову не приходит. СпасиБо за быстрый ответ. Я тоже думал про каскад Хаара, точнее даже запустил его генерацию, но по истечении 36+ часов генерация практически не сдвинулась с места, это при том, что я (только для теста) сделал только 3 позитивных и три негативных изображения (или из-за такого маленького количества могут быть проблемы?), с параметрами всё в порядке вроде -- отталкивался от топиков на этом форуме и от других мануалов. Да и потом проблема то в том, что снимков с такими вот объектами в сети практически нет, а следовательно нет в принципе смысла создавать коллекцию из сгенерированных изображений. Вобщем Хаар, я думаю, отпадает. Я больше думаю в сторону отделения приближённых к окружности объектов и потом через сравнение площади определять искомый ли это объект или нет. За ссылку спасиБо! Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
KNCH 0 Жалоба Опубликовано January 15, 2011 Согласен, что выделение простым не будет. Вообще говоря, перед началом решения подобной задачи нужно на естественном (русском) языке выделить отличительные признаки объекта, как его можно однозначно классифицировать, отделить от других. Если это удаётся (например круг от прямоугольника или изображение единицы от нуля), то можно пошагово реализовывать словесную классификацию в программе. Если не удаётся (а для многих сложных объектов это так), то создавай выборку изображений, выбирай классификатор и тренируй его. Единственное отличие - это округлая форма, и возможно более яркий цвет. Но на данном снимке этот объект - не единственное яркое "пятно". С созданием классификации тоже проблема, как я уже писал выше, так как нет такой базы данных. В любом случае, спасиБо за советы! Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Nuzhny 243 Жалоба Опубликовано January 16, 2011 Если принять гипотезу, что наш объект внутри тёмный, а снаружи светлый, то можно воспользоваться операциями математической морфологии: CV_MOP_TOPHAT - поиск светлых областей и CV_MOP_BLACKHAT - поиск тёмных областей. После построить гистограмму для каждого результата, найти по ней порог, бинаризовать, отсеять мелкие объекты эрозией, результат нарастить, найти на нём контуры. Если в результате получатся вложенные контуры, то искомый объект найден. Как тебе идея? Сразу предупреждаю, что код довольно корявый - писал его быстро, только ради иллюстрации: #include "stdafx.h" #include <cv.h> #include <highgui.h> int main(int argc, char* argv[]) { IplImage* image = cvLoadImage("d:\\resultFrame4.png", 0); IplImage* tophat = cvCloneImage(image); IplImage* blackhat = cvCloneImage(image); IplImage *result = cvCreateImage(cvSize(image->width, image->height), IPL_DEPTH_8U, 1); cvShowImage("original",image); int radius = 2; IplConvKernel* Kern = cvCreateStructuringElementEx(radius * 2 + 1, radius * 2 + 1, radius, radius, CV_SHAPE_ELLIPSE); IplImage* Temp = cvCreateImage(cvSize(image->width, image->height), IPL_DEPTH_8U, 1); int iterations = 7; cvMorphologyEx(image, tophat, Temp, Kern, CV_MOP_TOPHAT, iterations); cvMorphologyEx(image, blackhat, Temp, Kern, CV_MOP_BLACKHAT, iterations); cvShowImage("CV_MOP_TOPHAT", tophat); cvShowImage("CV_MOP_BLACKHAT", blackhat); { int hist[256] = {0}; for (unsigned char *ib = (unsigned char *)tophat->imageData, *stopb = (unsigned char *)(tophat->imageData + tophat->imageSize); ib != stopb; ++ib) { ++hist[*ib]; } int threshold = 255; int sum = 0; for (int i = 255; i != 0; --i) { sum += hist[i]; if (sum > tophat->imageSize / 100) { threshold = i; break; } } cvThreshold(tophat, tophat, threshold, 255, CV_THRESH_BINARY); cvErode(tophat, tophat, NULL, 1); cvDilate(tophat, tophat, NULL, 7); cvShowImage("binary_tophat", tophat); } { int hist[256] = {0}; for (unsigned char *ib = (unsigned char *)blackhat->imageData, *stopb = (unsigned char *)(blackhat->imageData + blackhat->imageSize); ib != stopb; ++ib) { if (*ib > 100) *ib = 0; ++hist[*ib]; } int threshold = 255; int sum = 0; for (int i = 255; i != 0; --i) { sum += hist[i]; if (sum > blackhat->imageSize / 100) { threshold = i; break; } } cvThreshold(blackhat, blackhat, threshold, 255, CV_THRESH_BINARY); cvErode(blackhat, blackhat, NULL, 1); cvDilate(blackhat, blackhat, NULL, 7); cvShowImage("binary_blackhat", blackhat); } #if 1 cvSet(result, cvScalar(0)); #else cvOr(tophat, blackhat, result); #endif { CvMemStorage *storage = cvCreateMemStorage(0); CvContourScanner cs = cvStartFindContours(tophat, storage, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_NONE); CvSeq *mContour = 0; for (CvSeq *contour = cvFindNextContour(cs); contour; contour = cvFindNextContour(cs)) { if (contour->total >= 6) { CvBox2D box = cvFitEllipse2(contour); CvPoint center = cvPointFrom32f(box.center); CvSize size = cvSize(cvRound(box.size.width * 0.5), cvRound(box.size.height * 0.5)); cvEllipse(result, center, size, -box.angle, 0, 360, CV_RGB(0, 0, 255), 1, CV_AA, 0); } } cvEndFindContours(&cs); cvReleaseMemStorage(&storage); } { CvMemStorage *storage = cvCreateMemStorage(0); CvContourScanner cs = cvStartFindContours(blackhat, storage, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_NONE); CvSeq *mContour = 0; for (CvSeq *contour = cvFindNextContour(cs); contour; contour = cvFindNextContour(cs)) { if (contour->total >= 6) { CvBox2D box = cvFitEllipse2(contour); CvPoint center = cvPointFrom32f(box.center); CvSize size = cvSize(cvRound(box.size.width * 0.5), cvRound(box.size.height * 0.5)); cvEllipse(result, center, size, -box.angle, 0, 360, CV_RGB(0, 0, 255), 1, CV_AA, 0); } } cvEndFindContours(&cs); cvReleaseMemStorage(&storage); } cvShowImage("result", result); cvReleaseStructuringElement(&Kern); cvReleaseImage(&Temp); while(1) { if (cvWaitKey(33) > 0) break; } cvReleaseImage(&result); cvReleaseImage(&image); cvReleaseImage(&tophat); cvReleaseImage(&blackhat); cvDestroyAllWindows(); return 0; } 1 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
KNCH 0 Жалоба Опубликовано January 17, 2011 Если принять гипотезу, что наш объект внутри тёмный, а снаружи светлый, то можно воспользоваться операциями математической морфологии: CV_MOP_TOPHAT - поиск светлых областей и CV_MOP_BLACKHAT - поиск тёмных областей. После построить гистограмму для каждого результата, найти по ней порог, бинаризовать, отсеять мелкие объекты эрозией, результат нарастить, найти на нём контуры. Если в результате получатся вложенные контуры, то искомый объект найден. Как тебе идея? Сразу предупреждаю, что код довольно корявый - писал его быстро, только ради иллюстрации: ... Огромное-огромное спасиБо!! Видать, я слишком быстро "прощёлкал" tophat и blackhat. Буду пробовать, потом отпишусь. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
kudukSweetone 3 Жалоба Опубликовано January 18, 2011 Здравствуйте всем! Имеется видеоролик с записью передвижения живых клеток крови. Передо мной поставлена задача выделить каждую клетку на видео и построить галерею найденных объектов. Подскажите, пожалуйста, как это можно реализовать? Дело в том, что я здесь на форуме нашел код где используется преобразование Хафа для выделения окружностей, но в результате получаются множественные окружности в произвольных местах и видео сильно тормозит. Как это исправить? Или может есть другой способ решения поставленной задачи? Вот ролик test.rar и код CircleDetection.rar. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Romiks 6 Жалоба Опубликовано January 18, 2011 при вызове cvHoughCircles задайте минимальный и максимальный радиус окружности, тогда правильно выделится процентов 60, я поставил 5 и 40. Также можно попробовать отделить клетки от фона и потом применять преобразование Хафа, короче надо экспериментировать... Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Nuzhny 243 Жалоба Опубликовано January 18, 2011 Сохрани изображение одной клетки, а после используй его как шаблон для функции cvMatchTemplate. Порог выбирай небольшой, в районе 0.1 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Nuzhny 243 Жалоба Опубликовано January 18, 2011 Да, ещё можно, как советовал Romiks, отделить клетки от фона. И искать уже по бинарному изображению Это можно сделать, например, так:cvSmooth(gray, gray, CV_GAUSSIAN, 5, 5); cvCanny(gray, gray, 50, 150); cvDilate(gray, gray, NULL, 2); cvErode(gray, gray, NULL, 2); Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
KNCH 0 Жалоба Опубликовано January 19, 2011 Пока я решил остановиться только на применении TopHat и вычислении площади контуров, этого вполне достаточно. По логике ведь, выпуклые объекты всегда будут светлее при освещении эндоскопической камеры (да и не только её). Ну края тоже бывают светлыми, т.к. они ближе, но я накладываю круглую маску на изображение и края обрезаются (http://nashruddin.com/OpenCV_Circular_ROI). Огромное спасиБо ещё раз за идею, Вы меня спасли! =) Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
kudukSweetone 3 Жалоба Опубликовано January 19, 2011 Спасибо всем за предложения, попробую похимичить. В ходе раздумий появилась следующая идея усовершенствования программы: дело в том, что на изображении есть как правило несколько видов клеток крови. Возможно ли сделать так чтобы пользователь щелчком мыши указывал на клетку, она сохранялась как образец, и затем искались и выделялись клетки подобные ей? Может что-то похожее есть в примерах к OpenCV? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Romiks 6 Жалоба Опубликовано January 19, 2011 В ходе раздумий появилась следующая идея усовершенствования программы: дело в том, что на изображении есть как правило несколько видов клеток крови. Возможно ли сделать так чтобы пользователь щелчком мыши указывал на клетку, она сохранялась как образец, и затем искались и выделялись клетки подобные ей? Может что-то похожее есть в примерах к OpenCV? а разве клетки на видео чем-то друг от друга отличаются?, если да это это сложновато будет сделать, а если нет то попробовать можно Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Nuzhny 243 Жалоба Опубликовано January 19, 2011 Может что-то похожее есть в примерах к OpenCV?Есть выделение мышью в стандартном примере camshiftdemo. Вот программа с иллюстрацией работы cvMatchTemplate: #include "stdafx.h" #include <cv.h> #include <highgui.h> #define USE_BINARY_TEMPL //////////////////////////////////////////////////////////////////////////// int _tmain(int argc, _TCHAR* argv[]) { CvCapture* capture = cvCaptureFromAVI("d:\\test.avi"); if (!capture) return 1; #ifdef USE_BINARY_TEMPL IplImage *tpl = cvLoadImage("d:\\cell.png", 0); #else IplImage *tpl = cvLoadImage("d:\\cell_cl.png", 1); #endif IplImage *gray = NULL; IplImage *res = NULL; for (IplImage *frame = cvQueryFrame(capture); frame; frame = cvQueryFrame(capture)) { if (!gray) gray = cvCreateImage(cvGetSize(frame), IPL_DEPTH_8U, 1); int w = frame->width - tpl->width + 1; int h = frame->height - tpl->height + 1; if (!res) res = cvCreateImage(cvSize(w, h), IPL_DEPTH_32F, 1); #ifdef USE_BINARY_TEMPL cvCvtColor(frame, gray, CV_BGR2GRAY); cvSmooth(gray, gray, CV_GAUSSIAN, 5, 5); cvCanny(gray, gray, 50, 150); cvDilate(gray, gray, NULL, 2); cvErode(gray, gray, NULL, 2); cvMatchTemplate(gray, tpl, res, CV_TM_SQDIFF_NORMED); #else cvMatchTemplate(frame, tpl, res, CV_TM_SQDIFF_NORMED); #endif cvShowImage("gray", gray); cvSet(gray, cvScalar(0)); #ifdef USE_BINARY_TEMPL float threshold = 0.8f; #else float threshold = 0.08f; #endif for (int y = 0 ; y < res->height; ++y) { for (int x = 0 ; x < res->width ; ++x) { CvScalar s = cvGet2D(res, y, x); if (s.val[0] < threshold) cvSet2D(gray, y, x, cvScalar(255)); } } CvMemStorage *storage = cvCreateMemStorage(0); CvContourScanner cs = cvStartFindContours(gray, storage, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_NONE); for (CvSeq *contour = cvFindNextContour(cs); contour; contour = cvFindNextContour(cs)) { if (contour->total >= 6) { CvBox2D box = cvFitEllipse2(contour); CvPoint center = cvPointFrom32f(box.center); cvCircle(frame, cvPoint(center.x + tpl->width / 2, center.y + tpl->height / 2), tpl->width / 2, CV_RGB(0, 255, 255)); } } cvEndFindContours(&cs); cvReleaseMemStorage(&storage); cvShowImage("color", frame); if (cvWaitKey(30) == 27) break; } cvReleaseImage(&res); cvReleaseImage(&tpl); cvReleaseImage(&gray); cvReleaseCapture(&capture); cvDestroyAllWindows(); return 0; } //////////////////////////////////////////////////////////////////////////// Если закомментируешь строку #define USE_BINARY_TEMPL, то сравнение будет идти с цветной клеткой (cell_cl.png), иначе с чёрно-белой бинаризованной (cell.png). Примеры клеток шаблонов: Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Gizatulin 9 Жалоба Опубликовано January 10, 2012 Есть задачка: Есть изображения с органами человека. На картинке нужно распознавать органы. То есть если там сердце, программа должна выделить и подписать "сердце". Не подскажешь каким методом лучше реализовать? 1 Думаю использовать обучение каскадов Хаара 2 Или как-нибудь задать шаблоны контуров и делать поиск по контурам. Есть какие-нибудь идеи? То есть суть задачи пользователь задает какой-то шаблон и дает название. На изображении по шаблону ищутся объекты. Сложность в том объект может отображаться по-разному. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано January 10, 2012 Темы для "почитать и подумать": http://www.compvision.ru/forum/index.php?showtopic=411&st=0&p=2266&hl=%D0%B0%D0%BA%D1%82%D0%B8%D0%B2%D0%BD%D1%8B%D0%B5&fromsearch=1&#entry2266 http://www.compvision.ru/forum/index.php?showtopic=502&st=0&p=3019&hl=%D0%B0%D0%BA%D1%82%D0%B8%D0%B2%D0%BD%D1%8B%D0%B5&fromsearch=1&#entry3019 http://www.compvision.ru/forum/index.php?showtopic=15&st=80&p=4581&hl=%D0%B0%D0%BA%D1%82%D0%B8%D0%B2%D0%BD%D1%8B%D0%B5&fromsearch=1&#entry4581 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
bbbbbaran 0 Жалоба Опубликовано January 11, 2012 Спасибо! 1 SURF мне точно не подойдет. 2 каскадов Хаара - если только самому обучить все органы и ищет он все равно слабо. А так если сделать какой-то конструктор, что бы пользователь сам мог обучать, но обучение долго идет. Как я понял решения, что бы задать какой-то шаблон для объекта и потом искать по шаблону объект нету. В каждом случаи идет подбор определенных параметров под искомый объект. Но под каждый орган такое делать... Есть ли какие-нибудь решения, которые более менее ищут объекты? Что бы можно было ввести либо параметры или шаблоны какие-то, а по ним уже поиск делать. PS: Много битых ссылок на страницах. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано January 11, 2012 Ссылки посмотрю. Форум падал как то, до сих пор разгребаю. По поводу SURF , я бы подумал. На счет Хаара это Вы правильно решили. Легкого пути здесь не будет. Модель объекта придется делать в любом случае, и чем модель содержит больше информации об объекте, тем лучше будет качество работы алгоритма поиска. Часто для выделения органов на медицинских изображениях используют Active Appeareance Models (AAM), Active Shape Models (ASM), и змеиные алгоритмы. Вот ссылки: http://www.scs.ryerson.ca/tmcinern/mypapers/papers.html http://www.lumc.nl/con/1010/83058/87377/87386/904011158482222/ Можно подгонять еще и трехмерные модели (параметрические), но для этого надо их создать. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано January 12, 2012 непонятно как у вас выглядят эти органы, как они могут варьироваться и т.д. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Gizatulin 9 Жалоба Опубликовано January 12, 2012 рентгеновские снимки. К примеру сердце. Вид сердца на картинке может быть разный. Хотелось сделать, что-то универсальное. Что бы можно было через какой-то конструктор задавать шаблон и по нему был бы поиск. Я понял уже что так сделать не просто. Скорее всего придется для каждого органа писать свой алгоритм распознавания. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано January 12, 2012 если они имеют non-rigid форму, то да будет сложно, то что выше обозначено Часто для выделения органов на медицинских изображениях используют Active Appeareance Models (AAM), Active Shape Models (ASM), и змеиные алгоритмы. наверно может помочь. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано January 12, 2012 Вот тут посмотрите, может пригодится: http://www.compvision.ru/forum/index.php?showtopic=443 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Gizatulin 9 Жалоба Опубликовано January 12, 2012 вот примеры фалов Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Gizatulin 9 Жалоба Опубликовано January 12, 2012 Вот тут посмотрите, может пригодится: http://www.compvision.ru/forum/index.php?showtopic=443 это не то, так как мне поиск надо делать. То есть будет поиск либо по алгоритму или по шаблону для нужного органа. Сейчас вот смотрю Active Appeareance Models, Active Shape Models (ASM). Или думаю использовать SURF, только сравнивать не с одной картинкой, а с несколькими в разных положениях. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах