一、问题
女朋友的大作业第一题选自于robomaster的题目,机器人需要通过摄像头先识别数码管区域的 5 个密码数字,然后控制射击机构依照顺序用塑料子弹击打九宫格区域内对应的数字。因此需要对数码管进行识别。下面是题目要求。
二、分析
对于数码管的识别,可以利用简单的穿线法。
图像的分割可以利用opencv中自带的函数。
将图片转换为HSV格式可以更好分割。
三、代码
1.转换成hsv格式,利用hsv格式进行筛选,其中筛选参数lower,upper需要根据自己情况来设定。
hsv = cv2.cvtColor(image_org, cv2.COLOR_BGR2HSV)
lower = np.array([h0, s0, v0])
upper = np.array([h1, s1, v1])
image_gray = cv2.inRange(hsv, lower, upper)
2.对hsv图像进行高斯滤波,二值化处理
image_gray = cv2.GaussianBlur(image_gray, (7, 7), 0)
ret, image_bin = cv2.threshold(image_gray, 200, 255, cv2.THRESH_BINARY)
3.进行形态学处理,利用闭运算处理。
cv2.morphologyEx(image_bin, cv2.MORPH_CLOSE, kernel2, iterations=1)
4. 运用cv2.findContours得到边界,下图是可视化边界的样图。
5.对上述的得到的边框进行位置以及大小的筛选,进行穿线法识别,下面是穿线法的代码。
def TubeIdentification(filename, num, image):
tube = 0
tubo_roi = [
[image.shape[0] * 0/3, image.shape[0] * 1/3, image.shape[1] * 1/2,
image.shape[1] * 1/2],
[image.shape[0] * 1/3, image.shape[0] * 1/3, image.shape[1] * 2/3,
image.shape[1] - 1 ],
[image.shape[0] * 2/3, image.shape[0] * 2/3, image.shape[1] * 2/3,
image.shape[1] - 1 ],
[image.shape[0] * 2/3, image.shape[0] -1 , image.shape[1] * 1/2,
image.shape[1] * 1/2],
[image.shape[0] * 2/3, image.shape[0] * 2/3, image.shape[1] * 0/3,
image.shape[1] * 1/3],
[image.shape[0] * 1/3, image.shape[0] * 1/3, image.shape[1] * 0/3,
image.shape[1] * 1/3],
[image.shape[0] * 1/3, image.shape[0] * 2/3, image.shape[1] * 1/2,
image.shape[1] * 1/2]]
i = 0
while(i < 7):
if(Iswhite(image, int(tubo_roi[i][0]), int(tubo_roi[i][1]),
int(tubo_roi[i][2]),int(tubo_roi[i][3]))):
tube = tube + pow(2,i)
cv2.line(image, ( int(tubo_roi[i][3]),int(tubo_roi[i][1])),
(int(tubo_roi[i][2]), int(tubo_roi[i][0])),
(255,0,0), 1)
i += 1
if(tube==63):
onenumber = 0
elif(tube==6):
onenumber = 1
elif(tube==91):
onenumber = 2
elif(tube==79):
onenumber = 3
elif(tube==102 or tube==110):
#110是因为有干扰情况
onenumber = 4
elif(tube==109):
onenumber = 5
elif(tube==125):
onenumber = 6
elif(tube==7):
onenumber = 7
elif(tube==127):
onenumber = 8
elif(tube==103):
onenumber = 9
else:
onenumber = -1
cv2.imwrite(filename + '_' + str(num) + '_' + str(onenumber) + '.png', image)
return onenumber
def Iswhite(image, row_start, row_end, col_start, col_end):
white_num = 0
j=row_start
i=col_start
while(j <= row_end):
while(i <= col_end):
if(image[j][i] == 255):
white_num+=1
i+=1
j+=1
i=col_start
#print('white num is',white_num)
if(white_num >= 5):
return True
else:
return False
6.最终得到结果(未按顺序输出)
四、改进
可以利用神经网络来做,这样准确率很高,鲁棒性强。但是需要自己做数据集,麻烦。
五、参考
https://blog.csdn.net/zong596568821xp/article/details/85098590
https://blog.csdn.net/km2km2km/article/details/94778305
https://blog.csdn.net/sandalphon4869/article/details/95398033