问题描述
我正在使用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 为真时。
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参数是否相同,然后我会添加调试步骤以查看中间变量包含相同的数据。
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:如何迭代轮廓进行形状识别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!