使用javacv中的匹配模板在图像中的特定区域中查找图像

时间:2014-01-22 20:12:27

标签: java opencv image-processing javacv template-matching

我试图在另一个特定区域内找到图像的位置。我正在使用javacv来解决这个问题。但是我的代码在执行 cvMatchTemplate 函数时出错。我想我错过了使用 cvSetImageROI

这就是我使用它的方式:

    public static void main(String c[]) {

    IplImage src = cvLoadImage("test.jpg", 0);
    IplImage tmp = cvLoadImage("tmp.png", 0);
    IplImage result = cvCreateImage(cvSize(src.width() - tmp.width() + 1, src.height() - tmp.height() + 1),
                           IPL_DEPTH_32F,1);
    cvZero(result);

    cvSetImageROI(src, new CvRect(22, 50, 30, 30));
    cvSetImageROI(result, new CvRect(22, 50, 30, 30));

    //Match Template Function from OpenCV
    cvMatchTemplate(src, tmp, result, CV_TM_CCORR_NORMED);

    double[] min_val = new double[2];
    double[] max_val = new double[2];
    CvPoint minLoc = new CvPoint();
    CvPoint maxLoc = new CvPoint();

    cvMinMaxLoc(result, min_val, max_val, minLoc, maxLoc,
            null);
    CvPoint point = new CvPoint();
    point.x(maxLoc.x() + tmp.width());
    point.y(maxLoc.y() + tmp.height());
    cvRectangle(src, maxLoc, point, CvScalar.RED, 2, 8, 0);
    cvShowImage("Lena Image", src);
    cvWaitKey(0);
    cvReleaseImage(src);
    cvReleaseImage(tmp);
    cvReleaseImage(result);
}

这是错误:

    OpenCV Error: Assertion failed (result.size() == cv::Size(std::abs(img.cols - templ.cols) 
    + 1,std::abs(img.rows - templ.rows) + 1) && result.type() == CV_32F) in unknown function,
    file ..\..\..\src\opencv\modules\imgproc\src\templmatch.cpp, line 384

任何帮助?

2 个答案:

答案 0 :(得分:1)

嘿,看到我用Javacv做的这个例子

public class Test {
static Image image;

public static void main(String[] args) throws Exception {
    int width = Integer.parseInt(args[3]);
    int height = Integer.parseInt(args[4]);

    IplImage src = cvLoadImage(
            args[0], 0);
    IplImage tmp = cvLoadImage(
            args[1], 0);

    IplImage result = cvCreateImage(
            cvSize(src.width() - tmp.width() + 1,
                    src.height() - tmp.height() + 1), IPL_DEPTH_32F, src.nChannels());

    cvZero(result);

    // Match Template Function from OpenCV
    cvMatchTemplate(src, tmp, result, CV_TM_CCORR_NORMED);

    // double[] min_val = new double[2];
    // double[] max_val = new double[2];
    DoublePointer min_val = new DoublePointer();
    DoublePointer max_val = new DoublePointer();

    CvPoint minLoc = new CvPoint();
    CvPoint maxLoc = new CvPoint();

    cvMinMaxLoc(result, min_val, max_val, minLoc, maxLoc, null);

    // Get the Max or Min Correlation Value
    // System.out.println(Arrays.toString(min_val));
    // System.out.println(Arrays.toString(max_val));

    CvPoint point = new CvPoint();
    point.x(maxLoc.x() + tmp.width());
    point.y(maxLoc.y() + tmp.height());
    // cvMinMaxLoc(src, min_val, max_val,0,0,result);

    cvRectangle(src, maxLoc, point, CvScalar.RED, 2, 8, 0);// Draw a
                                                            // Rectangle for
                                                            // Matched
                                                            // Region
    CvRect rect = new CvRect();
    rect.x(maxLoc.x());
    rect.y(maxLoc.y());
    rect.width(tmp.width() + width);
    rect.height(tmp.width() + height);
    cvSetImageROI(src, rect);
    IplImage imageNew = cvCreateImage(cvGetSize(src), src.depth(),
            src.nChannels());
    cvCopy(src, imageNew);
    cvSaveImage(args[2], imageNew);

    cvShowImage("Lena Image", src);
    cvWaitKey(0);
    cvReleaseImage(src);
    cvReleaseImage(tmp);
    cvReleaseImage(result);

}

完整参考here 我们需要4个默认参数 " C:\用户\ Waldema \桌面\ bg.jpg" " C:\用户\ Waldema \桌面\ logosiemens.jpg" " C:\用户\ Waldema \桌面\ imageToFind.jpg" 100 200

可在通用IDE的运行配置中进行配置。 我认为这会有所帮助

答案 1 :(得分:0)

我发现在设置结果图像的roi时遇到了问题,这是错误的行:

   cvSetImageROI(result, new CvRect(22, 50, 30, 30));

应该是这样的:

   cvSetImageROI(result, new CvRect(22, 50, 30 - tmp.width() + 1, 30 - tmp.height() + 1));

我不确定为什么,但我认为这是因为 cvMatchTemplate 函数将结果维度等于源维度减去模板尺寸加上一个像素。