我使用Python,但主要思路相同。
如果您直接对img2进行cvtColor:bgr-> gray,则必定失败。因为灰度难以区分区域:
![enter image description here](https://istack.dev59.com/H7iql.webp)
相关答案:
- 如何使用OpenCV检测图像中的彩色补丁?
- 在带颜色背景的图像上使用OpenCV进行边缘检测
- OpenCV C++/Obj-C:检测一张纸/方形检测
在您的图像中,纸张是白色
,而背景是彩色
。因此,最好在HSV color space
中检测纸张的Saturation(饱和度)
通道。关于HSV,请参见https://en.wikipedia.org/wiki/HSL_and_HSV#Saturation。
主要步骤:
- 读入
BGR
- 将图像从
bgr
转换为hsv
空间
- 阈值S通道
- 然后找到最大的外部轮廓(或者按照您喜欢的方式进行
Canny
、HoughLines
,我选择findContours
),近似得到角落。
这是第一次结果:
![enter image description here](https://istack.dev59.com/6pKxQ.webp)
这是第二个结果:
![enter image description here](https://istack.dev59.com/3Gubs.webp)
Python代码(Python 3.5 + OpenCV 3.3):
import cv2
import numpy as np
img = cv2.imread("test2.jpg")
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
h,s,v = cv2.split(hsv)
th, threshed = cv2.threshold(s, 50, 255, cv2.THRESH_BINARY_INV)
cnts = cv2.findContours(threshed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]
canvas = img.copy()
cnts = sorted(cnts, key = cv2.contourArea)
cnt = cnts[-1]
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)
cv2.imwrite("detected.png", canvas)
th
和threshold
是什么意思吗?代码如下:th, threshed = cv2.threshold(s, 50, 255, cv2.THRESH_BINARY_INV)
。我正在尝试将您的代码转换并在C++中测试,但不知道如何处理这一行代码。我查了一下,发现 threshold 函数只有一个 double 输出,但是您好像得到了两个输出(虽然我不懂 Python,只是猜测)。 - Hasanith
是返回的阈值;threshed
是二值化后的图像。函数原型:cv2.threshold(src, thresh, maxval, type[, dst]) -> retval, dst - Kinght 金