繁体   English   中英

OpenCV Java极限轮廓

[英]OpenCV Java limit contours

我在Android应用程序中使用OpenCV。 我希望移动应用程序在查看矩形(例如收据形状的东西)时自动拍照。 我正在使用Canny边缘检测,但是当我寻找轮廓时,数组大小大于1500。显然,遍历所有轮廓并找到最大的轮廓并不是最佳选择,所以我想知道是否可以过滤出最大的轮廓通过api自动绘制轮廓?

到目前为止,我的代码:

ArrayList contours;

    @Override
    public Mat onCameraFrame(final CameraBridgeViewBase.CvCameraViewFrame inputFrame) {

    // Clear contours array on each frame
    contours.clear();

    // Get Grayscale image
    final Mat gray = inputFrame.gray();

    // Canny edge detection 
    Imgproc.Canny(gray, gray, 300, 1000, 5, true);

    // New empty black matrix to store the edges captured
    Mat dest = new Mat();
    Core.add(dest, Scalar.all(0), dest);

    // Copy the edge data over to the empty black matrix
    gray.copyTo(dest);

    // Is there a way to filter the size of contours so that not everything is returned? Right now this function is returning a lot of contours (1500 +)
    Imgproc.findContours(gray, contours, hirearchy, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);

    return dest;
}

编辑用户将手持电话,并且我希望应用程序在收据查看时自动拍照。 收据示例

我已经介绍了您可能使用的基本技术,在下面的Python代码中,将不难用您选择的语言(在这种情况下为Java)来翻译代码。 因此,该技术涉及:

  • 估计要分割的对象的颜色,在您的情况下为白色,因此上限和下限的安全限制可以近似为:

     RECEIPT_LOWER_BOUND = np.array([200, 200, 200]) RECEIPT_UPPER_BOUND = np.array([255, 255, 255]) 
  • 对输入图像应用一些模糊以使颜色分布平滑,这将在将来缩小较小的轮廓。

     img_blurred = cv2.blur(img, (5, 5)) 
  • 对二值图像应用膨胀以去除围绕目标最大轮廓的相邻较小轮廓

     kernel = np.ones((10, 10), dtype=np.uint8) mask = cv2.dilate(mask, kernel) 
  • 现在,在执行上述操作之后,在遮罩中找到轮廓,并根据ContourArea过滤出轮廓。

     im, contours, hierarchy = cv2.findContours(receipt_mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) largest_contour = max(contours, key=lambda x: cv2.contourArea(x)) 
  • 最后,您可以在该区域上应用一些阈值,以验证输入内容是否确实是票证。

码:

import cv2
import numpy as np


# You may change the following ranges to define your own lower and upper BGR bounds.
RECEIPT_LOWER_BOUND = np.array([200, 200, 200])
RECEIPT_UPPER_BOUND = np.array([255, 255, 255])


def segment_receipt(img):
    # Blur the input image to reduce the noise which in-turn reduces the number of contours
    img_blurred = cv2.blur(img, (5, 5))
    mask = cv2.inRange(img_blurred, RECEIPT_LOWER_BOUND, RECEIPT_UPPER_BOUND)

    # Also dilate the binary mask which further reduces the salt and pepper noise
    kernel = np.ones((10, 10), dtype=np.uint8)
    mask = cv2.dilate(mask, kernel)
    return mask


def get_largest_contour_rect(image):
    receipt_mask = segment_receipt(image)
    im, contours, hierarchy = cv2.findContours(receipt_mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    print "Number of contours found :", len(contours)

    # Sorting the contours to get the largest one
    largest_contour = max(contours, key=lambda x: cv2.contourArea(x))

    # Return the last contour in sorted list as the list is sorted in increasing order.
    return cv2.boundingRect(largest_contour)

image = cv2.imread("path/to/your/image.jpg")
rect = get_largest_contour_rect(image)

输出:

在此处输入图片说明

@ J.Doe我目前正在从事这样的项目,经过大量的处理,我已经能够成功隔离图像中最大的轮廓。 剩下的唯一部分是识别矩形轮廓并拍照。

mRgba = inputFrame.rgba();
    Imgproc.Canny(mRgba,mCanny,50,200);
    Imgproc.cvtColor(mRgba, mGray, Imgproc.COLOR_RGB2GRAY);

    Imgproc.GaussianBlur(mGray, mGray1, new Size(3, 3), 1);
    Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT,new Size(9,9));

    Imgproc.dilate(mGray1, mGray2, kernel);
    Imgproc.Canny(mGray2, mCanny, 50, 200);

    Imgproc.findContours(mCanny,contours,hierarchy,Imgproc.RETR_TREE,Imgproc.CHAIN_APPROX_SIMPLE);
    double maxVal = 0;
    int maxValIdx = 0;
    for(int contourIdx = 0; contourIdx < contours.size(); contourIdx++){
        double contourArea = Imgproc.contourArea(contours.get(contourIdx));
        if(maxVal < contourArea)
        {
            maxVal = contourArea;
            maxValIdx = contourIdx;
        }
    }
    Imgproc.drawContours(mRgba,contours,maxValIdx,new Scalar(0,255,255),-1);
    return mRgba;

警惕图像名称,我在不同的过程中更改了它们。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM