利用python-OpenCV对成像有瑕疵的图片进行检测
任务
利用路由器将海康工业相机成像传递给工控机的过程中,部分图像出现成行的绿线,如下图所示,用python-OpenCV进行处理,追求在最短的时间内检测出有瑕疵的图片进行排除。
图1
使用halcon18进行协助,按住CTRL,光标会显示该像素点的坐标以及gb,很方便发现绿线的rgb分别是(0,136,0)
思路:通道分离》二值化》遍历像素点的像素,找出符合条件像素,就进行累加》遍历完一行的像素点的像素值,对累加值与图片宽进行比较,判断是否是绿线。
第一次程序
但是缺点十分明显,图片大,600万像素,遍历十分耗时,对图片的长宽都进行了缩放,再进行处理,缩小5倍,代码如下
1 import cv2 as cv 2 import time 3 4 startTime = time.time() 5 img = cv.imread(r'C:\Users\Administrator\Desktop\2\07.bmp') 6 7 imgInfo = img.shape 8 height = imgInfo[0] 9 width = imgInfo[1] 10 11 dstHeight = int(height*0.2) 12 dstWdth = int(width*0.2) 13 dst = cv.resize(img,(dstWdth,dstHeight)) 14 # cv.imshow('dst',dst) 15 16 b,g,r = cv.split(dst) 17 # cv.imshow('green',g) 18 19 ret1, thresh1 = cv.threshold(g,135,255,cv.THRESH_BINARY_INV) 20 # cv.imshow('th',thresh1) 21 h,w = thresh1.shape 22 23 num1 = 0 24 s = 0 25 for i in range(h): 26 n = num1/w 27 if n >= 0.2: # 排除噪音干扰 28 s += 1 29 num1 = 0 30 for j in range(w): 31 if thresh1[i,j] == 0: 32 num1 += 1 33 print('总共有 '+str(s) +' 条绿线') 34 35 endTime = time.time() 36 uesTime = endTime-startTime 37 print('总共花了 '+str(uesTime) +' 秒') 38 39 cv.waitKey(0) 40 cv.destroyAllWindows()
结果:只有4条线,完全不符合实际结果
不对图像进行缩放
仅仅对一张图片进行检测就耗时太久了,不符合实际项目要求。
第二次程序
解决方法:同时对图像的行与列进行压缩会使绿线的航速变少,为了减少程序时间,对图像进行列(宽)压缩,行(高)不变。
1 import cv2 as cv 2 import time 3 4 startTime = time.time() 5 img = cv.imread(r'C:\Users\Administrator\Desktop\2\07.bmp') 6 7 imgInfo = img.shape 8 height = imgInfo[0] 9 width = imgInfo[1] 10 11 dstHeight = int(height*1) 12 dstWdth = int(width*0.1) 13 dst = cv.resize(img,(dstWdth,dstHeight)) 14 # cv.imshow('dst',dst) 15 16 b,g,r = cv.split(dst) 17 # cv.imshow('green',g) 18 19 ret1, thresh1 = cv.threshold(g,135,255,cv.THRESH_BINARY_INV) 20 # cv.imshow('th',thresh1) 21 h,w = thresh1.shape 22 23 num1 = 0 24 s = 0 25 for i in range(h): 26 n = num1/w 27 if n >= 0.2: # 排除噪音干扰 28 s += 1 29 num1 = 0 30 for j in range(w): 31 if thresh1[i,j] == 0: 32 num1 += 1 33 print('总共有 '+str(s) +' 条绿线') 34 35 endTime = time.time() 36 uesTime = endTime-startTime 37 print('总共花了 '+str(uesTime) +' 秒') 38 39 cv.waitKey(0) 40 cv.destroyAllWindows()
二值化处理图像效果如下(缩放为0.2,0.2):
将宽压缩了十倍,绿线检测数量不变,时间直接减少将近十倍。对二十张图像进行检测,这种算法对目标缺陷检测无干扰,但能有效缩减时间。但是还是存在噪音干扰。
最后程序
增加了图片不同通道图片的像素相减,代替了单纯的二值化处理
1 import cv2 as cv 2 import time 3 4 startTime = time.time() 5 38 endTime = time.time() 39 uesTime = endTime-startTime 40 print('总共花了 '+str(uesTime) +' 秒') 41 42 43 cv.waitKey(0) 44 cv.destroyAllWindows()
通道相减处理图像效果如下(缩放为0.2,0.2):
时间无太大变化,阈值取值更加简单明确,绿线检测数量一样。