c++ c opencv image-processing template-matching

c++ - ¿Cómo puedo realizar el proceso de coincidencia de plantilla en SUB-IMAGE extraído de ORIGINAL-IMAGE y visualizar los resultados en la imagen original



opencv image-processing (1)

Un día entero he intentado mucho para obtener todas las coincidencias relacionadas (con la función matchtemplate) en sub-Imagen, que es ROI que ya he extraído de la imagen original con la función de devolución de mouse. Entonces mi código está debajo para la función Matching

////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 image if(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; } }

proceso de compilación y depuración realizado con éxito. Pero, cuando hago clic en el botón Coincidir en el cuadro de diálogo, aparece el error:

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

Entonces, mi idea es obtener todas las coincidencias en la Sub-imagen cuando las comparo con la IMAGEN DE PLANTILLA y mostrar el resultado final (coincide con recuadros delimitadores) en la IMAGEN ORIGINAL misma.

¡Alguien me ayude en este sentido! ¡La ayuda sería apreciada enormemente!


Mi código a continuación es una modificación del tutorial original proporcionado por OpenCV.

Carga una imagen desde la línea de comandos y la muestra en la pantalla para que el usuario pueda dibujar un rectángulo en algún lugar para seleccionar la subimagen que será la plantilla. Después de que la operación finalice, la subimagen estará dentro de un rectángulo verde :

Presione cualquier tecla para permitir que el programa realice la coincidencia de plantilla. Aparece una nueva ventana titulada " Concordancia de plantilla: " que muestra la imagen original más un rectángulo azul que muestra el área combinada:

#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; }