使用扫描仪伪影仅从图像中提取特定颜色

Extracting only specific color from image with scanner artifacts

我有以下问题:

我只想从扫描图像中提取蓝色笔的颜色,这些扫描图像还包含白色页面背景上的灰度和黑色打印区域。

我可以忽略任何类型的灰度(非彩色)像素值,只保留蓝色部分,图像上不会有除蓝色以外的任何主色。

这听起来很简单,但问题是通过扫描过程,整个图像包含彩色像素,包括蓝色像素,甚至灰度或黑色部分,所以我不知道如何去做隔离这些部分并只保留蓝色部分,这是一个特写来展示我的意思:

这是一张图片,供参考:

我希望输出是一张新图像,只包含用蓝笔绘制/书写的部分,在本例中是刺猬/眼睛的绘图。

所以我尝试使用以下代码隔离图像中蓝色的 HSV 范围:

img = cv.imread("./data/scan_611a720bcd70bafe7beb502d.jpg")
img_hsv = cv.cvtColor(img, cv.COLOR_BGR2HSV)

# accepted color range for blue pen
lower_blue = np.array([90, 35, 140])
upper_blue = np.array([150, 255, 255])

# preparing the mask to overlay
mask = cv.inRange(img_hsv, lower_blue, upper_blue)
inverted_mask = cv.bitwise_not(mask)
mask_blur = cv.GaussianBlur(inverted_mask, (5, 5), 0)
ret, mask_thresh = cv.threshold(mask_blur, 0, 255, cv.THRESH_BINARY + cv.THRESH_OTSU)

# The black region in the mask has the value of 0,
# so when multiplied with original image removes all non-blue regions
result = cv.bitwise_and(img, img, mask=mask)

cv.imshow("Result", mask_thresh)
k = cv.waitKey(0)

然而结果是这样的:

图片的许多黑色部分(例如云图像)没有被删除,因为如前所述,由于扫描过程,它们包含蓝色/彩色像素。

是否有任何方法可以干净地隔离图像的那些蓝色部分,即使存在这些伪像? 该解决方案需要适用于像这样的任何类型的图像,给出的图像只是一个示例,但如前所述,除了 grey/black 区域之外,唯一存在的颜色是蓝色笔。

也许可以尝试相反的方法——先搜索黑色部分,然后在这个黑色蒙版周围做一些腐蚀,并在搜索蓝色之前移除它周围的所有部分。云中的“主要”颜色仍然是黑色,因此您可以尝试解决这个问题。

您应该重新调整扫描件的颜色平面。那么你至少摆脱了那些彩色条纹。我建议扫描 sheet 方格纸进行校准。

这是使用 OpenCV 的 findTransformECC.

完成的

可在此处找到完整示例:

下面是对齐问题中给出的图片的颜色平面的具体代码:

https://gist.github.com/crackwitz/b8867b46f320eae17f4b2684416c79ea

(它所做的只是分割颜色平面,调用findTransformECCwarpPerspective,合并颜色平面)