答案 0 :(得分:2)
以下是使用Python OpenCV清理图像的两种方法
方法1:numpy阈值化
由于垂直线,水平线和背景为红色,因此我们可以利用这一点,并使用Numpy阈值将所有高于阈值的红色像素更改为白色。
import cv2
import numpy as np
image = cv2.imread('1.jpg')
image[np.where((image > [0,0,105]).all(axis=2))] = [255,255,255]
cv2.imshow('image', image)
cv2.waitKey()
方法2:传统图像处理
对于更通用的方法,如果线条不是红色,我们可以使用简单的图像处理技术来清洁图像。要删除垂直和水平线,我们可以构造特殊的内核以隔离线,并使用屏蔽和按位运算将其删除。删除线条后,我们可以使用阈值处理,形态学运算和轮廓过滤来删除红色背景。这是该过程的可视化
首先,我们构造垂直和水平内核,然后cv2.morphologyEx()
来检测线。从这里开始,我们分别得到了水平线和垂直线的各个遮罩,然后按位排列-或两个遮罩获得了要删除所有线条的遮罩。接下来,我们按位-或与原始图像一起删除所有行
现在删除了线条,我们可以继续删除红色背景。我们阈值获取二进制图像并执行形态学操作以平滑文本
仍然有一些小点,因此要去除它们,我们会找到轮廓并使用最小阈值区域进行滤波以去除小噪声
最后,我们反转图像以获得结果
import cv2
image = cv2.imread('1.jpg')
# Remove vertical and horizontal lines
kernel_vertical = cv2.getStructuringElement(cv2.MORPH_RECT, (1,50))
temp1 = 255 - cv2.morphologyEx(image, cv2.MORPH_CLOSE, kernel_vertical)
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (50,1))
temp2 = 255 - cv2.morphologyEx(image, cv2.MORPH_CLOSE, horizontal_kernel)
temp3 = cv2.add(temp1, temp2)
removed = cv2.add(temp3, image)
# Threshold and perform morphological operations
gray = cv2.cvtColor(removed, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 180, 255, cv2.THRESH_BINARY_INV)[1]
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (2,2))
close = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, iterations=1)
# Filter using contour area and remove small noise
cnts = cv2.findContours(close, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
area = cv2.contourArea(c)
if area < 10:
cv2.drawContours(close, [c], -1, (0,0,0), -1)
final = 255 - close
cv2.imshow('removed', removed)
cv2.imshow('thresh', thresh)
cv2.imshow('close', close)
cv2.imshow('final', final)
cv2.waitKey()