2013-03-19 4 views
4

Один целый день я пробовал много, чтобы получить все связанные совпадения (с функцией matchtemplate) в суб-изображении, который является ROI, я уже извлек из исходного изображения функцию mousecallback. Поэтому мой код ниже для MatchingfunctionКак я могу выполнить процесс сопоставления шаблонов в SUB-IMAGE, извлеченном из ORIGINAL-IMAGE, и отобразить результаты в оригинальном изображении

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

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

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

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

Помогите мне в этом отношении !! Помощь будет оценена очень!

ответ

7

Мой код ниже является модификация из original tutorial Предоставляемые OpenCV.

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

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

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

Спасибо, но я получаю ниже ошибки, ошибки C2664 : 'cv :: boundingRect': невозможно преобразовать параметр 1 из 'std :: vector <_Ty>' to 'const cv :: Mat &' 1> с 1> [ 1> _Ty = cv :: Point 1>] 1> Причина: не может конвертировать из 'std :: vec тор <_Ty> 'до 'сопзЬ сорта :: Mat' 1> с 1> [ 1> _Ty = резюме :: Точка ->] 1> Нет оператор определенного пользователя преобразования доступно, который может выполнить это преобразование, или оператор не может быть вызван. – Sharath

+0

А также, я хочу сказать, что я хочу сделать: Предоставить пользователю возможность выбрать ROI для использования в качестве изображения шаблона (уже сделано). Опять пользователь будет выбирать ROI на другом изображении (скажем, например, исходное изображение1 с тремя лицами, такими же, как исходное изображение, с которым вы работаете с одним лицом), нам нужно обрабатывать только эту часть (ROI) для соответствия вхождениях (если ROI имеет только два лица, то шаблон будет совпадать с двумя лицами, а не с третьим из ROI). Не заботьтесь о регионе от ROI. И покажите результаты (все соответствующие вхождения в ROI) в исходном изображении. Спасибо. Помощь будет оценена очень! – Sharath

+0

Произошла ли эта ошибка при компиляции моего кода? Он успешно скомпилирован с OpenCV 2.4.3 и 2.4.4, поэтому обновление вашей OpenCV до более новой версии должно устранить проблему. – karlphillip

 Смежные вопросы

  • Нет связанных вопросов^_^