Как я могу выполнить процесс сопоставления шаблонов в SUB-IMAGE, извлеченном из ORIGINAL-IMAGE, и отобразить результаты в исходном изображении

Целый день я много пытался получить все связанные совпадения (с функцией matchtemplate) в подизображении, которое является ROI, которое я уже извлек из исходного изображения с помощью функции mousecallback. Так что мой код ниже для функции соответствия

 ////Matching Function
void CTemplate_MatchDlg::OnBnTemplatematch()
{

namedWindow("reference",CV_WINDOW_AUTOSIZE);
while(true)
{

Mat ref = imread("img.jpg");                    //  Original Image
mod_ref = cvCreateMat(ref.rows,ref.cols,CV_32F);// resizing the image to fit in picture box
resize(ref,mod_ref,Size(),0.5,0.5,CV_INTER_AREA);

Mat tpl =imread("Template.jpg"); // TEMPLATE IMAGE

cvSetMouseCallback("reference",find_mouseHandler,0);

Mat aim=roiImg1.clone(); // SUB_IMAGE FROM ORIGINALIMAGE
// aim variable contains the ROI matrix
// next, want to perform template matching in that ROI                                                //                                     and display results on original imageif(select_flag1 == 1)
{

// imshow("ref",aim);

Mat res(aim.rows-tpl.rows+1, aim.cols-tpl.cols+1,CV_32FC1);
matchTemplate(aim, tpl, res, CV_TM_CCOEFF_NORMED);
threshold(res, res, 0.8, 1., CV_THRESH_TOZERO);

while (1)
{
double minval, maxval, threshold = 0.8;
Point minloc, maxloc;
minMaxLoc(res, &minval, &maxval, &minloc, &maxloc);

//// Draw Bound boxes for detected templates in sub matrix

if (maxval >= threshold)
{
rectangle(
aim,
maxloc,
Point(maxloc.x + tpl.cols, maxloc.y + tpl.rows),
CV_RGB(0,255,0), 1,8,0
);
floodFill(res, maxloc, cv::Scalar(0), 0, cv::Scalar(.1), cv::Scalar(1.));
}else
break;
}
}
////Bounding box for ROI  selection with mouse

rectangle(mod_ref, rect2, CV_RGB(255, 0, 0), 1, 8, 0);  // rect2 is ROI
// my idea is to get all the matches in ROI with bounding boxes
// no need to mark any matches outside the ROI
//Clearly i want to process only ROI

imshow("reference", mod_ref); // show the image with the results
waitKey(10);
}
//cvReleaseMat(&mod_ref);
destroyWindow("reference");}

/// ImplementMouse Call Back

void find_mouseHandler(int event, int x, int y, int flags, void* param)

{
if (event == CV_EVENT_LBUTTONDOWN && !drag)
{
/* left button clicked. ROI selection begins*/
point1 = Point(x, y);
drag = 1;

}

if (event == CV_EVENT_MOUSEMOVE && drag)
{
/* mouse dragged. ROI being selected*/
Mat img3 = mod_ref.clone();
point2 = Point(x, y);
rectangle(img3, point1, point2, CV_RGB(255, 0, 0), 1, 8, 0);
imshow("reference", img3);

//
}

if (event == CV_EVENT_LBUTTONUP && drag)
{

Mat img4=mod_ref.clone();
point2 = Point(x, y);
rect1 = Rect(point1.x,point1.y,x-point1.x,y-point1.y);
drag = 0;
roiImg1 = mod_ref(rect1);  //SUB_IMAGE MATRIX
imshow("reference", img4);
}

if (event == CV_EVENT_LBUTTONUP)
{
/* ROI selected */
select_flag1 = 1;
drag = 0;
}
}

Процесс сборки и отладки успешно завершен. Но когда я нажимаю кнопку Match в диалоговом окне, я получаю сообщение об ошибке:

Unhandled exception at 0x74bf812f in Match.exe: Microsoft C++ exception: cv::Exception at memory location 0x001ae150..

Поэтому моя идея состоит в том, чтобы получить все совпадения в подизображении при сравнении с ОБРАЗОМ ШАБЛОНА и показать конечный результат (совпадения с ограничивающими рамками) в самом ОРИГИНАЛЬНОМ ИЗОБРАЖЕНИИ.

Кто-нибудь, помогите мне в этом отношении! Помощь будет принята с благодарностью!

5

Решение

Мой код ниже модификация из оригинальный учебник предоставлено OpenCV.

Это загружает изображение из командной строки и отображает его на экране, чтобы пользователь может нарисовать прямоугольник где-то выбрать субизображение, которое будет шаблоном. После того, как эта операция сделана, изображение будет внутри зеленый прямоугольник:

Нажмите любую кнопку позволить программе выполнить сопоставление с шаблоном. Новое окно под названием «Соответствие шаблона:«появляется отображение исходного изображения плюс синий прямоугольник это показывает согласованную область:

#include <cv.h>
#include <highgui.h>
#include <iostream>const char* ref_window = "Draw rectangle to select template";
std::vector<cv::Point> rect_points;void mouse_callback(int event, int x, int y, int flags, void* param)
{
if (!param)
return;

cv::Mat* ref_img = (cv::Mat*) param;

// Upon LMB click, store the X,Y coordinates to define a rectangle.
// Later this info is used to set a ROI in the reference image.
switch (event)
{
case CV_EVENT_LBUTTONDOWN:
{
if (rect_points.size() == 0)
rect_points.push_back(cv::Point(x, y));
}
break;

case CV_EVENT_LBUTTONUP:
{
if (rect_points.size() == 1)
rect_points.push_back(cv::Point(x, y));
}
break;

default:
break;
}

if (rect_points.size() == 2)
{
cv::rectangle(*ref_img,
rect_points[0],
rect_points[1],
cv::Scalar(0, 255, 0),
2);

cv::imshow(ref_window, *ref_img);
}
}

int main(int argc, char* argv[])
{
if (argc < 2)
{
std::cout << "Usage: " << argv[0] << " <image>" << std::endl;
return -1;
}

cv::Mat source = cv::imread(argv[1]);   // original image
if (source.empty())
{
std::cout << "!!! Failed to load source image." << std::endl;
return -1;
}

// For testing purposes, our template image will be a copy of the original.
// Later we will present it in a window to the user, and he will select a region
// as a template, and then we'll try to match that to the original image.

cv::Mat reference = source.clone();

cv::namedWindow(ref_window, CV_WINDOW_AUTOSIZE);
cv::setMouseCallback(ref_window, mouse_callback, (void*)&reference);

cv::imshow(ref_window, reference);
cv::waitKey(0);

if (rect_points.size() != 2)
{
std::cout << "!!! Oops! You forgot to draw a rectangle." << std::endl;
return -1;
}

// Create a cv::Rect with the dimensions of the selected area in the image
cv::Rect template_roi = cv::boundingRect(rect_points);

// Create THE TEMPLATE image using the ROI from the rectangle
cv::Mat template_img = cv::Mat(source, template_roi);

// Create the result matrix
int result_cols =  source.cols - template_img.cols + 1;
int result_rows = source.rows - template_img.rows + 1;
cv::Mat result;

// Do the matching and normalize
cv::matchTemplate(source, template_img, result, CV_TM_CCORR_NORMED);
cv::normalize(result, result, 0, 1, cv::NORM_MINMAX, -1, cv::Mat());

/// Localizing the best match with minMaxLoc
double min_val = 0, max_val = 0;
cv::Point min_loc, max_loc, match_loc;
int match_method = CV_TM_CCORR_NORMED;
cv::minMaxLoc(result, &min_val, &max_val, &min_loc, &max_loc, cv::Mat());

// When using CV_TM_CCORR_NORMED, max_loc holds the point with maximum
// correlation.
match_loc = max_loc;

// Draw a rectangle in the area that was matched
cv:rectangle(source,
match_loc,
cv::Point(match_loc.x + template_img.cols , match_loc.y + template_img.rows),
cv::Scalar(255, 0, 0), 2, 8, 0 );

imshow("Template Match:", source);
cv::waitKey(0);

return 0;
}
7

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]