如何使用javacv识别长度和宽度可变的方形或矩形? [英] How to identify square or rectangle with variable lengths and width by using javacv?

查看:475
本文介绍了如何使用javacv识别长度和宽度可变的方形或矩形?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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){
//原始图片
IplImage src = cvLoadImage(src\\ lena.jpg ,0);
//模板图片
IplImage tmp = cvLoadImage(src\\those_eyes.jpg,0);
//相关图像结果
IplImage结果= cvCreateImage(cvSize(src.width() - tmp.width()+ 1,src.height() - tmp.height()+ 1), IPL_DEPTH_32F,1);
//初始化我们的新图片
cvZero(结果);
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); // las las它是
可选掩码mat()

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());
cvRectangle(src,maxLoc,point,CvScalar.WHITE,2,8,8); //在原始img中绘制rectangule结果。
cvShowImage(Lena Image,src);
cvWaitKey(0);
//发布
cvReleaseImage(src);
cvReleaseImage(tmp);
cvReleaseImage(result);
}
}

请一位有人帮助完成此任务

解决方案

(因此它被固定为方形。)



对于方形检测, OpenCV为此提供了一些示例。代码使用C ++,C,Python。希望你能把它移植到JavaCV。




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 ?

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

解决方案

(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.

C++ code , Python Code.

I will just illustrate how it works:

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

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

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).

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

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

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

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 :

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

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

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 :

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:

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

这篇关于如何使用javacv识别长度和宽度可变的方形或矩形?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆