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?
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()
This is the expected output

This is the converted code:
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 ?

EDIT: Here is the most interesting finding –
I think you are not iterating correctly through the contours – you should do something like:
Or:
First, I think pst is right regarding the calculation of the ratio – you have to cast the width to float.
Secondly, I see that when you are making the gray image in python you use
COLOR_BGR2GRAYand in java you are usingCV_RGB2GRAYthat 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 ofx,y,wandhwhen(10 < (w/h) || (w/h) < 0.1)is true.Another thing is that in the java solution you use
CV_RETR_CCOMPto get the contours and in the python solution you useCV_RETR_LISTaccording to the documentation: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.