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

Alexer

Пользователи
  • Количество публикаций

    6
  • Зарегистрирован

  • Посещение

Репутация

0 Новичек

О Alexer

  • Звание
    Новичок
  1. Работа с контурами

    Спасибо огромнейшее, разобрался с этим вопросом. Я хотел бы спросить у Вас еще..вот после вычитания маски из исходного изображения, был получен знак. А вот как его лучше распознать? Я хотел сравнивать данный знак "40", со знаком "40" из ГОСТа и на основе какого-то процентного совпадения сделать вывод с определённой вероятностью, что это именно этот знак. Насколько такой метод эффективен и можно ли где нибудь почитать о реализации чего-то подобного в OpenCV? Есть ли у него какие нибудь "подводные камни"? Сможет ли программа узнать знак, если предположим, они по какой-либо причине разных размеров?(допустим изображение знака в программе меньше, чем знак на изображении шаблона). Извините, что так много вопросов и скорее всего большинство из них действительно глупые, но я нашёл довольно мало реcурсов в рунете, посвящённых OpenCV( Ваш форум и robocraft.ru)
  2. Работа с контурами

    Мне пришлось переписать данный код на C# ввиду требования руководителя. Вот именно на C# у меня вывело ContourArea = -4. if(Math.Abs(Cv.ContourArea(contours))>20) { Contour.DrawContours(contours, CvColor.White, CvColor.White, 2, Cv.FILLED, LineType.Link8); Console.WriteLine(cv.ContourArea(contours); } Но в данной ситуации рисуются все контуры абсолютно(включая маленькие). Может нужно как-то посчитать площадь каждого контура, чтобы потом отсеять? А на C код у меня выглядел вот так, но он рушится на условии if(abs(cvContourArea(storage))>20). #include "stdafx.h" #include <stdio.h> #include <stdlib.h> #include <cv.h> #include <highgui.h> int main(int argc, char* argv[]) { //Создаём 3 изображения IplImage* sign = cvLoadImage("D:\\1.jpg",3); IplImage* sign_hsv=cvCreateImage(cvGetSize(sign),IPL_DEPTH_8U,3); IplImage* sign_bin=cvCreateImage(cvGetSize(sign),IPL_DEPTH_8U,1); IplImage* canny = cvCreateImage(cvGetSize(sign),IPL_DEPTH_8U,1); IplImage* mask = cvCreateImage(cvGetSize(sign),IPL_DEPTH_8U,1); //Создание маски cvSet(mask,cvScalar(0,0,0)); //Преобразуем исходное изображение в градации серого cvCvtColor(sign,sign_hsv,CV_BGR2HSV); //Проводим бинаризацию полученного изображения(преобразуем в двоичное) cvInRangeS(sign_hsv, cvScalar(170,100,100), cvScalar(179,255,255), sign_bin); cvCanny(sign_bin,canny,50,255,5); cvSmooth(canny,canny,CV_BLUR,2,2); //Хранилище памяти для контуров CvMemStorage* storage = cvCreateMemStorage(0); CvSeq* contours=0; //Поиск контура cvFindContours(canny,storage,&contours,sizeof(CvContour),CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0)); if(abs(cvContourArea(storage))>20) { // рисуем найденный контур НА маске и заливаем его белым cvDrawContours(mask,contours, CV_RGB(255,255,255),CV_RGB(255,255,255), 2, CV_FILLED, CV_AA, cvPoint(0,0)); } cvNamedWindow("Original",CV_WINDOW_AUTOSIZE); cvNamedWindow("Gray",CV_WINDOW_AUTOSIZE); cvNamedWindow("Bin",CV_WINDOW_AUTOSIZE); cvNamedWindow("Canny",CV_WINDOW_AUTOSIZE); cvNamedWindow("Mask",CV_WINDOW_AUTOSIZE); cvShowImage("Original",sign); cvShowImage("Gray",sign_hsv); cvShowImage("Bin",sign_bin);; cvShowImage("Сanny",canny); cvShowImage("Mask",mask); cvWaitKey(0); cvReleaseImage(&sign); cvReleaseImage(&sign_hsv); cvReleaseImage(&sign_bin); cvReleaseImage(&canny); cvReleaseImage(&mask); cvReleaseMemStorage(&storage); cvDestroyAllWindows(); return 0; } Извиняюсь, что такая куча сложностей с переписыванием на разные языки. Чтобы разбираться и в случае чего опытные люди могли помочь, пишу на Cи, а в дальнейшем переписываю на C#, всвязи с требованием проекта...
  3. Работа с контурами

    Спасибо Вам большое! Аппроксимация помогла в какой-то степени, но желаемого результата удалось добиться лишь "размыв" изображение после детектора границ Канни)). Теперь у меня вопрос по ContourArea().. функция ContourArea() показывает, что площадь контуров равна -4. Я получил абсолютное значение и когда хочу отсеять мелкие контуры - у меня он или рисует все контуры, либо не рисует ничего.. Все контуры рисуются, когда ContourArea = 4. И не рисуются ни маленькие, ни большие при любых других значениях, независимо от того больше четырёх, либо меньше. Не могли бы Вы подсказать, что можно сделать в данной ситуации?
  4. Работа с контурами

    Сделал попытку аппроксимации,но программка крашится на данной строке // хранилище памяти CvMemStorage* storage = cvCreateMemStorage(0); CvSeq* contours = 0; //Поиск контура cvFindContours(cont,storage,&contours,sizeof(CvContour),CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0)); cvApproxPoly(contours,sizeof(CvContour),storage,CV_POLY_APPROX_DP,0.1,0); // рисуем найденный контур НА маске и заливаем его белым cvDrawContours(mask,contours, CV_RGB(255,255,255),CV_RGB(255,255,255), 0, CV_FILLED, CV_AA, cvPoint(0,0)); Скорее всего я просто не до конца понял, как правильно использовать данную функцию, пока пытаюсь найти примеры к ней.. А ругается дебаггер следующим образом: fatal error C1099: Edit and Continue engine terminating compile И в консоль выбрасывает:
  5. Работа с контурами

    Конечно...на mask у меня выводится это: Как видите...выводит он совсем не то, что бы мне хотелось, к сожалению...
  6. Работа с контурами

    Добрый день! Изучаю OpenCV очень недавно, но требуется решить задачу распознавания знаков ограничения скорости. Решил попробовать вариант сравнения с шаблоном, но у меня возникает проблема: сначала я использую детектор границ Canny и он довольно хорошо находит нужные мне окружности(рамка знака ограничения скорости). Но когда я по примеру для похожей задачи хочу выделить контуры и залить их белым(для маски, чтобы в последующем сравнить её с исходным изображением), контурами рамка обводится плохо и нет возможности сделать из неё маску. Подскажите, пожалуйста, что можно сделать в данной ситуации? И как можно было бы очистить изображение от мелких объектов? Идея такая - исходное изображение я конвертирую в HSV палитру и разбиваю на отдельные каналы. Для каждого канала есть свои ползунки, чтобы подобрать оптимальное значение( экспериментально и через статьи в интернете оптимальными явились Hue [170,255], Sat[100,255], Val[100,255]). Это параметры для красного цвета, чтобы в последующем выделить рамку знака. #include "stdafx.h" #include <stdio.h> #include <stdlib.h> #include <cv.h> #include <highgui.h> #include <cxcore.h> IplImage* image = 0; IplImage* dst = 0; // для хранения каналов HSV IplImage* hsv = 0; IplImage* h_plane = 0; IplImage* s_plane = 0; IplImage* v_plane = 0; // для хранения каналов HSV после преобразования IplImage* h_range = 0; IplImage* s_range = 0; IplImage* v_range = 0; // для хранения суммарной картинки IplImage* hsv_and = 0; //Для хранения контуров IplImage* contoured=0; //Маска IplImage* mask=0; //Между кенни и контуром IplImage* cont=0; int Hmin = 0; int Hmax = 256; int Smin = 0; int Smax = 256; int Vmin = 0; int Vmax = 256; int HSVmax = 256; // // функции-обработчики ползунков // void myTrackbarHmin(int pos) { Hmin = pos; cvInRangeS(h_plane, cvScalar(Hmin), cvScalar(Hmax), h_range); } void myTrackbarHmax(int pos) { Hmax = pos; cvInRangeS(h_plane, cvScalar(Hmin), cvScalar(Hmax), h_range); } void myTrackbarSmin(int pos) { Smin = pos; cvInRangeS(s_plane, cvScalar(Smin), cvScalar(Smax), s_range); } void myTrackbarSmax(int pos) { Smax = pos; cvInRangeS(s_plane, cvScalar(Smin), cvScalar(Smax), s_range); } void myTrackbarVmin(int pos) { Vmin = pos; cvInRangeS(v_plane, cvScalar(Vmin), cvScalar(Vmax), v_range); } void myTrackbarVmax(int pos) { Vmax = pos; cvInRangeS(v_plane, cvScalar(Vmin), cvScalar(Vmax), v_range); } int main(int argc, char* argv[]) { image=cvLoadImage("D:\\1.jpg",1); //Создание картинок hsv=cvCreateImage(cvGetSize(image),IPL_DEPTH_8U,3); h_plane = cvCreateImage(cvGetSize(image),IPL_DEPTH_8U,1); s_plane = cvCreateImage(cvGetSize(image),IPL_DEPTH_8U,1); v_plane = cvCreateImage(cvGetSize(image),IPL_DEPTH_8U,1); h_range = cvCreateImage(cvGetSize(image),IPL_DEPTH_8U,1); s_range = cvCreateImage(cvGetSize(image),IPL_DEPTH_8U,1); v_range = cvCreateImage(cvGetSize(image),IPL_DEPTH_8U,1); hsv_and = cvCreateImage(cvGetSize(image),IPL_DEPTH_8U,1); contoured=cvCreateImage(cvGetSize(image),IPL_DEPTH_8U,1); mask=cvCreateImage(cvGetSize(image),IPL_DEPTH_8U,1); cont=cvCreateImage(cvGetSize(image),IPL_DEPTH_8U,1); //Создание маски, заливка изображения чёрным cvSet(mask,cvScalar(0,0,0)); //Конвертируем в HSV cvCvtColor(image,hsv,CV_BGR2HSV); //Разбиваем на отдельные каналы cvCvtPixToPlane(hsv, h_plane,s_plane,v_plane,0); //определим max и min значение HSV каналов double framemin=0; double framemax=0; cvMinMaxLoc(h_plane,&framemin,&framemax); printf("[H] %f x %f\n",framemin,framemax); Hmin=framemin; Hmax=framemax; cvMinMaxLoc(s_plane,&framemin,&framemax); printf(" %f x %f\n",framemin,framemax); Smin=framemin; Smax=framemax; cvMinMaxLoc(v_plane,&framemin,&framemax); printf("[V] %f x %f\n",framemin,framemax); Vmin=framemin; Vmax=framemax; //Отображение изображений cvNamedWindow("original",CV_WINDOW_AUTOSIZE); cvNamedWindow("H range",CV_WINDOW_AUTOSIZE); cvNamedWindow("S range",CV_WINDOW_AUTOSIZE); cvNamedWindow("V range",CV_WINDOW_AUTOSIZE); cvNamedWindow("Contoured",CV_WINDOW_AUTOSIZE); cvNamedWindow("Mask",CV_WINDOW_AUTOSIZE); cvNamedWindow("Canny",CV_WINDOW_AUTOSIZE); cvCreateTrackbar("Hmin","H range", &Hmin, HSVmax, myTrackbarHmin); cvCreateTrackbar("Hmax","H range", &Hmax, HSVmax,myTrackbarHmax); cvCreateTrackbar("Smin","S range",&Smin,HSVmax,myTrackbarSmin); cvCreateTrackbar("Smax","S range",&Smax,HSVmax,myTrackbarSmax); cvCreateTrackbar("Vmin","V range",&Vmin,HSVmax,myTrackbarVmin); cvCreateTrackbar("Vmax","V range",&Vmax,HSVmax,myTrackbarVmax); while(1){ //отображаем изображение cvShowImage("original",image); cvShowImage("H range",h_range); cvShowImage("S range",s_range); cvShowImage("V range",v_range); //складываем cvAnd(h_range,s_range,hsv_and); cvAnd(hsv_and,v_range,hsv_and); //Выделение контура cvCanny(hsv_and,cont,50,255,5); // хранилище памяти CvMemStorage* storage = cvCreateMemStorage(0); CvSeq* contours = 0; //Поиск контура cvFindContours(cont,storage,&contours,sizeof(CvContour),CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0)); // рисуем найденный контур НА маске и заливаем его белым cvDrawContours(mask,contours, CV_RGB(255,255,255),CV_RGB(255,255,255), 0, CV_FILLED, CV_AA, cvPoint(0,0)); cvShowImage("Canny",cont); cvShowImage("Contoured", hsv_and); cvShowImage("Mask", mask); char c=cvWaitKey(33); if (c==27){ break; } } // освобождаем ресурсы cvReleaseImage(&image); cvReleaseImage(&hsv); cvReleaseImage(&h_range); cvReleaseImage(&s_range); cvReleaseImage(&v_range); cvReleaseImage(&hsv_and); cvReleaseImage(&contoured); cvReleaseImage(&mask); cvReleaseImage(&cont); // удаляем окна cvDestroyAllWindows(); return 0; } Скриншоты исходного изображения, изображения после поиска границ Кенни и контура прилагаются. 1. Исходное 2. Детектор границ Кенни 3. Поиск контура Буду премного благодарен Вам всем за помощь!
×