2013-11-21 43 views
3

我用:
javacv:迭代CvSeq在Java中

cvFindContours(gray, mem, contours, Loader.sizeof(CvContour.class) , CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));


和作为结果我有CvSeq contours迭代(据我所知)。
于是我就用它这样的:

if(contours!=null) { 
    for (ptr = contours; ptr != null; ptr = ptr.h_next()) { 
    //..do sth with ptr 
    } 
} 

它的工作原理,但不时(经常)我得到:

Exception in thread "Thread-3" java.lang.NullPointerException: This pointer address is NULL. 
at com.googlecode.javacv.cpp.opencv_core$CvSeq.h_next(Native Method) 
at pl..filter(FullFilter.java:69) 
at pl..Window$1.run(Window.java:41) 
at java.lang.Thread.run(Unknown Source) 


在抛出异常的行是与ptr.h_next()的行。
我试图检查空值,但它不工作:

System.out.println("PTR="+ptr); // it's not null here! 
if(ptr.h_next()==null) //exception in this line! 
    System.out.println("NULL"); 
System.out.println(ptr.h_next()); 

,第一行显示: PTR=com.googlecode.javacv.cpp.opencv_core$CvSeq[address=0x0,position=0,limit=1,capacity=1,[email protected]53ea4]

我试着也援引contours.total()但它总是抛出同样的异常。
那么,在Java中使用这种类似C的序列的正确方法是什么?

编辑: 我的全部方法:

public IplImage filter(IplImage image) { 
     IplConvKernel kernel = cvCreateStructuringElementEx(2,2,1,1,CV_SHAPE_RECT, null); 
     cvDilate(image, image, kernel, 1); 
     kernel = cvCreateStructuringElementEx(5,5,2,2,CV_SHAPE_RECT, null); 
     cvErode(image, image, kernel, 1); 
     IplImage resultImage = cvCloneImage(image); 
     IplImage gray = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1); 
     cvCvtColor(image, gray, CV_BGR2GRAY); 
     CvMemStorage mem = CvMemStorage.create(); 
     CvSeq contours = new CvSeq(); 
     CvSeq ptr = new CvSeq(); 
     cvThreshold(gray, gray, 20, 255, opencv_imgproc.CV_THRESH_BINARY); 
     double thresh = 20; 
     Canny(gray, gray, thresh, thresh*2, 3 ,true); 
     cvFindContours(gray, mem, contours, Loader.sizeof(CvContour.class) , CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0)); 

     int i=0; 
     CvRect boundbox; 
     if(contours!=null) { 
      for (ptr = contours; ptr != null; ptr = ptr.h_next()) { //EXCEPTION HERE! 
       System.out.println((i++)+"\t"+ptr); 
       cvDrawContours(resultImage, ptr, CvScalar.BLUE, CvScalar.RED, -1, 3, 8, cvPoint(0,0)); 
       System.out.println("PTR="+ptr); 
      } 

     }  
     return resultImage; 
    } 

它正常工作了一段时间,突然(很可能在没有轮廓发现?),它有以下例外结束:

Exception in thread "Thread-3" java.lang.NullPointerException: This pointer address is NULL. 
    at com.googlecode.javacv.cpp.opencv_core$CvSeq.h_next(Native Method) 
    at pl.kasprowski.eyetracker.FullFilter2.filter(FullFilter2.java:39) 
    at pl.kasprowski.eyetracker.Window$1.run(Window.java:42) 
    at java.lang.Thread.run(Unknown Source) 

Im直接使用摄像头拍摄的图像(每秒一次)。

编辑:

它发生一些实验后,从时间,当调用cvFindContours如上我得到一个contour对象,它是NOT NULL,但调用像contour.h_next()contour.total()结果异常像上述的任何方法时, 。什么可能是错误的?或者 - 如何检查contour对象是否可以?当然,我可以赶上NullPointerException但我不认为这是解决问题的正确道路...

+0

嗨,你可以显示告诉完整的“运行”功能,究竟是什么与异常行号一起做?正如你所做的是正确的。其他一些事情可能会导致问题。 – SeeTheC

+0

我添加了完整的代码。 – paulo116

回答

2

问题解决了。
我添加了附加条件。相反的:

if(contours!=null) { 

我写

if(contours!=null && !contours.isNull()) { 

和它的作品。我不明白为什么这是必要的,但我认为它与Java语义差距有关。

0

尝试使用cvGetSeqElem(contours, i)

例子:

for (int i = 0; i < contours.total(); i++) { 
    CvRect rect = cvBoundingRect(cvGetSeqElem(contours, i),0); 
    //....... Your code ....// 

} 
+0

使用时:'CvRect rect = cvBoundingRect(cvGetSeqElem(contour,j),0);''我得到了:'opencv_imgproc类型的方法cvBoundingRect(opencv_core.CvArr,int)不适用于参数(Pointer,int) ' – paulo116