I have a hundreds of ID card images which some of them provided below:
(Disclaimer: I downloaded the images from the Web, all rights (if exist) belong to their respective authors)
可以看出,它们在亮度、视角和距离、卡片方向方面都有所不同。我试图仅提取矩形卡片区域并将其保存为新图像。为了实现这一目标,我开始知道我必须将图像转换为灰度图像并应用一些阈值方法。然后,将 cv2.findCountours() 应用于阈值图像以获得多个向量点。
我尝试了很多方法并开始使用 cv2.adaptiveThreshold() ,因为据说它找到阈值(因为,我无法手动设置每个图像的阈值)。但是,当我将其应用于图像时,我没有得到我想要的。例如:
My desired output should look like this:
似乎它还包括仿射变换以使卡片区域(奥巴马案例)正确,但我发现它很难理解。如果可能的话,我会进一步提取并单独保存图像。
有没有其他方法或算法可以达到我想要的效果?应考虑不同的照明条件和卡片方向。鉴于只有一张矩形身份证,我期待一种万能的解决方案。请用您认为有帮助的任何内容来指导我完成此操作。
请注意,我不能使用 CNN 作为目标检测器,它必须基于纯粹的图像处理。
谢谢。
EDIT:上述结果的代码非常简单:
image = cv2.imread(args["image"])
gray_img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh_img = cv2.adaptiveThreshold(gray_img,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV,51,9)
cnts = cv2.findContours(thresh_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
area_treshold = 1000
for cnt in cnts:
if cv2.contourArea(cnt) > area_treshold:
x,y,w,h = cv2.boundingRect(cnt)
print(x,y,w,h)
cv2.rectangle(image, (x, y), (x + w, y + h), (36,255,12), 3)
resize = ResizeWithAspectRatio(image, width=640)
cv2.imshow("image", resize)
cv2.waitKey()
EDIT 2:
I provide the gradient magnitude images below:
这是否意味着我必须同时涵盖低强度值和高强度值?因为底部的身份证边缘几乎看不出来。