opencv / javacv:如何迭代轮廓进行形状识别?

编程入门 行业动态 更新时间:2024-10-27 16:30:59
本文介绍了opencv / javacv:如何迭代轮廓进行形状识别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在使用JavaCV开发一个形状识别项目,我发现了一些OpenCV代码来识别特定图像中的U形状。我试图将其转换为JavaCV,但它没有提供相同的输出。能帮我转一下这个OpenCV代码到JavaCV吗?

I'm developing a shape identification project using JavaCV and I have found some OpenCV code to identify U shapes in a particular image. I have tried to convert it into JavaCV but it doesn't give the same output. Can you please help me to convert this OpenCV code into JavaCV?

这是OpenCV代码:

This is the OpenCV code:

import cv2 import numpy as np img = cv2.imread('sofud.jpg') gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) ret,thresh = cv2.threshold(gray,127,255,1) contours,hierarchy = cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE) for cnt in contours: x,y,w,h = cv2.boundingRect(cnt) if 10 < w/float(h) or w/float(h) < 0.1: cv2.rectangle(img,(x,y),(x+w,y+h),(0,0,255),2) cv2.imshow('res',img) cv2.waitKey(0) cv2.destroyAllWindows()

这是预期的输出

这是转换后的代码:

import com.googlecode.javacpp.Loader; import com.googlecode.javacv.CanvasFrame; import static com.googlecode.javacpp.Loader.*; import static com.googlecode.javacv.cpp.opencv_core.*; import static com.googlecode.javacv.cpp.opencv_imgproc.*; import static com.googlecode.javacv.cpp.opencv_highgui.*; import java.io.File; import javax.swing.JFileChooser; public class TestBeam { public static void main(String[] args) { CvMemStorage storage=CvMemStorage.create(); CvSeq squares = new CvContour(); squares = cvCreateSeq(0, sizeof(CvContour.class), sizeof(CvSeq.class), storage); JFileChooser f=new JFileChooser(); int result=f.showOpenDialog(f);//show dialog box to choose files File myfile=null; String path=""; if(result==0){ myfile=f.getSelectedFile();//selected file taken to myfile path=myfile.getAbsolutePath();//get the path of the file } IplImage src = cvLoadImage(path);//hear path is actual path to image IplImage grayImage = IplImage.create(src.width(), src.height(), IPL_DEPTH_8U, 1); cvCvtColor(src, grayImage, CV_RGB2GRAY); cvThreshold(grayImage, grayImage, 127, 255, CV_THRESH_BINARY); CvSeq cvSeq=new CvSeq(); CvMemStorage memory=CvMemStorage.create(); cvFindContours(grayImage, memory, cvSeq, Loader.sizeof(CvContour.class), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE); System.out.println(cvSeq.total()); for (int i = 0; i < cvSeq.total(); i++) { CvRect rect=cvBoundingRect(cvSeq, i); int x=rect.x(),y=rect.y(),h=rect.height(),w=rect.width(); if (10 < (w/h) || (w/h) < 0.1){ cvRectangle(src, cvPoint(x, y), cvPoint(x+w, y+h), CvScalar.RED, 1, CV_AA, 0); //cvSeqPush(squares, rect); } } CanvasFrame cnvs=new CanvasFrame("Beam"); cnvs.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE); cnvs.showImage(src); //cvShowImage("Final ", src); } }

这是我得到的输出。请有人帮我解决这个问题吗?

This is the output that I got. Please can someone help me to solve this problem ?

推荐答案

编辑:这是最有趣的发现 - 我认为你没有正确迭代通过轮廓 - 你应该做类似的事情:

Here is the most interesting finding - I think you are not iterating correctly through the contours - you should do something like:

CvRect rect = cvBoundingRect(cvGetSeqElem(cvSeq, i),0); //python default?

或者:

// ... CvSeq contours = new CvSeq(); CvSeq ptr = new CvSeq(); CvRect rect = null; // ... cvFindContours(..., contours, ...); for (ptr = contours; ptr != null; ptr = ptr.h_next()) { rect = cvBoundingRect(ptr, 0); // ... Draw the box if meets criteria }

首先,我认为pst对于比率的计算是正确的 - 你必须将宽度转换为浮动。

First, I think pst is right regarding the calculation of the ratio - you have to cast the width to float.

其次,我看到当你制作灰色图像时python你使用 COLOR_BGR2GRAY 而在java中你使用 CV_RGB2GRAY 可能导致完全不同的灰色图片。我会在两个程序上添加一些调试步骤来保存临时灰度图像,并将它们与 x,y,w 和 h 当(10 <(w / h)||(w / h)<0.1)为真时。

Secondly, I see that when you are making the gray image in python you use COLOR_BGR2GRAY and in java you are using CV_RGB2GRAY that could lead to a totally different gray picture. I would add some debug steps on both programs to save the temp gray images and compare them as also print outs for the values of x,y,w and h when (10 < (w/h) || (w/h) < 0.1) is true.

另一件事是在java解决方案中你使用 CV_RETR_CCOMP 来获取轮廓并在你使用的python解决方案中 CV_RETR_LIST 根据文档:

Another thing is that in the java solution you use CV_RETR_CCOMP to get the contours and in the python solution you use CV_RETR_LIST according to the documentation:

CV_RETR_LIST检索所有轮廓而不建立任何层次关系CV_RETR_CCOMP检索所有轮廓并将它们组织成两级层次结构:顶层是组件的外部边界,第二层是的孔边界。如果在连接组件的一个洞内有另一个轮廓,它仍然会被放在顶层

CV_RETR_LIST retrieves all of the contours without establishing any hierarchical relationships CV_RETR_CCOMP retrieves all of the contours and organizes them into a two-level hierarchy: on the top level are the external boundaries of the components, on the second level are the boundaries of the holes. If inside a hole of a connected component there is another contour, it will still be put on the top level

所以首先,我会仔细检查两个程序中的所有cv参数是否相同,然后我会添加调试步骤以查看中间变量包含相同的数据。

So first I would double check that all cv's parameters in both programs are the same, then I would add debug steps to see that the intermediate variables contains the same data.

更多推荐

opencv / javacv:如何迭代轮廓进行形状识别?

本文发布于:2023-05-26 20:19:47,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/265205.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:轮廓   形状   迭代   opencv   javacv

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!