有没有一种方法可以对图像进行阈值处理,以便使用opencv尽可能多地忽略阴影?

时间:2019-03-30 12:24:28

标签: python opencv

我希望能够找到图像中可能有阴影也可能没有阴影的数字边界框。

enter image description here

为此,我将图像转换为灰度,然后转换为黑白,然后使用cv2.findCountours()找到数字

img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img = cv2.bitwise_not(img)
img = cv2.GaussianBlur(img,(3,3),0)
cv2.threshold(img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU,img)
contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)

但是在上一个示例中,我得到了黑白图像:

enter image description here

不允许轮廓查找功能正常工作。

有没有办法解决这个问题?

1 个答案:

答案 0 :(得分:1)

大津的门槛不是正确的选择。给定具有双峰分布的直方图,这是正确的。阅读更多here

在许多替代方案中,自适应阈值。

import cv2

img = cv2.imread("path/to/image")
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img = cv2.bitwise_not(img)
img = cv2.GaussianBlur(img, (3, 3), 0)
# _, img = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 401)
contours, _, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

您在这里必须提供自适应内核的块大小的值。我认为401在这里工作正常,但可能无法在您的其他图像上工作。

对于一个更简单的解决方案,以下是使用OpenCV Wrapper library的解决方案:

import cv2
import opencv_wrapper as cvw
import numpy as np

img = cv2.imread("masterproject/numbers.jpg")
img = cvw.bgr2gray(img)
img = ~img.astype(np.uint8)  # Not part of the library, this is numpy. Only works with uint8
img = cvw.blur_gaussian(img, 3)
img = cvw.threshold_adaptive(img, 401)
contours = cvw.find_external_contours(img)
cvw.draw_contours(img, contours, cvw.Color.GREEN)