小白妹子一个,自学了一点点皮毛,有基础但不多,想通过喷码识别进行一下实战演练,欢迎指正(自尊心强,望轻喷)
目录
图像增强
1、直方图均指法
2、Otsu阈值处理
图像滤波
(1)均指滤波
(2)中值滤波
形态学处理
(1) 膨胀、腐蚀
(2)开运算、闭运算
首先在网上随便找了一张图片,进行一下预处理
(1)获取图像信息
import cv2
import matplotlib.pyplot as plt
plt.rcParams['font.family'] = 'SimHei' # matplotlib 绘图库正常使用中文黑体
# 读取图像信息
img0 = cv2.imread('D:/YJS/pmsy/1.png')
img1 = cv2.resize(img0, dsize=None, fx=0.5, fy=0.5)
h, w = img1.shape[:2]
print(h, w)
img2 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
cv2.namedWindow("W0")
cv2.imshow("W0", img1)
cv2.waitKey(delay=0)
(2)绘制直方图
#绘制直方图
hist0 = cv2.calcHist([img2], [0], None, [256], [0, 255])
plt.plot(hist0, label = "灰度图直方图", linestyle = "--", color = 'g')
plt.legend() #增加图例
plt.savefig("D:/YJS/pmsy/2.png") #保存直方图
plt.show()
(3)直方图均衡
#对图像进行局部直方图均衡化
clahe = cv2.createCLAHE (clipLimit = 2.0, tileGridSize=(10, 10)) #对图像进行分割,10*10
img4 = clahe.apply(img2) #进行直方图均衡化
cv2.namedWindow("W2")
cv2.imshow("W2", img4)
cv2.waitKey(delay = 0)
(4)总代码
import cv2
import matplotlib.pyplot as plt
plt.rcParams['font.family'] = 'SimHei' # matplotlib 绘图库正常使用中文黑体
# 读取图像信息
img0 = cv2.imread('D:/YJS/pmsy/1.png')
img1 = cv2.resize(img0, dsize=None, fx=0.5, fy=0.5)
h, w = img1.shape[:2]
print(h, w)
img2 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
cv2.namedWindow("W0")
cv2.imshow("W0", img1)
cv2.waitKey(delay=0)
#绘制直方图
hist0 = cv2.calcHist([img2], [0], None, [256], [0, 255])
plt.plot(hist0, label = "灰度图直方图", linestyle = "--", color = 'g')
plt.legend() #增加图例
plt.savefig("D:/YJS/pmsy/2.png") #保存直方图
plt.show()
#对图像进行局部直方图均衡化
clahe = cv2.createCLAHE (clipLimit = 2.0, tileGridSize=(10, 10)) #对图像进行分割,10*10
img4 = clahe.apply(img2) #进行直方图均衡化
cv2.namedWindow("W2")
cv2.imshow("W2", img4)
cv2.waitKey(delay = 0)
对图像像素进行遍历,找到最大的方差,并将其作为阈值,高于该阈值
的像素点均置为 0
import numpy as np
import cv2
import math
image = cv2.imread(r"D:/YJS/pmsy/1.png", 0)
rows, cols = image.shape[:2]
gray_hist = np.zeros([256], np.uint64)
for i in range(rows):
for j in range(cols):
gray_hist[image[i][j]] += 1
uniformGrayHist = gray_hist / float(rows * cols)
# 计算零阶累积距和一阶累积距
zeroCumuMomnet = np.zeros(256, np.float32)
oneCumuMomnet = np.zeros(256, np.float32)
for k in range(256):
if k == 0:
zeroCumuMomnet[k] = uniformGrayHist[0]
oneCumuMomnet[k] = (k) * uniformGrayHist[0]
else:
zeroCumuMomnet[k] = zeroCumuMomnet[k - 1] + uniformGrayHist[k]
oneCumuMomnet[k] = oneCumuMomnet[k - 1] + k * uniformGrayHist[k]
# 计算类间方差
variance = np.zeros(256, np.float32)
for k in range(255):
if zeroCumuMomnet[k] == 0 or zeroCumuMomnet[k] == 1:
variance[k] = 0
else:
variance[k] = math.pow(oneCumuMomnet[255] * zeroCumuMomnet[k] - oneCumuMomnet[k], 2) / (
zeroCumuMomnet[k] * (1.0 - zeroCumuMomnet[k]))
# 找到阈值
threshLoc = np.where(variance[0:255] == np.max(variance[0:255]))
thresh = threshLoc[0][0]
# 阈值处理
threshold = np.copy(image)
threshold[threshold > thresh-35] = 255
threshold[threshold <= thresh] = 0
cv2.imshow("test", threshold)
cv2.waitKey(0)
效果图
目前常见的噪声有椒盐噪声、高斯噪声、斑点噪声,当前常用的滤波算法分为线性滤波与非线性滤波,选取线性滤波与非线性滤波算法中效果较好的均值滤波与中值滤波进行对带噪声的图像进行处理。
指在图像上对目标像素给一个模板,该模板包括了其周围的临近像素(以目标像素为中心的周围8个像素,构成一个滤波模板,即去掉目标像素本身),再用模板中的全体像素的平均值来代替原来像素值。
#均值滤波
blur = cv2.blur(threshold,(3,3))
cv2.imshow("blur",blur)
cv2.waitKey()
将每一像素点的灰度值设置为该点某邻域窗口内的所有像素点灰度值的中值。
#中值滤波
median= cv2.medianBlur(threshold,3)
cv2.imshow("median",median)
cv2.waitKey()
更好进行字符分割字符识别,需对字符断续的情况做数学形态学处理。膨胀是将与字符相接触的背景点合并到字符里去,使部分背景点变为目标,以此来填补字符间断或空洞的地方。腐蚀是将部分目标像素点变为背景,其可以用切断字符间存在粘连的情况,此外也能消除图像中噪点。
对喷码字符进行加粗去掉字符间断部分的操作为膨胀。对喷码字符进行去除字符粘连部分与去除小噪点的操作为腐蚀。
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3, 3))
eroded = cv2.erode(median,kernel) #腐蚀图像
dilated = cv2.dilate(median,kernel) #膨胀图像
cv2.imshow("Eroded Image",eroded) #显示腐蚀后的图像
cv2.imshow("Dilated Image",dilated) #显示膨胀后的图像
#NumPy定义的结构元素
NpKernel = np.uint8(np.ones((3,3)))
Nperoded = cv2.erode(median,NpKernel) #腐蚀图像
cv2.imshow("Eroded by NumPy kernel",Nperoded) #显示腐蚀后的图像
cv2.waitKey(0)
cv2.destroyAllWindows()
开运算是对喷码字符图像先腐蚀后膨胀,开运算对喷码字符轮廓有平滑作用、
断开一些粘连的地方、去掉小的毛刺等特点。
闭运算是对喷码字符图像先膨胀后腐蚀,闭运算对喷码字符边缘也有平滑作用,其
有去掉字符内部一些小空洞,连接字符间断的地方等特点。
gray_res = cv2.resize(median,None,fx=2,fy=2,
interpolation = cv2.INTER_CUBIC) #图形太大了缩小一点
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3,3)) #定义矩形结构元素
closed1 = cv2.morphologyEx(gray_res, cv2.MORPH_CLOSE, kernel,iterations=1) #闭运算1
closed2 = cv2.morphologyEx(gray_res, cv2.MORPH_CLOSE, kernel,iterations=3) #闭运算2
opened1 = cv2.morphologyEx(gray_res, cv2.MORPH_OPEN, kernel,iterations=1) #开运算1
opened2 = cv2.morphologyEx(gray_res, cv2.MORPH_OPEN, kernel,iterations=3) #开运算2
gradient = cv2.morphologyEx(gray_res, cv2.MORPH_GRADIENT, kernel) #梯度
#显示如下腐蚀后的图像
cv2.imshow("gray_res", gray_res)
cv2.imshow("Close1",closed1)
cv2.imshow("Close2",closed2)
cv2.imshow("Open1", opened1)
cv2.imshow("Open2", opened2)
cv2.imshow("gradient", gradient)
cv2.waitKey(0)
cv2.destroyAllWindows()