2016-09-15 132 views
0

我正在尝试渲染相机预览框中的最大轮廓。这里是我的代码:使用opencv进行文档轮廓检测

@Override 
    public void onPreviewFrame(byte[] data, Camera camera) { 
     previewSize = cameraConfigUtil.cameraInstance.getParameters().getPreviewSize(); 
     Mat srcMat = new Mat(previewSize.height, previewSize.width, CvType.CV_8UC3); 
     srcMat.put(0, 0, data); 
     rect = ImageCorrection.getLargestContour(data, previewSize.height, previewSize.width); 
     android.graphics.Rect rectangle = new android.graphics.Rect(); 
     rectangle.left = rect.x; 
     rectangle.top = rect.y; 
     rectangle.right = rect.x + rect.width; 
     rectangle.bottom = rect.y + rect.height; 
     mOverlay.clear(); 
     BarcodeGraphic graphic = new BarcodeGraphic(mOverlay); 
     mOverlay.add(graphic); 
     graphic.updateItem(rectangle); 
     Imgproc.rectangle(srcMat, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(255, 0, 0, 255), 3); 
     Utils.matToBitmap(srcMat, bitmap); 
    } 

它检测的轮廓,但是当我把它添加到覆盖没有放置在文件上框和边框看起来更小。我正在使用预览帧中的原始数据。我错过了什么?基本上检测到的最大轮廓与实际预览大小无关。

public static Rect getLargestContour(byte[] data, int height, int width) { 
     Mat srcMat = new Mat(height, width, CvType.CV_8UC3); 
     srcMat.put(0, 0, data); 
     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), 0); 

     Imgproc.Canny(imgSource, imgSource, 50, 50); 

     List<MatOfPoint> contours = new ArrayList<>(); 
     Imgproc.findContours(imgSource, contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE); 
     Imgproc.cvtColor(imgSource, srcMat, Imgproc.COLOR_GRAY2RGB, 4); 

     double maxArea = -1; 
     Log.d("size", Integer.toString(contours.size())); 
     MatOfPoint temp_contour; 
     MatOfPoint2f approxCurve = new MatOfPoint2f(); 

     for (MatOfPoint contour : contours) { 
      double contourarea = Imgproc.contourArea(contour); 
      if (contourarea > 0 
        && contourarea > maxArea) { 
       //check if this contour is a square 
       MatOfPoint2f new_mat = new MatOfPoint2f(contour.toArray()); 
       int contourSize = (int) contour.total(); 
       MatOfPoint2f approxCurve_temp = new MatOfPoint2f(); 
       Imgproc.approxPolyDP(new_mat, approxCurve_temp, contourSize * 0.05, true); 
       if (approxCurve_temp.total() == 4) { 
        maxArea = contourarea; 
        approxCurve = approxCurve_temp; 
       } 
      } 
     } 

     MatOfPoint points = new MatOfPoint(approxCurve.toArray()); 

     return Imgproc.boundingRect(points); 
    } 

enter image description here

这是OpenCV的考虑图像大小。

enter image description here

+1

请添加一些图片为那些坏imaginationen – PSchn

+0

我重视的图像 –

+0

我不是YUV格式转换为RGB这是原因吗? –

回答

0

于是终于发现了问题: 这里

Mat srcMat = new Mat(height, width, CvType.CV_8UC3); 
srcMat.put(0, 0, data); 

我把数据是YUV型的垫子是CV_8U3。它应该是CV_8U1。

Mat srcMat = new Mat(height, width, CvType.CV_8UC1); 
srcMat.put(0, 0, data); 

,我们并不需要将其转换为灰度:

Mat imgSource = new Mat(srcMat.size(), CvType.CV_8UC1); 
Imgproc.cvtColor(srcMat, imgSource, Imgproc.COLOR_RGB2GRAY, 4);