问题描述
我正在尝试对文档的图片进行OCR,而我目前的做法是
- 读取灰度图像
- 将其阈值二等化
- 将透视图沿从
cv2.findContours()
获得的轮廓包裹
如果图像没有阴影,上述方法效果很好。现在,我想获得阴影图片的轮廓。我的第一个尝试是将cv2.adaptiveThreshold
用于步骤2。自适应阈值成功地减弱了阴影,但是所得的图像失去了纸张和背景之间的对比度。这使得cv2无法找到纸张的轮廓。所以我需要使用其他方法去除阴影。
有什么方法可以消除保持背景颜色的阴影?
在此提供参考的是我正在使用各种方法处理的示例图片。从左开始,我做了
- 灰度
- 阈值
- 自适应阈值
- 规范化
请注意,实际上我有一个临时解决方案,专门针对图片,即分别处理带有阴影的图片部分。但是,这并不是阴影图像的通用解决方案,因为其性能取决于阴影的大小,形状和位置,因此请使用其他方法。
这是原始图片。
解决方法
这是Python / OpenCV中使用除法归一化的一种方法,还可以选择进行锐化和/或阈值化。
输入:
import cv2
import numpy as np
import skimage.filters as filters
# read the image
img = cv2.imread('receipt.jpg')
# convert to gray
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# blur
smooth = cv2.GaussianBlur(gray,(95,95),0)
# divide gray by morphology image
division = cv2.divide(gray,smooth,scale=255)
# sharpen using unsharp masking
sharp = filters.unsharp_mask(division,radius=1.5,amount=1.5,multichannel=False,preserve_range=False)
sharp = (255*sharp).clip(0,255).astype(np.uint8)
# threshold
thresh = cv2.threshold(sharp,255,cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
# save results
cv2.imwrite('receipt_division.png',division)
cv2.imwrite('receipt_division_sharp.png',sharp)
cv2.imwrite('receipt_division_thresh.png',thresh)
# show results
cv2.imshow('smooth',smooth)
cv2.imshow('division',division)
cv2.imshow('sharp',sharp)
cv2.imshow('thresh',thresh)
cv2.waitKey(0)
cv2.destroyAllWindows()
部门:
锐化:
阈值: