Goldz 0 Жалоба Опубликовано April 11, 2015 Всем доброго здравия Написал процедуру поиска по шаблону в видео с камеры Все работает, но есть проблема При нахождении шаблона на изображении он выделяется красным прямоугольником, а если шаблона нет то прямоугольник все равно есть и хаотично передвигается по экрану Как программно определиться, что шаблон найден? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Nagdiel 2 Жалоба Опубликовано April 11, 2015 Как вариант, можно смотреть значение функции сходства, которая используется для поиска шаблона, и сравнивать его с порогом. Если значение меньше заданного порога, то объект не найден. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
iskees 32 Жалоба Опубликовано April 11, 2015 Всем доброго здравия Написал процедуру поиска по шаблону в видео с камеры Все работает, но есть проблема При нахождении шаблона на изображении он выделяется красным прямоугольником, а если шаблона нет то прямоугольник все равно есть и хаотично передвигается по экрану Как программно определиться, что шаблон найден? Вы бы хоть написали как вы этот поиск шаблона производите, какой функцией и т.п. Ну как выше сказано отсекать можно по значению функции отклика. 1 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Goldz 0 Жалоба Опубликовано April 11, 2015 Вы бы хоть написали как вы этот поиск шаблона производите, какой функцией и т.п. Ну как выше сказано отсекать можно по значению функции отклика. Очень прошу, давайте перейдем с намеков на понятный многим язык С++ Я не теоретик, я практик Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Nagdiel 2 Жалоба Опубликовано April 11, 2015 Очень прошу, давайте перейдем с намеков на понятный многим язык С++ Я не теоретик, я практик Чтобы перейти на язык С++, неплохо бы Ваш код иметь перед глазами. Ну предположим, что используется функция из OpenCV: matchTemplate( img, templ, result, match_method ); На входе текущее изображение img, и отыскиваемый шаблон templ. Результат - изображение result, каждый пиксель которого представляет собой меру сходства изображения и шаблона в соответствующей позиции с точки зрения выбранного критерия match_method. Чтобы определить точку наилучшего соответствия необходимо в зависимости от выбранного критерия найти глобальный минимум или максимум: double minVal; double maxVal; Point minLoc; Point maxLoc; minMaxLoc( result, &minVal, &maxVal, &minLoc, &maxLoc, Mat() ); Теперь, чтобы понять, есть шаблон на изображении или нет, необходимо проанализировать величину отклика. Т.е. сравнить minVal или maxVal (в зависимости от используемого критерия) с порогом. Если условие не выполняется, то искомого объекта на изображении нет, и рамку для указания его местоположения отрисовывать не следует. 1 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Goldz 0 Жалоба Опубликовано April 12, 2015 Чтобы перейти на язык С++, неплохо бы Ваш код иметь перед глазами. Ну предположим, что используется функция из OpenCV: #include <opencv\cv.h> #include <opencv\highgui.h> #include <stdlib.h> #include <stdio.h> using namespace cv; IplImage* image = 0; IplImage* templ = 0; CvRect rect; int main(int argc, char* argv[]) { CvCapture* capture = cvCreateCameraCapture(CV_CAP_ANY); assert( capture ); //cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 320);//1280); // cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 240);//960); IplImage* image=0, *res=0; // шаблон char* filename2 = argc >= 3 ? argv[2] : "D:/OpenCV/Image1.jpg"; templ = cvLoadImage(filename2,1); assert( templ != 0 ); cvNamedWindow("Match", CV_WINDOW_AUTOSIZE); // размер шаблона int width = templ->width; int height = templ->height; while(1) { image = cvQueryFrame( capture );// получаем кадр cvFlip(image, image, 0);//отображаем зеркально cvFlip(image, image, 1);//отображаем зеркально //ROI CvRect rect = cvRect(0, 0, 120, 240); // Определение прямоугольника для ИОР cvSetImageROI(image, rect); // Установка ИОР IplImage *res = cvCreateImage( cvSize( (rect.width-templ->width+1), (rect.height-templ->height+1)), IPL_DEPTH_32F, 1 ); cvMatchTemplate(image, templ, res, CV_TM_SQDIFF_NORMED);// сравнение изображения с шаблоном // определение лучшее положение для сравнения // (поиск минимумов и максимумов на изображении) double minval, maxval, threshold = 0.8; CvPoint minloc, maxloc; cvMinMaxLoc(res, &minval, &maxval, &minloc, &maxloc, 0); // нормализуем cvNormalize(res,res,1,0,CV_MINMAX); printf("minloc= %d, maxloc= %d\n", minloc,maxloc ); // выделим область прямоугольником cvRectangle(image, cvPoint(minloc.x, minloc.y), cvPoint(minloc.x+templ->width-1, minloc.y+templ->height-1), CV_RGB(255, 0, 0), 1, 8); cvShowImage("Match", image); // ждём нажатия клавиши cvWaitKey(33); } // освобождаем ресурсы cvReleaseImage( &image ); cvReleaseImage( &templ ); cvReleaseImage( &res ); cvDestroyAllWindows(); return 0; } Вывожу значения minloc и maxloc в консольное окно. При нахождении объекта выводятся стабильные значения. При отсутствии объекта значения выводятся то же, но значения колеблются Самое противное что значения могут совпадать как при наличии объекта так и без него Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Nagdiel 2 Жалоба Опубликовано April 12, 2015 Ок. minVal соответствует значению функции сходства (нормированный квадрат разности) в точке наилучшего совмещения (minLoc). Для начала можно это значение сравнить с порогом: if (minVal < threshold) { cvRectangle(image, cvPoint(minloc.x, minloc.y), cvPoint(minloc.x+templ->width-1, minloc.y+templ->height-1), CV_RGB(255, 0, 0), 1, 8); } Попробуйте подобрать значение порога threshold. Если не выйдет, можно подумать над более сложным критерием. Например, можно анализировать выраженность пика. Т.е. смотреть отношение величины пика к среднему значению функции отклика в его окрестности. 1 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Goldz 0 Жалоба Опубликовано April 12, 2015 Ок. minVal соответствует значению функции сходства (нормированный квадрат разности) в точке наилучшего совмещения (minLoc). Для начала можно это значение сравнить с порогом: if (minVal < threshold) { cvRectangle(image, cvPoint(minloc.x, minloc.y), cvPoint(minloc.x+templ->width-1, minloc.y+templ->height-1), CV_RGB(255, 0, 0), 1, 8); } Попробуйте подобрать значение порога threshold. Если не выйдет, можно подумать над более сложным критерием. Например, можно анализировать выраженность пика. Т.е. смотреть отношение величины пика к среднему значению функции отклика в его окрестности. Спасибо за помощь Все заработало, значение 0.5 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах