利用条码的特征即白色背景,不同宽度的黑色条码进行图书条码提取
1、首先是读取图像,默认是(B,G,R)图像:
import cv2 as cv
#bgr通道顺序的彩色图像
origin_image = cv.imread("E:/PythonFiles/images/shu.bmp")
cv.imshow("image",origin_image)
#复制图片 保留原图
image = origin_image.copy()
image_background = origin_image.copy()
读取图像之后,根据后续的需要进行多次的图像复制,保留原图用于最后的操作。
2、获得图像的宽、高:
gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY)
h,w = gray.shape
#h,w,_ = image.shape
3、提取b、g、r三个通道:
#提取 三个通道
b = image[:,:,0];g=image[:,:,1];r=image[:,:,2]
4、根据背景特征获得图片
白色的BGR通道值为(255,255,255)。
遍历三个通道每一个像素点的值时,考虑到灯光、拍摄角度等外界影响因素,可以给该值与255的差设置一个范围,可以更好得获得想要的结果。
for i in range(h):
for j in range(w):
if (abs(b[i,j]-255)<50) and (abs(g[i,j]-255)<50) and (abs(r[i,j]-255)<50):
image[:,:,:][i,j] = 255
else:
image[:,:,:][i,j] = 0
此时获得为三通道的图片!
5、灰度、二值化处理
gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY)
_,binary = cv.threshold(gray,0,255,cv.THRESH_OTSU)
#cv.imshow("binary",binary)
6、形态学处理
可以更改结构元的大小,获得不同的处理效果。
#膨胀操作 进行连接
kernel = cv.getStructuringElement(cv.MORPH_RECT,(20,1))
binary = cv.dilate(binary,kernel)
#cv.imshow("dilate",binary)
#腐蚀操作 去噪
kernel = cv.getStructuringElement(cv.MORPH_RECT,(1,15))
binary = cv.erode(binary,kernel)
#cv.imshow("erode",binary)
膨胀效果:
腐蚀效果:
7、根据轮廓特征在原图上绘制最小包围矩形
找出轮廓后,遍历全部的轮廓并用最小矩形包围;然后根据条码宽、高的比例范围,得出最终结果;再利用返回的四个值(x、y、w、h)在原图上绘制出矩形框。
contours,_ = cv.findContours(binary,cv.RETR_EXTERNAL,cv.CHAIN_APPROX_SIMPLE)
for contour in contours:
rect = cv.boundingRect(contour)
x = rect[0]; y = rect[1]; w = rect[2]; h = rect[3]
if (w>1.2*h) and (w<1.6*h):
cv.rectangle(image_background,(x,y),(x+w,y+h),(0,0,255),3)
cv.imshow("jieguo",image_background)
8、提取条码图片
提取图片时,注意左上角坐标位置(x,y),图片宽高(w,h)与矩阵行列(r,c)三者的关系。
ROI = origin_image[y:y+h,x:x+w]
cv.imshow("ROI",ROI)
cv.waitKey()
cv.destroyAllWindows()
写在最后:
在该过程中是利用目标区域的颜色特征进行提取,根据这一方法,整个的提取流程也就可以用到其他方面,例如车牌的提取,感兴趣的可以试一下。