9

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

Andrey Rubshtein
  • 20,795
  • 11
  • 69
  • 104
  • Dave: Please can you provide some guild line to archive this > –  Jun 19 '12 at 03:18
  • 2
    Is it squire or SQUARE ? if not, what is squire? google says it is armor of soldiers. Is that what you want? Better add an image. – Abid Rahman K Jun 19 '12 at 06:26
  • Ohh I just see that error I really need to identify rectangles and squares on the image. really really sorry about the mistake I had done. Now I had corrected the question. –  Jun 19 '12 at 11:50

1 Answers1

10

(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

Abid Rahman K
  • 51,886
  • 31
  • 146
  • 157
  • Can you please explain how can I get rectangles with less than specific width ? actually I need to remove that large rectangles that shows in image(borders). –  Jun 20 '12 at 12:01
  • That large rectangle border is detected because, opencv contours find white objects in black background. So make squares white, ie just invert the image. I have updated the answer. – Abid Rahman K Jun 20 '12 at 12:41
  • So can't I get the each and every rectangle separately ? If its able to do can you provide some code example for it. –  Jun 21 '12 at 01:29
  • Hay can you please explain how to identify squres using above code ? Because it gave all the rectangles as well please can you explain this? – Gum Slashy Jul 06 '12 at 04:55
  • Hi, I have explained it in my answer. Checkout the 8th point. Find distance between all the points and check if they are almost equal. – Abid Rahman K Jul 06 '12 at 04:59
  • @AbidRahmanK // Sadly the two links above (C++ and python code) was inaccessble or broken. Could you kindly post the code on Gist or here? – Youngjae May 20 '13 at 14:12
  • @AbidRahmanK // Thanks for the lightning feedback! :) You make my day. – Youngjae May 20 '13 at 14:59
  • Python Link seems to be broken: This one should work: https://github.com/opencv/opencv/blob/master/samples/python/squares.py – Elias Feb 16 '21 at 13:53