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

Как программно определить что шаблон найден?

Recommended Posts

Всем доброго здравия

Написал процедуру поиска по шаблону в видео с камеры

Все работает, но есть проблема

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

 

 Как программно определиться, что шаблон найден?

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


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

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

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


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

Всем доброго здравия

Написал процедуру поиска по шаблону в видео с камеры

Все работает, но есть проблема

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

 

 Как программно определиться, что шаблон найден?

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

  • Like 1

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


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

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

Очень прошу, давайте перейдем с намеков на понятный многим язык С++

Я не теоретик, я практик

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


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

Очень прошу, давайте перейдем с намеков на понятный многим язык С++

Я не теоретик, я практик

 

Чтобы перейти на язык С++, неплохо бы Ваш код иметь перед глазами. Ну предположим, что используется функция из 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 (в зависимости от используемого критерия) с порогом. Если условие не выполняется, то искомого объекта на изображении нет, и рамку для указания его местоположения отрисовывать не следует.

  • Like 1

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


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

 

 

Чтобы перейти на язык С++, неплохо бы Ваш код иметь перед глазами. Ну предположим, что используется функция из 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 в консольное окно. При нахождении объекта выводятся стабильные значения. При отсутствии объекта значения выводятся то же, но значения колеблются

Самое противное что значения могут совпадать как при наличии объекта так и без него

 

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


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

Ок.  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. Если не выйдет, можно подумать над более сложным критерием. Например, можно анализировать выраженность пика. Т.е. смотреть отношение величины пика к среднему значению функции отклика в его окрестности. 

  • Like 1

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


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

Ок.  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

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


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

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

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

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

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

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

Войти

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

Войти сейчас


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

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

×