Currently I am developing image processing project and I'm using javacv to develop image processing components. I was able to extract some interesting parts of a image and now I need to read the x and y coordinates of those objects. This is the image that I haveextracted
And I need to identify those objects and draw square around those objects. I went through some tutorials and try to identify objects using following code.
IplImage img="sourceimage";
CvSize sz = cvSize(img.width(), img.height());
IplImage gry=cvCreateImage(sz, img.depth(), 1);
cvCvtColor(img, gry, CV_BGR2GRAY);
cvThreshold(gry, gry, 200, 250, CV_THRESH_BINARY);
CvMemStorage mem = CvMemStorage.create();
CvSeq contours = new CvSeq();
CvSeq ptr = new CvSeq();
cvFindContours(gry, mem, contours, Loader.sizeof(CvContour.class) , CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));
CvRect boundbox;
for (ptr = contours; ptr != null; ptr = ptr.h_next()) {
boundbox = cvBoundingRect(ptr, 0);
if(boundbox.height()>10||boundbox.height()>10){
cvRectangle( gry, cvPoint( boundbox.x(), boundbox.y() ), cvPoint( boundbox.x() + boundbox.width(), boundbox.y() + boundbox.height()),CvScalar.BLUE, 0, 0, 0 );
System.out.println(boundbox.x()+", "+boundbox.y());
}
}
cvShowImage("contures", gry);
cvWaitKey(0);
But it doesn't draw as rectangle around the objects. I would like to know whether I can use cvFindContours method to identify those objects ? Please can some one explain how to archive my objective using javacv/opencv?
Try to go through following code and it will give answer for your question.
IplImage img=cvLoadImage("pathtosourceimage");
CvSize cvSize = cvSize(img.width(), img.height());
IplImage gry=cvCreateImage(cvSize, img.depth(), 1);
cvCvtColor(img, gry, CV_BGR2GRAY);
cvThreshold(gry, gry, 200, 255, CV_THRESH_BINARY);
cvAdaptiveThreshold(gry, gry, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY_INV, 11, 5);
CvMemStorage storage = CvMemStorage.create();
CvSeq contours = new CvContour(null);
int noOfContors = cvFindContours(gry, storage, contours, Loader.sizeof(CvContour.class), CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE, new CvPoint(0,0));
CvSeq ptr = new CvSeq();
int count =1;
CvPoint p1 = new CvPoint(0,0),p2 = new CvPoint(0,0);
for (ptr = contours; ptr != null; ptr = ptr.h_next()) {
CvScalar color = CvScalar.BLUE;
CvRect sq = cvBoundingRect(ptr, 0);
System.out.println("Contour No ="+count);
System.out.println("X ="+ sq.x()+" Y="+ sq.y());
System.out.println("Height ="+sq.height()+" Width ="+sq.width());
System.out.println("");
p1.x(sq.x());
p2.x(sq.x()+sq.width());
p1.y(sq.y());
p2.y(sq.y()+sq.height());
cvRectangle(img, p1,p2, CV_RGB(255, 0, 0), 2, 8, 0);
cvDrawContours(img, ptr, color, CV_RGB(0,0,0), -1, CV_FILLED, 8, cvPoint(0,0));
count++;
}
cvShowImage("contures",img);
cvWaitKey(0);
This is the output that I got for your given image.
Did you know that findContours
function finds white contours on black background?
Just do bitwise_not
(or analogue in JavaCV) to your image and after this apply findContours
. This is actually fix to your problem.
No need for third party libraries! What you are looking for can be achieved in OpenCV using a technique known as bounding box:
The trick is to use cvFindContours()
to retrieve the contours and then cvApproxPoly()
to improve the result. Notice that you'll have to invert the colors of the input image using cvNot()
because cvFindContours()
search for white contours.
By the way cvMinEnclosingCircle()
returns the center of the circle as CvPoint2D32f
.
cvFindContours is the right solution to your problem.
And I have verified that it works on your images.
You have System.out.println inside, what's the output?
cvFindContours could be tricky to use, I have wrapped it into a more general C++ function. Also I use a class called vBlob to describe an object cvFindContours detects. From what I see from your java code, java version API is very similar to C/C++ version. So it won't be hard to rewrite it.
ps. Astor gave the right answer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With