目前我正在开发图像处理项目,我正在使用javacv开发图像处理组件。我能够提取图像的一些有趣部分,现在我需要读取这些对象的x和y坐标。 这是我提取的图像
我需要识别这些对象并围绕这些对象绘制正方形。我浏览了一些教程并尝试使用以下代码识别对象。
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);
但它并没有在对象周围画出矩形。我想知道我是否可以使用cvFindContours方法来识别这些对象?请问有人可以解释如何使用javacv / opencv归档我的目标吗?
答案 0 :(得分:11)
尝试通过以下代码,它将为您的问题提供答案。
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);
这是我为您的图像输出的。
答案 1 :(得分:4)
cvFindContours是您解决问题的正确方法 我已经确认它适用于您的图像
你的System.out.println里面有什么输出?
cvFindContours可能很难使用,我把它包装成more general C++ function。我还使用class called vBlob来描述cvFindContours检测到的对象。从我从java代码中看到的,java版本API与C / C ++版本非常相似。所以重写它并不难。
PS。阿斯特给出了正确答案。
答案 2 :(得分:4)
您是否知道findContours
函数在黑色背景上找到白色轮廓?
只需对您的图片执行bitwise_not
(或类似于JavaCV),然后应用findContours
。这实际上解决了你的问题。
答案 3 :(得分:4)
不需要第三方库!使用称为bounding box的技术可以在OpenCV中实现您的目标:
诀窍是使用cvFindContours()
检索轮廓,然后使用cvApproxPoly()
来改善结果。请注意,您必须使用cvNot()
反转输入图像的颜色,因为cvFindContours()
会搜索白色轮廓。
顺便说一句cvMinEnclosingCircle()
将圆圈的中心返回为CvPoint2D32f
。
答案 4 :(得分:2)
我使用的是c ++ api,但我认为在javacv中也应该有一些名为drawContours或cvDrawContours的函数,它使用了findContours的输出。