mixChannels() 在 opencv android 中给出异常

mixChannels() giving exception in opencv android

本文关键字:异常 android opencv mixChannels      更新时间:2023-10-16

我正在编写函数以在 Mat 中查找矩形。但是我在mixChannels()函数上遇到了异常。 我的代码如下。有人可以检查并告诉我其中可能出了什么问题吗?我还想知道如何在 java 或 android 中实现gray = gray0 >= (l+1)*255/N;

private void findSqaures(Mat sourceImage){
        Vector<Point> sqares;
        Mat pyr,timing ,gry =new Mat();
        pyr=new Mat(sourceImage.size(),CvType.CV_8U);
        timing=new Mat(sourceImage.size(),CvType.CV_8U);
        int thresh = 50, N = 11;
        List<Mat> grayO=new ArrayList<Mat>();
        List<Mat> timing1=new ArrayList<Mat>();
        Imgproc.pyrDown(sourceImage, pyr,new Size(sourceImage.cols()/2.0, sourceImage.rows()/2));
        Imgproc.pyrUp(pyr, timing,sourceImage.size());
//      Vector<Point> contours=new Vector<Point>();
        timing1.add(0,pyr);
        grayO.add(0,timing);
//      grayO.add(0,timing);
        for(int c=0;c<3;c++){
            int ch[]={1,0};
            MatOfInt fromto = new MatOfInt(ch);
            Core.mixChannels(timing1, grayO, fromto); // Getting Exception here
//          Core.mixChannels(src, dst, fromTo)
            for(int i=0;i<N;i++){
                Mat output=grayO.get(0);
                if(i==0){
                    Imgproc.Canny(output, gry, 5, thresh);
                    Imgproc.dilate(gry, gry, new Mat(), new Point(-1,-1), 1);
                }
                 else { 
//                   output = output >= (i+1)*255/N;
                   }
//              sourceImage=gry;
                contours=new ArrayList<MatOfPoint>();
                Imgproc.findContours(gry, contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
                 MatOfPoint2f approxCurve = new MatOfPoint2f();
                 mDrawnContours.clear();
                 Log.i(TAG, "::findSqaures:" + "contours.size():"+contours.size());
                for(int j=0;i<contours.size();j++){
                    MatOfPoint tempContour=contours.get(i);
                    MatOfPoint2f newMat = new MatOfPoint2f( tempContour.toArray() );
                    int contourSize = (int)tempContour.total();
                    Imgproc.approxPolyDP(newMat, approxCurve, contourSize*0.02, true);
                    MatOfPoint points=new MatOfPoint(approxCurve.toArray());
//                    if( approx.size() == 4 && fabs(contourArea(cv::Mat(approx))) > 1000 && cv::isContourConvex(cv::Mat(approx))) {
                    if(points.toArray().length==4 && (Math.abs(approxCurve.total())>1000) && Imgproc.isContourConvex(points)){
                        double maxCosine=0;
                        int k;
                        for( k=2;k<5;k++){
                            double cosine=Math.abs(angle(points.toArray()[k%4], points.toArray()[k-2], points.toArray()[k-1]));
                            if(maxCosine>cosine){
                                maxCosine=cosine;
                            }
                        }
                        Log.i(TAG, "::findSqaures:" + "maxCosine:"+maxCosine);
                        if(maxCosine<0.3){
                            DrawnContours drawnContours=new DrawnContours();
                            drawnContours.setIndex(k);
                            mDrawnContours.add(drawnContours);
                        }
                    }
                }
                Log.i(TAG, "::findSqaures:" + "mDrawnContours.size():"+mDrawnContours.size());
            }
        }

//      Core.mixChannels(src, dst, fromTo)
    }

例外是 *CvException [org.opencv.core.CvException:/home/reports/ci/slave_desktop/50-SDK/opencv/modules/core/src/matrix.cpp:3210: error: (-215) A.size == arrays[i0]->size in function void cv::NAryMatIterator::init(const cv::Mat, cv::Mat*, uchar*, int)**

而不是以下内容定时1.添加(0,吡喃);grayO.add(0,timeing);

试试这个

timing1.add(pyr);
grayO.add(timing);

而不是下面的行

gry = output >= (i+1)*255/N;

你可以使用

Imgproc.threshold(output, gry, (l+1) * 255 / N, 255, Imgproc.THRESH_BINARY);

此外,不使用pyr作为源,而是使用medianBlur功能模糊图像,您将获得更好的矩形识别。

from

Core.mixChannels(timing1, grayO, fromto); 

元素gray0数组和timing1数组的大小应相同。但是pyr的大小只有timing的一半,所以你有一个错误。

再看样squares.cpp

  1. 混合通道函数的来源应该是 pyrUp 函数的结果垫
  2. mixChannels函数的目的地应该是具有相同大小的新空垫。

因此,请用以下方法更正:

timing1.add(0,timing); // or timing1.add(timing)
grayO.add(0, new Mat(timing.size(), timing.type()) );

问候路易斯