9

我正在使用java开发项目来识别使用opencv包的组件,但我是javacv的新手,我只想知道如何识别特定源图像中的矩形请一些有经验的人提供一些基本指南来存档这个任务。我尝试在这里使用模板匹配,但它只能识别精确大小的矩形。但在我的情况下,我需要识别可变长度矩形?

import java.util.Arrays;
import static com.googlecode.javacv.cpp.opencv_core.*;
import static com.googlecode.javacv.cpp.opencv_imgproc.*;
import static com.googlecode.javacv.cpp.opencv_highgui.*;
public class TestingTemplate {
public static void main(String[] args) {
//Original Image
IplImage src = cvLoadImage("src\\lena.jpg",0);
//Template Image
IplImage tmp = cvLoadImage("src\\those_eyes.jpg",0);
//The Correlation Image Result
IplImage result = cvCreateImage(cvSize(src.width()-tmp.width()+1, src.height()-tmp.height()+1), IPL_DEPTH_32F, 1);
//Init our new Image
cvZero(result);
cvMatchTemplate(src, tmp, result, CV_TM_CCORR_NORMED);

double[] min_val = new double[2];
double[] max_val = new double[2];

//Where are located our max and min correlation points
CvPoint minLoc = new CvPoint();
CvPoint maxLoc = new CvPoint();
cvMinMaxLoc(result, min_val, max_val, minLoc, maxLoc, null); //the las null it's for
 optional mask mat()

System.out.println(Arrays.toString(min_val)); //Min Score
System.out.println(Arrays.toString(max_val)); //Max Score

CvPoint point = new CvPoint();
point.x(maxLoc.x()+tmp.width());
point.y(maxLoc.y()+tmp.height());
cvRectangle(src, maxLoc, point, CvScalar.WHITE, 2, 8, 0); //Draw the rectangule result in original img.
cvShowImage("Lena Image", src);
cvWaitKey(0);
//Release
cvReleaseImage(src);
cvReleaseImage(tmp);
cvReleaseImage(result);
}
}

请有人帮助完成此任务

4

1 回答 1

10

(所以它固定为正方形。)

对于正方形检测,OpenCV 提供了一些示例。代码采用 C++、C、Python。希望您可以将其移植到 JavaCV。

C++ 代码Python 代码

我将仅说明它是如何工作的:

1 - 首先将图像拆分为 R、G、B 平面。

2 - 然后为每个平面执行边缘检测,除此之外,不同值的值,如 50、100、...等。

3 - 在所有这些二进制图像中,找到轮廓(记住它正在处理很多图像,所以可能有点慢,如果你不想要,你可以删除一些阈值)。

4 - 找到轮廓后,通过根据区域过滤去除一些不需要的小噪声。

5 - 然后,近似轮廓。(更多关于轮廓近似)。

6 - 对于一个矩形,它会给你四个角。对于其他人,将给出相应的角。

因此,根据近似轮廓中的元素数量(应该是四个)过滤这些轮廓,这与角的数量相同。矩形的第一个属性。

7 - 接下来,可能有一些具有四个角但不是矩形的形状。所以我们取矩形的第二个属性,即所有内角都是 90。所以我们使用下面的关系找到所有角落的角度:

在此处输入图像描述

如果 cos (theta) < 0.1,即 theta > 84 度,则为矩形。

8 - 那么广场呢?使用它的属性,即所有边都相等。

您可以通过如上所示的关系找到两点之间的距离。检查它们是否都相等,则该矩形是正方形。

这就是代码的工作方式。

下面是我在图像上应用上述代码的输出:

在此处输入图像描述

编辑 :

有人询问如何删除在边界检测到的矩形。这是因为,opencv 在黑色背景中找到白色对象,边框也是如此。只需使用 cv2.bitwise_not() 函数反转图像即可解决问题。我们得到如下结果:

在此处输入图像描述

您可以在此处找到有关轮廓的更多信息:轮廓 - 1:入门

于 2012-06-19T15:15:49.050 回答