使用OpenCV检测最大轮廓

时间:2016-08-18 00:55:26

标签: android opencv

问题1: 我尝试了什么? 我正在构建一个带有文档识别和透视校正的文档扫描程序。为此,我使用的是OpenCV。以下是步骤:

  1. 拍摄文件图片
  2. 调整图片大小

    Bitmap bitmap = CameraImageUtils.decodeSampledBitmapFromResource(data[0], CameraConfigurationUtils.MIN_FRAME_WIDTH, CameraConfigurationUtils.MIN_FRAME_HEIGHT);
    
  3. 应用Canny Edge检测

    Mat srcMat = new Mat(height, width, CvType.CV_8UC3);
        Utils.bitmapToMat(sourceBitmap, srcMat);
        Mat imgSource = new Mat(srcMat.size(), CvType.CV_8UC1);
        Imgproc.cvtColor(srcMat, imgSource, Imgproc.COLOR_RGB2GRAY, 4);
        Imgproc.GaussianBlur(imgSource, imgSource, new org.opencv.core.Size(5, 5), 5);
    
        Imgproc.Canny(imgSource, imgSource, 50, 50);
    
        //find the contours
        List<MatOfPoint> contours = new ArrayList<>();
        Imgproc.findContours(imgSource, contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
    
        double maxArea = -1;
        int maxAreaIdx = -1;
        Log.d("size", Integer.toString(contours.size()));
        MatOfPoint temp_contour = contours.get(0); //the largest is at the index 0 for starting point
        MatOfPoint2f approxCurve = new MatOfPoint2f();
        MatOfPoint largest_contour = contours.get(0);
    
        for (int idx = 0; idx < contours.size(); idx++) {
            temp_contour = contours.get(idx);
            double contourarea = Imgproc.contourArea(temp_contour);
            //compare this contour to the previous largest contour found
            if (contourarea > maxArea) {
                //check if this contour is a square
                MatOfPoint2f new_mat = new MatOfPoint2f(temp_contour.toArray());
                int contourSize = (int) temp_contour.total();
                MatOfPoint2f approxCurve_temp = new MatOfPoint2f();
                Imgproc.approxPolyDP(new_mat, approxCurve_temp, contourSize * 0.05, true);
                if (approxCurve_temp.total() == 4) {
                    maxArea = contourarea;
                    maxAreaIdx = idx;
                    approxCurve = approxCurve_temp;
                    largest_contour = temp_contour;
                }
            }
        }
    

    有什么问题? 我试图绘制所有轮廓,但文档本身从未被识别为轮廓。 Document Correction

  4. 我在这里做错了什么?该应用程序的主要目标是在实时摄像头预览中检测文档,并且当用户拍照时,仅显示尺寸减小(<160kb)的文档并上传图片。

    问题2: 我正在为OpenCv使用静态初始化程序,这将增加应用程序的大小,我不希望这样。 OpenCV有替代方案吗?

1 个答案:

答案 0 :(得分:1)

我无法发表评论,但我会尝试为您的问题1 做出回答。

您的原始图片在哪里?

您需要拥有类似二进制图像的内容,其中包含0&amp; 255色像素,是灰色图像(所以你只有1个通道)。您需要拥有完整的图像块才能使OpenCV findContour()功能正常工作。

到那时我确定你会找到你的轮廓。您的代码没有问题。

PS。您甚至不需要使用Canny进行轮廓检测。如果你真的想要获得图像的边缘,你只能使用它。

希望它有所帮助。