android - 使用 OpenCV 在彩色背景上进行边缘检测

标签 android opencv edge-detection

我正在使用以下代码检测给定文档的边缘。

private Mat edgeDetection(Mat src) {
    Mat edges = new Mat();
    Imgproc.cvtColor(src, edges, Imgproc.COLOR_BGR2GRAY);
    Imgproc.GaussianBlur(edges, edges, new Size(5, 5), 0);
    Imgproc.Canny(edges, edges, 10, 30);
    return edges;
}

然后我可以从这个 edges 中找到最大的轮廓来找到文档。

我的问题是我可以从下面的图片中找到文档:

enter image description here

但不是来自下图:

enter image description here

如何改进这种边缘检测?

最佳答案

我用的是Python,但是主要思想是一样的。

如果你直接为 img2 执行 cvtColor: bgr -> gray,那么你一定会失败。因为灰色变得难以区分区域:

enter image description here


相关回答:

  1. How to detect colored patches in an image using OpenCV?
  2. Edge detection on colored background using OpenCV
  3. OpenCV C++/Obj-C: Detecting a sheet of paper / Square Detection

在您的图像中,纸张是白色,而背景是彩色。因此,最好在 HSV 颜色空间 中检测纸张是否为 Saturation(饱和度) channel 。对于 HSV,请参阅 https://en.wikipedia.org/wiki/HSL_and_HSV#Saturation .


主要步骤:

  1. 读入BGR
  2. 将图像从bgr转换为hsv空间
  3. S channel 阈值
  4. 然后找到最大外部轮廓(或者做Canny,或者HoughLines,我选择findContours),大约得到角落。

这是第一个结果:

enter image description here

这是第二个结果:

enter image description here

Python代码(Python 3.5 + OpenCV 3.3):

#!/usr/bin/python3
# 2017.12.20 10:47:28 CST
# 2017.12.20 11:29:30 CST

import cv2
import numpy as np

##(1) read into  bgr-space
img = cv2.imread("test2.jpg")

##(2) convert to hsv-space, then split the channels
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
h,s,v = cv2.split(hsv)

##(3) threshold the S channel using adaptive method(`THRESH_OTSU`) or fixed thresh
th, threshed = cv2.threshold(s, 50, 255, cv2.THRESH_BINARY_INV)

##(4) find all the external contours on the threshed S
cnts = cv2.findContours(threshed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]
canvas  = img.copy()
#cv2.drawContours(canvas, cnts, -1, (0,255,0), 1)

## sort and choose the largest contour
cnts = sorted(cnts, key = cv2.contourArea)
cnt = cnts[-1]

## approx the contour, so the get the corner points
arclen = cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, 0.02* arclen, True)
cv2.drawContours(canvas, [cnt], -1, (255,0,0), 1, cv2.LINE_AA)
cv2.drawContours(canvas, [approx], -1, (0, 0, 255), 1, cv2.LINE_AA)

## Ok, you can see the result as tag(6)
cv2.imwrite("detected.png", canvas)

关于android - 使用 OpenCV 在彩色背景上进行边缘检测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47899132/

相关文章:

python - openCV vs GIMP,边缘检测在openCV中失败

android - 跟踪代码管理器能否用于移动应用分析中的人口统计报告?

python - opencv/ python : Draw image over a webcam stream

java - 适用于 Android 的 Canny 边缘检测器——关于递归函数的 StackOverflow

matlab - 如何像matlab一样在opencv中检测角点?

opencv - 限制前景对象

image - 图像中的线检测

Android XML 资源值错误

java - android 秒表/计时器应用程序 - 当时间用完时切换回应用程序

java - 将 Access 2003 日期数字(整数)转换为 Java 日期