识别停止线和测距三个功能
发布时间:2025-06-24 18:58:58 作者:北方职教升学中心 阅读量:442
也就是说,OpenMV同时实现了循迹、色块中心点等等,最后拍拍脑袋,直接用色块的下边沿y值,再根据实际测量设置参数k,调节成距离值。
2.通过三个色块中心点的cx和cy值计算当前轨迹相对小车的偏移角,以便于PID计算。要求:(20 分)
(1) 领头小车的平均速度误差不大于 10%;
(2) 领头小车达到“等停指示”点停车,停车位置准确,误差不大于 5cm;
(3) 在“等停指示”处停车时间为 5s,误差不超过 1s。LAB色域中B的负数那边就是蓝色。

OpenMV的色块识别有很多细节方面,可以更加巧妙的利用,若有时间可以整理出一篇blog记录一下
defcar_run():centroid_sum =0#利用颜色识别分别寻找三个矩形区域内的线段forr inROIS:blobs =img.find_blobs(GRAYSCALE_THRESHOLD,roi=r[0:4],merge=True)# r[0:4] is roi tuple.#找到视野中的线,merge=true,将找到的图像区域合并成一个#目标区域找到色块ifblobs:# Find the index of the blob with the most pixels.most_pixels =0largest_blob =0fori inrange(len(blobs)):#目标区域找到的颜色块(线段块)可能不止一个,找到最大的一个,作为本区域内的目标直线ifblobs[i].pixels()>most_pixels:most_pixels =blobs[i].pixels()#merged_blobs[i][4]是这个颜色块的像素总数,如果此颜色块像素总数大于 #most_pixels,则把本区域作为像素总数最大的颜色块。
加上MSP的代码:https://download.csdn.net/download/weixin_52385589/86393773?spm=1001.2014.3001.5503importsensor,image,time,mathfrompyb importUART,LEDLED(3).on()uart =UART(3,115200,timeout_char=1000)u_start=bytearray([0xb3,0xb3])u_over=bytearray([0x0d,0x0a])GRAYSCALE_THRESHOLD =[(-125,20,-21,13,-28,14)]#巡线的阈值ROIS =[(0,90,160,20,0.7),(0,050,160,20,0.4),(0,000,160,20,0.05)]#三个区域weight_sum =0range_stop=[390,190,100]#停止线像素最小值range_wait=[60,40,0]#等待停止线像素最小值forr inROIS:weight_sum +=r[4]#摄像头设置sensor.reset()sensor.set_contrast(1)sensor.set_pixformat(sensor.RGB565)sensor.set_framesize(sensor.QQVGA)sensor.skip_frames(30)sensor.set_auto_gain(False)sensor.set_auto_whitebal(False)clock =time.clock()sensor.set_vflip(True)sensor.set_hmirror(True)thresholds=[(-100,72,-128,-16,-128,127)]#该阈值用于测距#寻找两个最大的色块,ID存在max_ID中,便于调用deffind_max(blobs):max_size=[0,0]max_ID=[-1,-1]fori inrange(len(blobs)):ifblobs[i].pixels()>max_size[0]:max_ID[1]=max_ID[0]max_size[1]=max_size[0]max_ID[0]=i max_size[0]=blobs[i].pixels()elifblobs[i].pixels()>max_size[1]:max_ID[1]=i max_size[1]=blobs[i].pixels()returnmax_IDdefcar_run():centroid_sum =[0,0]left_center=[-1,-1,-1]#存放左边色块的中心cx值用于计算左边的偏移角right_center=[-1,-1,-1]#存放右边色块的中心cx值用于计算右边的偏移角flag_cross=0#是否有分岔口flag_Stop=0#停止标志flag_Wait=[0,0]#等待停止标志forr inrange(3):#三个区域分别寻找色块blobs =img.find_blobs(GRAYSCALE_THRESHOLD,roi=ROIS[r][0:4],merge=True,area_threshold=100,margin=3)ifblobs:max_ID=[-1,-1]max_ID=find_max(blobs)#找最大色块img.draw_rectangle(blobs[max_ID[0]].rect())img.draw_cross(blobs[max_ID[0]].cx(),blobs[max_ID[0]].cy())ifmax_ID[1]!=-1:#如果有两个色块,即有分岔口,分成左边右边存入数组img.draw_rectangle(blobs[max_ID[1]].rect())flag_cross=1img.draw_cross(blobs[max_ID[1]].cx(),blobs[max_ID[1]].cy())ifblobs[max_ID[0]].cx()<blobs[max_ID[1]].cx():left_center[r]=blobs[max_ID[0]].cx()right_center[r]=blobs[max_ID[1]].cx()else:left_center[r]=blobs[max_ID[1]].cx()right_center[r]=blobs[max_ID[0]].cx()else:#只有一个色块#print(blobs[max_ID[0]].pixels(),blobs[max_ID[0]].w())ifflag_cross==0:#没有分岔口,进行判断停止线ifblobs[max_ID[0]].pixels()>range_stop[r]:flag_Stop=r+1ifblobs[max_ID[0]].w()>range_wait[r]:flag_Wait[0]=flag_Wait[0]+1left_center[r]=right_center[r]=blobs[max_ID[0]].cx()centroid_sum[0]+=left_center[r]*ROIS[r][4]#乘权值centroid_sum[1]+=right_center[r]*ROIS[r][4]center_pos =[0,0]center_pos[0]=(centroid_sum[0]/weight_sum)center_pos[1]=(centroid_sum[1]/weight_sum)ifflag_Wait[0]==2:flag_Wait[1]=1deflection_angle =[0,0]deflection_angle[0]=-math.atan((center_pos[0]-80)/60)#计算角度deflection_angle[1]=-math.atan((center_pos[1]-80)/60)deflection_angle[0]=math.degrees(deflection_angle[0])#弧度制换成角度制deflection_angle[1]=math.degrees(deflection_angle[1])ifcenter_pos[0]==center_pos[1]==0:deflection_angle[1]=deflection_angle[0]=0A=[int(deflection_angle[0])+90,int(deflection_angle[1])+90,flag_Stop,flag_Wait[1]]returnAdefdegrees(radians):return(180*radians)/math.pik=1while(True):times=0clock.tick()img =sensor.snapshot().lens_corr(strength =1.8,zoom =1.0)#不断拍照,进行鱼眼校正row_data=[0,0,0,0,0]row_data[0],row_data[1],row_data[3],row_data[4]=car_run()blobs=img.find_blobs([(30,60,-30,-10,-25,-12)],pixels_threshold=300,area_threshold=300,merge=False)max_size=0ifblobs:forblob inblobs:ifblob.cy()+0.5*blob.h()>max_size:img.draw_rectangle(blob.rect(),(255,0,0))max_size =blob.cy()+0.5*blob.h()row_data[2]=int(k*(120-max_size))#计算距离,k可调print(row_data)#传输数据给单片机uart_buf =bytearray(row_data)uart.write(u_start)uart.write(uart_buf)uart.write(u_over)