Java Android Opencv 2.3上的凸包

Java Android Opencv 2.3上的凸包,java,android,opencv,convex-hull,Java,Android,Opencv,Convex Hull,请帮帮我 我对Android上的凸面外壳有一个问题。我使用Java和OpenCV 2.3 在我用java制作之前,我用Visual Studio 2008在C++上做了.< /P> 此代码可以在C++上运行成功。p> 现在,我想在Android上从C++转换成java。在SDK Android模拟器上运行时,我发现了类似“强制关闭”的错误 这是我在C++上的代码: vector<vector<Point> > contours; vector<Vec4i> h

请帮帮我

我对Android上的凸面外壳有一个问题。我使用Java和OpenCV 2.3

在我用java制作之前,我用Visual Studio 2008在C++上做了.< /P>

此代码可以在C++上运行成功。p>

现在,我想在Android上从C++转换成java。在SDK Android模拟器上运行时,我发现了类似“强制关闭”的错误

这是我在C++上的代码:

vector<vector<Point> > contours;
vector<Vec4i> hierarchy;

findContours( canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
drawing = Mat::zeros( canny_output.size(), CV_64F );

/// Find the convex hull object for each contour
vector<vector<Point> > hull ( contours.size() );
for( int i = 0; i < contours.size(); i++ )
  {  convexHull( Mat(contours[i]), hull[i], false );
}

for(size_t i = 0; i < contours.size(); i++){
    drawContours( drawing, hull, i, Scalar(255, 255, 255), CV_FILLED ); // FILL WHITE COLOR
}
矢量轮廓;
向量层次;
findContours(canny_输出、轮廓、层次、CV_RETR_树、CV_链近似_简单、点(0,0));
drawing=Mat::zeros(canny_output.size(),CV_64F);
///查找每个轮廓的凸面外壳对象
向量外壳(contours.size());
对于(int i=0;i
这是我在Android上的代码:

Mat hierarchy = new Mat(img_canny.rows(),img_canny.cols(),CvType.CV_8UC1,new Scalar(0));
    List<Mat> contours =new ArrayList<Mat>();
    List<Mat> hull = new ArrayList<Mat>(contours.size());
    drawing = Mat.zeros(img_canny.size(), im_gray);

    Imgproc.findContours(img_dilasi, contours, hierarchy,Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE, new Point(0, 0));

    for(int i=0; i<contours.size(); i++){
        Imgproc.convexHull(contours.get(i), hull.get(i), false);

    }
    for(int i=0; i<contours.size(); i++){
        Imgproc.drawContours(drawing, hull, i, new Scalar(255.0, 255.0, 255.0), 5);
    }
Mat hierarchy=new Mat(img_canny.rows()、img_canny.cols()、CvType.CV_8UC1、new Scalar(0));
列表等高线=新的ArrayList();
列表外壳=新的ArrayList(contours.size());
图纸=材料零点(img_canny.size(),im_灰色);
Imgproc.findContours(img_dilasi,等高线,层次结构,Imgproc.RETR_树,Imgproc.CHAIN_近似简单,新点(0,0));

对于(int i=0;i查看和的文档,您似乎错误地声明了变量
等高线
外壳

尝试将声明更改为:

List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
List<MatOfInt> hull = new ArrayList<MatOfInt>();
List contours=new ArrayList();
列表外壳=新的ArrayList();

然后,在调用
convexHull()
之后,
hull
包含构成凸壳的
等高线中的点的索引。为了使用
drawcourts()绘制点
,您将需要填充一个新的
MatOfPoint
,该点仅包含凸面外壳上的点,并将其传递给
drawcours()< /代码>。我将此作为练习。< / P> < P> >奥勒留的补充,在C++实现中,使用了一个点向量,因此,HARE矩阵包含实际的凸点:

“在第一种情况下[整数向量索引],外壳元素是原始数组中凸包点的基于0的索引(因为凸包点集是原始点集的子集)。在第二种情况下[向量点],外壳元素是凸包点本身。”-

这就是你能打电话的原因

drawContours( drawing, hull, i, Scalar(255, 255, 255), CV_FILLED );
在android版本中,外壳输出只是一个索引数组,对应于原始轮廓中的点。获取(i)矩阵。因此,您需要查找原始矩阵中的凸点。下面是一个非常粗略的想法:

MatOfInt hull = new MatOfInt();
MatOfPoint tempContour = contours.get(i);
Imgproc.convexHull(tempContour, hull, false); // O(N*Log(N))
//System.out.println("hull size: " + hull.size() + " x" + hull.get(0,0).length);
//System.out.println("Contour matrix size: " + tempContour.size() + " x" + tempContour.get(0,0).length);

int index = (int) hull.get(((int) hull.size().height)-1, 0)[0];
Point pt, pt0 = new Point(tempContour.get(index, 0)[0], tempContour.get(index, 0)[1]);
for(int j = 0; j < hull.size().height -1 ; j++){
    index = (int) hull.get(j, 0)[0];
    pt = new Point(tempContour.get(index, 0)[0], tempContour.get(index, 0)[1]);
    Core.line(frame, pt0, pt, new Scalar(255, 0, 100), 8);
    pt0 = pt;
}
MatOfInt外壳=新的MatOfInt();
MatOfPoint tempContour=等高线。获取(i);
Imgproc.convxhull(tempContour,hull,false);//O(N*Log(N))
//System.out.println(“外壳尺寸:”+hull.size()+“x”+hull.get(0,0).length);
//System.out.println(“轮廓矩阵大小:”+tempContour.size()+“x”+tempContour.get(0,0).length);
int index=(int)hull.get((int)hull.size().height)-1,0[0];
点pt,pt0=新点(tempContour.get(index,0)[0],tempContour.get(index,0)[1]);
对于(int j=0;j
没有代表添加评论,只是想说上面的两个答案帮助我让Imgproc.convxhull()在我的用例中使用类似的东西(2.4.8):

MatOfPoint mopIn=。。。
MatOfInt外壳=新MatOfInt();
Imgproc.CONVERXHULL(莫宾,船体,假);
MatOfPoint mopOut=新的MatOfPoint();
创建((int)hull.size().height,1,CvType.CV_32SC2);
对于(int i=0;i
此代码在我的应用程序中运行良好。在我的例子中,我有多个轮廓可供使用,因此您会注意到许多列表,但如果您只有一个轮廓,只需调整它即可,无需.get(I)迭代

这个线程更简单地解释了这个过程

//查找凸包
列表外壳=新的ArrayList();
对于(int i=0;iMatOfPoint mopIn = ...
MatOfInt hull = new MatOfInt();
Imgproc.convexHull(mopIn, hull, false);

MatOfPoint mopOut = new MatOfPoint();
mopOut.create((int)hull.size().height,1,CvType.CV_32SC2);

for(int i = 0; i < hull.size().height ; i++)
{
    int index = (int)hull.get(i, 0)[0];
    double[] point = new double[] {
        mopIn.get(index, 0)[0], mopIn.get(index, 0)[1]
    };
    mopOut.put(i, 0, point);
}           
// do something interesting with mopOut
   // Find the convex hull
            List<MatOfInt> hull = new ArrayList<MatOfInt>();
            for(int i=0; i < contours.size(); i++){
                hull.add(new MatOfInt());
            }
            for(int i=0; i < contours.size(); i++){
                Imgproc.convexHull(contours.get(i), hull.get(i));
            }

            // Convert MatOfInt to MatOfPoint for drawing convex hull

            // Loop over all contours
            List<Point[]> hullpoints = new ArrayList<Point[]>();
            for(int i=0; i < hull.size(); i++){
                Point[] points = new Point[hull.get(i).rows()];

                // Loop over all points that need to be hulled in current contour
                for(int j=0; j < hull.get(i).rows(); j++){
                    int index = (int)hull.get(i).get(j, 0)[0];
                    points[j] = new Point(contours.get(i).get(index, 0)[0], contours.get(i).get(index, 0)[1]);
                }

                hullpoints.add(points);
            }

            // Convert Point arrays into MatOfPoint
            List<MatOfPoint> hullmop = new ArrayList<MatOfPoint>();
            for(int i=0; i < hullpoints.size(); i++){
                MatOfPoint mop = new MatOfPoint();
                mop.fromArray(hullpoints.get(i));
                hullmop.add(mop);
            }


            // Draw contours + hull results
            Mat overlay = new Mat(binaryImage.size(), CvType.CV_8UC3);
            Scalar color = new Scalar(0, 255, 0);   // Green
            for(int i=0; i < contours.size(); i++){
                Imgproc.drawContours(overlay, contours, i, color);
                Imgproc.drawContours(overlay, hullmop, i, color);
            }
List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
MatOfInt4 hierarchy = new MatOfInt4();
MatOfInt hull = new MatOfInt();

void foo(Mat gray) {
    Imgproc.findContours(gray, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);        
    for (int i = 0; i < contours.size(); i++) {
        Imgproc.convexHull(contours.get(i), hull);
        MatOfPoint hullContour = hull2Points(hull, contours.get(i));
        Rect box = Imgproc.boundingRect(hullContour);
        Mat hullMat = new Mat(gray, box);
        ...
    }
}

MatOfPoint hull2Points(MatOfInt hull, MatOfPoint contour) {
    List<Integer> indexes = hull.toList();
    List<Point> points = new ArrayList<>();
    MatOfPoint point= new MatOfPoint();
    for(Integer index:indexes) {
        points.add(contour.toList().get(index));
    }
    point.fromList(points);
    return point;
}
 for(;;){
          Imgproc.fillConvexPoly(image_2, point,new Scalar(255, 255, 255));
    }