如何使用javacv识别具有可变长度和宽度的正方形或矩形?

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

请有人帮忙完成这个任务


Dave:请问您能提供一些实现此目标的指导吗? - user1465195
2
这是“squire”还是“SQUARE”?如果不是,那么“squire”是什么意思呢?谷歌说它是士兵的盔甲。这是你想要的吗?最好添加一张图片。 - Abid Rahman K
哦,我刚看到那个错误,我真的需要在图像上识别矩形和正方形。非常非常抱歉我之前犯的错误。现在我已经更正了问题。 - user1465195
1个回答

10

因此它被固定为正方形。

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

C++ 代码Python 代码

我将简要说明如何运作:

1-首先,您需要将图像分为R,G,B平面。

2-然后,对每个平面执行边缘检测,并添加不同阈值(例如50,100等)进行阈值处理

3-在所有尺寸的图像中,找到轮廓(请记住,它正在处理大量图像,如果您不想,请删除某些阈值),

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

5-然后,逼近轮廓。 (更多关于轮廓逼近的资料).

6-对于矩形,将会给出四个角落。对于其他图形,将给出相应的角落。

因此,将这些轮廓根据逼近后的元素数量进行过滤,该数量应为四,即角落数量。矩形的第一个特性。

7-接下来,可能存在一些具有四个角但不是矩形的形状。因此,我们采用矩形的第二个特征,即所有内角都为90度。因此,我们使用下面的关系找到所有角的角度:

enter image description here

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

8- 那么正方形怎么办?利用其属性,即所有边的长度相等。

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

这就是代码的工作原理。

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

enter image description here

编辑:

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

enter image description here

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


你好,请问能否解释一下如何使用上述代码来识别正方形?因为它也会将所有的矩形都识别出来,能否请您解释一下这个问题? - Gum Slashy
嗨,我在我的答案中已经解释过了。请查看第8点。找到所有点之间的距离,并检查它们是否几乎相等。 - Abid Rahman K
@AbidRahmanK // 很遗憾,上面的两个链接(C++和Python代码)无法访问或已损坏。您能否在Gist或这里发布代码? - Youngjae
@AbidRahmanK // 感谢您的迅速反馈! :) 你让我的一天变得美好。 - Youngjae
Python链接似乎已经失效:这个应该有效:https://github.com/opencv/opencv/blob/master/samples/python/squares.py - Elias
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接