在文档图像中查找圆形对象(图章)Python OpenCV

Find circle objects (stamps) in document image Python OpenCV

我写了一个简单的代码来搜索文档中的圆圈(因为印章是圆形的)。

但由于图像质量差,打印轮廓模糊,opencv始终检测不到。我在 photoshop 中编辑了图片并增强了深色。我保存了图片并将其发送以进行处理。它帮助了我。 Opencv 已经识别出一个代表低质量打印的圆圈(高质量文档中不存在此类问题)。我的代码:

import numpy as np
import cv2

img = cv2.imread(r"C:\buh\doc.jpg")

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)


# I tried experimenting with bluer, but opencv doesn't see circles in this case
# blurred = cv2.bilateralFilter(gray.copy(), 15, 15, 15 )
# imS = cv2.resize(blurred, (960, 540))
# cv2.imshow('img', imS)
# cv2.waitKey(0)



minDist = 100
param1 = 30 #500
param2 = 100 #200 #smaller value-> more false circles
minRadius = 90
maxRadius = 200 #10

# docstring of HoughCircles: HoughCircles(image, method, dp, minDist[, circles[, param1[, param2[, minRadius[, maxRadius]]]]]) -> circles
circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1, minDist, param1=param1, param2=param2, minRadius=minRadius, maxRadius=maxRadius)

if circles is not None:
    circles = np.uint16(np.around(circles))
    for i in circles[0, :]:
        cv2.circle(img, (i[0], i[1]), i[2], (0, 255, 0), 2)

# Show result for testing:
imS = cv2.resize(img, (960, 540))
cv2.imshow('img', imS)
cv2.waitKey(0)

证件上的印章是照片上的圆圈:

很遗憾,我无法添加原始印章所在文件的照片,因为这是私人信息...

所以,我需要在尝试寻找圆圈之前增强照片中的黑色阴影。我怎样才能做到这一点?如果有人已经遇到过这个问题,我也会听取其他改善印章(邮票)轮廓的建议。

谢谢。

示例:

这是一个简单的方法:

  1. 获取二进制图像。加载图像,转换为grayscale, Gaussian blur, then Otsu's threshold

  2. 将小轮廓合并为一个大轮廓。我们使用 cv2.dilate 将圆圈合并为一个轮廓。

  3. 求外轮廓最后我们find external contours with the external cv2.RETR_EXTERNAL flag and cv2.drawContours()


图像管道的可视化

输入图片

二值图像的阈值

扩张

检测到的轮廓为绿色

代码

import cv2
import numpy as np

# Load image, grayscale, Gaussian blur, Otsus threshold, dilate
image = cv2.imread('3.PNG')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (3,3), 0)
thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
dilate = cv2.dilate(thresh, kernel, iterations=1)

# Find contours
cnts = cv2.findContours(dilate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    cv2.drawContours(image, [c], -1, (36,255,12), 3)

cv2.imshow('image', image)
cv2.imshow('dilate', dilate)
cv2.imshow('thresh', thresh)
cv2.waitKey()