如何在Android中使用OpenCV删除轮廓的背景?

时间:2017-11-28 17:40:58

标签: java android opencv ocr

示例令牌已扫描:https://ibin.co/3irqGlxXezL3.jpg

输入图片:https://ibin.co/3irmfXKjYocz.jpg

Output Image

正如你所看到的,我已经应用了.submat,但我不确定为什么它会掩盖轮廓的内部而不是外表面。而且,过滤最大轮廓也不一致。关于如何根据票证的尺寸使其更加稳健的任何想法,因为我的目标是扫描具有相同尺寸的票证。

作为一名新手OpenCV爱好者,我希望有人指导我完成我的最终任务,即从机票中的日历中获取年份,月份,日期和时间,并以文本形式显示。

门票上有打孔作为标记。因此,我想到的是跟踪每个(洞)斑点并将其与周围的数字一起提取以知道它基于其周围的数字,并对所有斑点(洞)执行此操作一些层次结构,以了解提取是否来自' year'字段或月或日字段。或者还有其他更好的方法吗?

@Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
    Mat srcMat = inputFrame.rgba();
    Mat processedMat = new Mat();
    Imgproc.cvtColor(srcMat, processedMat, Imgproc.COLOR_BGR2GRAY);
    Imgproc.GaussianBlur(processedMat, processedMat, new Size(3, 3), 0);
    Imgproc.threshold(processedMat, processedMat, 98, 255, Imgproc.THRESH_BINARY);
    List<MatOfPoint> contours = new ArrayList<>();
    Mat hierarchy = new Mat();
    Imgproc.findContours(processedMat, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
    Log.e(TAG, "ContourSize: " + contours.size());
    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(srcMat, contours, maxValIdx, new Scalar(0, 255, 0), -2);
    if (!contours.isEmpty()) {
        Log.e("largestContour", "" + contours.get(maxValIdx));
        Rect rect = Imgproc.boundingRect(contours.get(maxValIdx));
        srcMat.submat(rect);
    }
    return srcMat;
}

1 个答案:

答案 0 :(得分:1)

那么,

首先,您使用的是drawContours方法的重载版本。 负厚度意味着将绘制填充的countour。

因此,尝试将-2更改为正数以获得所需的轮廓。

现在让我试着说出我在票证上检测这些日期的第一种方法:

1)使用预期变换将轮廓转换为垂直视图:

enter image description here

在Python中查看此example

2)使用blob检测来查找blob:

enter image description here

在Python和C ++中查看此example

如果您有明确定义的故障单布局模型,它应该有效。