Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
271 views
in Technique[技术] by (71.8m points)

java - How to identify square or rectangle with variable lengths and width by using 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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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

enter image description here

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 :

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:

enter image description here

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...