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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11093654/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 03:44:32  来源:igfitidea点击:

How to identify square or rectangle with variable lengths and width by using javacv?

javaimage-processingopencvjavacv

提问by Abid Rahman K

I'm developing project using java to identify components using opencv package but I'm new to javacv and I just want to know how to identify rectangles in a particular source image please can some experience person give some basic guide line to archive this task. I try to use template matching on here but it can identify exact size rectangle only. But In my case I need to identify variable length rectangle ?

我正在开发使用 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);
}
}

Please can some one help to accomplish this

请有人帮助完成此任务

回答by Abid Rahman K

(So it is fixed as square.)

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

For square detection, OpenCV comes with some samples for this. Codes are in C++, C, Python. Hope you can port this to JavaCV.

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

C++ code, Python Code.

C++ 代码Python 代码

I will just illustrate how it works:

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

1 - First you split the imageto R,G,B planes.

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

2 - Then for each plane perform edge detection, and in addition to that, thresholdfor different values like 50, 100, .... etc.

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

3 - And in all these binary images, find contours( remember it is processing a lot of images, so may be a little bit slow, if you don't want, you can remove some threshold values).

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

4 - After finding contours, remove some small unwanted noises by filtering according to area.

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

5 - Then, approximate the contour. (More about contour approximation).

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

6 - For a rectangle, it will give you the four corners. For others, corresponding corners will be given.

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

So filter these contours with respect to number of elements in approximated contour that should be four, which is same as number of corners. First property of rectangle.

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

7 - Next, there may be some shapes with four corners but not rectangles. So we take second property of rectangles, ie all inner angles are 90. So we find the angle at all the corners using the relation below :

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

enter image description here

在此处输入图片说明

And if cos (theta) < 0.1, ie theta > 84 degree, that is a rectangle.

如果 cos (theta) < 0.1,即 theta > 84 度,那就是一个矩形。

8 - Then what about the square? Use its property, that all the sides are equal.

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

You can find the distance between two points by the relation as shown above. Check if they all are equal, then that rectangle is a square.

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

This is how the code works.

这就是代码的工作原理。

Below is the output I got applying above mentioned code on an image :

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

enter image description here

在此处输入图片说明

EDIT :

编辑 :

It has been asked how to remove the rectangle detected at the border. It is because, opencv finds white objects in black background, so is border. Just inverting the image using cv2.bitwise_not() function will solve the problem. we get the result as below:

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

enter image description here

在此处输入图片说明

You can find more information about contour here : Contours - 1 : Getting Started

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