如何使用 Python OpenCV 通过去除噪声来检测复选框?
How to detect checkboxes by removing noise using Python OpenCV?
我正在尝试识别图像中的复选框
已识别前 4 个,但未识别后 2 个。同时,我希望能够去掉胡椒粉以避免误报,因为其他文档的复选标记要小得多。我已经尝试了各种膨胀和内核大小,但我一直无法成功获得盒子。
我试过先膨胀再腐蚀
kernel = np.ones((2, 2), np.uint8)
image_dilat = cv2.dilate(image, kernel, iterations=1)
kernel = np.ones((4, 4), np.uint8)
image_erosion = cv2.erode(image_dilat2, kernel, iterations=1)
我也试过变形
kernel = np.ones((3, 3), np.uint8)
image = cv2.morphologyEx(image, cv2.MORPH_OPEN, kernel, iterations=1)
kernel = np.ones((3, 3), np.uint8)
image = cv2.morphologyEx(image, cv2.cv2.MORPH_CLOSE, , kernel, iterations=1)
如有任何建议,我们将不胜感激。
这是一种使用简单图像处理的潜在方法:
获取二值图像。加载图像,转换为灰度,Otsu的阈值。
去除噪声的小像素。找到轮廓并使用轮廓区域过滤过滤掉噪声。我们通过用黑色“绘制”轮廓来有效地去除噪声。
修复复选框墙。从这里我们创建一个水平和垂直修复内核,然后执行形态学关闭以修复复选框墙中的任何孔。
检测复选框。接下来在修复后的图像上找到轮廓,然后使用形状近似和纵横比过滤来过滤复选框轮廓。这个想法是复选框是一个正方形,应该具有大致相同的宽度和高度。
带噪点的二值图像->
去除了微小的噪点
修复了复选框墙 ->
检测到复选框
代码
import cv2
# Load image, convert to grayscale, Otsu's threshold
image = cv2.imread('1.png')
original = image.copy()
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
cv2.imshow('thresh before', thresh)
# Find contours and filter using contour area filtering to remove noise
cnts, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)[-2:]
AREA_THRESHOLD = 10
for c in cnts:
area = cv2.contourArea(c)
if area < AREA_THRESHOLD:
cv2.drawContours(thresh, [c], -1, 0, -1)
# Repair checkbox horizontal and vertical walls
repair_kernel1 = cv2.getStructuringElement(cv2.MORPH_RECT, (5,1))
repair = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, repair_kernel1, iterations=1)
repair_kernel2 = cv2.getStructuringElement(cv2.MORPH_RECT, (1,5))
repair = cv2.morphologyEx(repair, cv2.MORPH_CLOSE, repair_kernel2, iterations=1)
# Detect checkboxes using shape approximation and aspect ratio filtering
cnts, _ = cv2.findContours(repair, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2:]
for c in cnts:
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.05 * peri, True)
x,y,w,h = cv2.boundingRect(approx)
aspect_ratio = w / float(h)
if aspect_ratio > 0.9 and aspect_ratio < 1.1:
cv2.rectangle(original, (x, y), (x + w, y + h), (36,255,12), 3)
cv2.imshow('thresh', thresh)
cv2.imshow('repair', repair)
cv2.imshow('original', original)
cv2.waitKey()
注意:假设复选框是方形的,并且没有噪声重叠在复选框上。根据图像的不同,您可能需要添加另一层轮廓区域过滤以确保您不会得到误报。
我正在尝试识别图像中的复选框
已识别前 4 个,但未识别后 2 个。同时,我希望能够去掉胡椒粉以避免误报,因为其他文档的复选标记要小得多。我已经尝试了各种膨胀和内核大小,但我一直无法成功获得盒子。
我试过先膨胀再腐蚀
kernel = np.ones((2, 2), np.uint8)
image_dilat = cv2.dilate(image, kernel, iterations=1)
kernel = np.ones((4, 4), np.uint8)
image_erosion = cv2.erode(image_dilat2, kernel, iterations=1)
我也试过变形
kernel = np.ones((3, 3), np.uint8)
image = cv2.morphologyEx(image, cv2.MORPH_OPEN, kernel, iterations=1)
kernel = np.ones((3, 3), np.uint8)
image = cv2.morphologyEx(image, cv2.cv2.MORPH_CLOSE, , kernel, iterations=1)
如有任何建议,我们将不胜感激。
这是一种使用简单图像处理的潜在方法:
获取二值图像。加载图像,转换为灰度,Otsu的阈值。
去除噪声的小像素。找到轮廓并使用轮廓区域过滤过滤掉噪声。我们通过用黑色“绘制”轮廓来有效地去除噪声。
修复复选框墙。从这里我们创建一个水平和垂直修复内核,然后执行形态学关闭以修复复选框墙中的任何孔。
检测复选框。接下来在修复后的图像上找到轮廓,然后使用形状近似和纵横比过滤来过滤复选框轮廓。这个想法是复选框是一个正方形,应该具有大致相同的宽度和高度。
带噪点的二值图像->
去除了微小的噪点
修复了复选框墙 ->
检测到复选框
代码
import cv2
# Load image, convert to grayscale, Otsu's threshold
image = cv2.imread('1.png')
original = image.copy()
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
cv2.imshow('thresh before', thresh)
# Find contours and filter using contour area filtering to remove noise
cnts, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)[-2:]
AREA_THRESHOLD = 10
for c in cnts:
area = cv2.contourArea(c)
if area < AREA_THRESHOLD:
cv2.drawContours(thresh, [c], -1, 0, -1)
# Repair checkbox horizontal and vertical walls
repair_kernel1 = cv2.getStructuringElement(cv2.MORPH_RECT, (5,1))
repair = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, repair_kernel1, iterations=1)
repair_kernel2 = cv2.getStructuringElement(cv2.MORPH_RECT, (1,5))
repair = cv2.morphologyEx(repair, cv2.MORPH_CLOSE, repair_kernel2, iterations=1)
# Detect checkboxes using shape approximation and aspect ratio filtering
cnts, _ = cv2.findContours(repair, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2:]
for c in cnts:
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.05 * peri, True)
x,y,w,h = cv2.boundingRect(approx)
aspect_ratio = w / float(h)
if aspect_ratio > 0.9 and aspect_ratio < 1.1:
cv2.rectangle(original, (x, y), (x + w, y + h), (36,255,12), 3)
cv2.imshow('thresh', thresh)
cv2.imshow('repair', repair)
cv2.imshow('original', original)
cv2.waitKey()
注意:假设复选框是方形的,并且没有噪声重叠在复选框上。根据图像的不同,您可能需要添加另一层轮廓区域过滤以确保您不会得到误报。