声明:本篇主要代码参考自这篇文章:https://blog.csdn.net/m0_38024433/article/details/78650024
在此基础上作了一些修改。
import cv2 as cv
img = cv.imread('test.png', 1)
cv.imshow('origin', img)
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) # 灰度化
cv.imshow('gray', gray)
blur = cv.bilateralFilter(gray, 13, 15, 15) # 双边滤波
cv.imshow('blur', blur)
ret, binary = cv.threshold(blur, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU) # 二值化
cv.imshow('binary', binary)
# 分割字符
white = [] # 记录每一列白色像素总和
black = [] # 记录每一列黑色像素总和
height = binary.shape[0]
width = binary.shape[1]
white_max = 0
black_max = 0
# 计算每一列的黑白色像素总和
for i in range(width): # 按列遍历
s = 0 # 这一列白色总数
t = 0 # 这一列黑色总数
for j in range(height): # 按行遍历
if binary[j][i] == 255: # 白色像素点
s += 1
if binary[j][i] == 0: # 黑色像素点
t += 1
white_max = max(white_max, s)
black_max = max(black_max, t)
white.append(s)
black.append(t)
print(s)
print(t)
print('white_len:',len(white)) # 273
print('black_len:',len(black)) # 273
print('black_max = ',black_max) # 88
print('white_max = ',white_max) # 80
arg = False # False表示白底黑字;True表示黑底白字,按黑底白字方式切割
if black_max > white_max:
arg = True
# 分割图像
def find_end(start_):
end_ = start_ + 1
for m in range(start_ + 1, width - 1):
if (black[m] if arg else white[m]) > (0.95 * black_max if arg else 0.95 * white_max): # 0.95这个参数请多调整,对应下面的0.05
end_ = m
break
return end_
n = 1
start = 1
end = 2
i = 0
while n < width - 2:
n += 1
if (white[n] if arg else black[n]) > (0.05 * white_max if arg else 0.05 * black_max):
# 上面这些判断用来辨别是白底黑字还是黑底白字
# 0.05这个参数请多调整,对应上面的0.95
start = n
end = find_end(start)
n = end
if end - start > 5:
cj = binary[1:height, start:end]
i = i + 1
# cv.imshow('caijian', cj) # 可以选择是否显示结果
cv.imwrite(str(i)+'.jpg',cj) # 自动保存分割结果
if cv.waitKey(0) & 0xFF == 27:
cv.destroyAllWindows()
测试的图片:
test.png:
切割结果: