我正在使用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);
}
}
请有人帮助完成此事
答案 0 :(得分:9)
(因此它被固定为方形。)
对于方形检测,OpenCV附带了一些样本。代码使用C ++,C,Python。希望你能把它移植到JavaCV。
我将只说明它的工作原理:
1 - 首先,将图像分割为R,G,B平面。
2 - 然后对于每个平面执行边缘检测,除此之外,阈值用于不同的值,如50,100,......等。
3 - 在所有这些二进制图像中,找到轮廓(记住它正在处理大量图像,所以可能有点慢,如果你不想要,你可以删除一些阈值)。
4 - 找到轮廓后,通过根据区域过滤删除一些小的不需要的噪音。
5 - 然后,近似轮廓。 (More about contour approximation)。
6 - 对于一个矩形,它会给你四个角。对于其他人,将给出相应的角落。
然后根据近似轮廓中应为4的元素数量过滤这些轮廓,这与角数相同。 矩形的第一个属性。
7 - 接下来,可能有一些形状有四个角但不是矩形。所以我们采用矩形的第二个属性,即所有内角都是90 。因此,我们使用以下关系找到所有角落的角度:
如果cos(theta)< 0.1,即theta> 84度,这是一个矩形。
8 - 那广场怎么样? 使用其属性,所有方面都相同。
您可以通过上述关系找到两点之间的距离。检查它们是否相等,然后该矩形是正方形。
这就是代码的工作原理。
以下是我在图像上应用上述代码的输出:
编辑:
有人询问如何删除在边框处检测到的矩形。这是因为,opencv在黑色背景中找到白色物体,因此是边框。只需使用cv2.bitwise_not()函数反转图像就可以解决问题。我们得到如下结果:
您可以在此处找到有关轮廓的更多信息:Contours - 1 : Getting Started