使用金字塔快速模板匹配

时间:2015-03-22 15:48:20

标签: python c++ opencv

我正在尝试将以下C程序从Fast Template matching with image pyramids转换为python:

#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

/**
* Function to perform fast template matching with image pyramid
*/
void fastMatchTemplate(cv::Mat& srca,  // The reference image
                   cv::Mat& srcb,  // The template image
                   cv::Mat& dst,   // Template matching result
                   int maxlevel)   // Number of levels
  {
   std::vector<cv::Mat> refs, tpls, results;

// Build Gaussian pyramid
cv::buildPyramid(srca, refs, maxlevel);
cv::buildPyramid(srcb, tpls, maxlevel);

cv::Mat ref, tpl, res;

// Process each level
for (int level = maxlevel; level >= 0; level--)
{
    ref = refs[level];
    tpl = tpls[level];
    res = cv::Mat::zeros(ref.size() + cv::Size(1,1) - tpl.size(), CV_32FC1);

    if (level == maxlevel)
    {
        // On the smallest level, just perform regular template matching
        cv::matchTemplate(ref, tpl, res, CV_TM_CCORR_NORMED);
    }
    else
    {
        // On the next layers, template matching is performed on pre-defined 
        // ROI areas.  We define the ROI using the template matching result 
        // from the previous layer.

        cv::Mat mask;
        cv::pyrUp(results.back(), mask);

        cv::Mat mask8u;
        mask.convertTo(mask8u, CV_8U);

        // Find matches from previous layer
        std::vector<std::vector<cv::Point> > contours;
        cv::findContours(mask8u, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);

        // Use the contours to define region of interest and 
        // perform template matching on the areas
        for (int i = 0; i < contours.size(); i++)
        {
            cv::Rect r = cv::boundingRect(contours[i]);
            cv::matchTemplate(
                ref(r + (tpl.size() - cv::Size(1,1))), 
                tpl, 
                res(r), 
                CV_TM_CCORR_NORMED
            );
        }
    }

    // Only keep good matches
    cv::threshold(res, res, 0.94, 1., CV_THRESH_TOZERO);
    results.push_back(res);
}

res.copyTo(dst);
}

int main()
 {
cv::Mat ref = cv::imread("reference.png");
cv::Mat tpl = cv::imread("template.png");
if (ref.empty() || tpl.empty())
    return -1;

cv::Mat ref_gray, tpl_gray;
cv::cvtColor(ref, ref_gray, CV_BGR2GRAY);
cv::cvtColor(tpl, tpl_gray, CV_BGR2GRAY);

cv::Mat dst;
fastMatchTemplate(ref_gray, tpl_gray, dst, 2);

while (true)
{
    double minval, maxval;
    cv::Point minloc, maxloc;
    cv::minMaxLoc(dst, &minval, &maxval, &minloc, &maxloc);

    if (maxval >= 0.9)
    {
        cv::rectangle(
            ref, maxloc, 
            cv::Point(maxloc.x + tpl.cols, maxloc.y + tpl.rows), 
            CV_RGB(0,255,0), 2
        );
        cv::floodFill(
            dst, maxloc, 
            cv::Scalar(0), 0, 
            cv::Scalar(.1), 
            cv::Scalar(1.)
        );
    }
    else
        break;
}

cv::imshow("result", ref);
cv::waitKey();
return 0;
}

以下是我转换的python代码:

maxlevel=4
img2 = gauss_pyramids("Search_Image.png",maxlevel);
template = gauss_pyramids("Template_Image.png",maxlevel);

# Process each level
for level in xrange(maxlevel,0,-1):
   methods =['cv2.TM_CCOEFF_NORMED']
   #On the smallest level, just perform regular template matching
   if level==maxlevel :
      template=template[level].copy()
      c,w,h= template.shape[::-1]
      for meth in methods:
        img = img2[4].copy()
        method = eval(meth)
      img = img2[maxlevel].copy()
      res = cv2.matchTemplate(img,template,method)
      #min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
      #top_left = max_loc
      #bottom_right = (top_left[0] + w, top_left[1] + h)
      #cv2.rectangle(img,top_left, bottom_right, (255,0,255), 2)
      #cv2.imshow('gray',res)
      #cv2.imshow("image",img)
      #cv2.imshow("meth",meth)
      #cv2.waitKey()
   else:
      H=cv2.pyrUp(img2[level])
      I=cv2.pyrUp(template[level])


   #On the next layers, template matching is performed on pre-defined 
   #ROI areas.  We define the ROI using the template matching result 
   #from the previous layer.

我在行中感到困惑

  

cv :: pyrUp(results.back(),mask);

我没有得到这个'结果'和函数'back()'。还有如何将矩阵转换为数据类型'CV_8U'。 非常感谢任何帮助!

0 个答案:

没有答案