序文
著者は電気コンペに参加するのは初めてで、OpenMV に連絡するのも初めてで、数日間の学習を経て、ガレージとサイドライン検査のための視覚認識スキームを完成させました。 OpenMV を使用している他の友人にアイデアを提供してください。
結果を示す
ガレージ T 字路の識別:
ラインパトロール効果のスクリーンショットを撮り忘れましたが、コード内にあるので、興味のある友達は試してみてください。
アイデアを特定する
このプロジェクトでは主にOpenMVが提供するfind_blobs()関数を使用していますが、具体的な使用方法については公式チュートリアルを参照してください。フィールド上の黒い線で区切られた白い領域
を識別することにより、車庫の継ぎ目を簡単かつ効果的に識別できます。まず、画像内のすべてのカラーブロックを抽出し、画像を上下に均等に分割し、上下のカラーブロックを分類する。ガレージの分岐点に到達していない場合は、画面内に黒い線が1本だけ表示され、画面が上下2つに分割されます。画面内にガレージの継ぎ目が表示されると、画面が上部 2 つと下部 1 つに分割され、上下のカラーブロックの数を検出することで、ガレージの継ぎ目を簡単かつ効果的に識別できます。ガレージを通過した継ぎ目の数を数え、現在の継ぎ目の座標で校正することで、カートの正確な現在位置を確認できます。線検査部では、画面左側の狭い部分からロイを抽出すると同時に黒線カラーブロックを抽出し、その中心座標をシングルチップマイコンに返して終了させます。ループを使用して、走行中にガレージからの距離が一定に保たれるようにします。
完全なコード
import sensor, image, time, pyb
# 串口通信
uart = pyb.UART(3,115200,timeout_char = 1000)#串口初始化
threshold1 = (80, 200)#阈值
threshold2 = (0, 40)#阈值
sensor.reset()
sensor.set_pixformat(sensor.GRAYSCALE)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 2000)
sensor.set_auto_gain(False) # 关闭增益(色块识别时必须要关)
sensor.set_auto_whitebal(False) # 关闭白平衡
clock = time.clock()#定义时钟对象clock
# 串口输出变量
out_str1 = ''
T_time = 0
real_time = 0
now_T = False
line_roi = (0,50,40,240)
while(True):
#clock.tick()#返回以毫秒计的通电后的运行时间。
img = sensor.snapshot().lens_corr(1.5)
blob_up = []
blob_down = []
largest_blob = []
line_blob=img.find_blobs([threshold2], roi=line_roi, merge=True,pixels_area=50)
if line_blob:#如果找到了颜色块
# Find the blob with the most pixels.
largest_blob.append(max(line_blob, key=lambda b: b.pixels()))
# 绘制色块边缘会影响到之后的识别,调参结束请注释
img.draw_rectangle(largest_blob[0].rect())#画矩形框 blob.rect() ---> 返回一个矩形元组(可当作roi区域)
img.draw_cross(largest_blob[0].cx(), largest_blob[0].cy())#画十字 blob.cx(), blob.cy() --->返回中心点x和y坐标
#img.find_blobs()查找图像中所有色块,并返回包含每个色块的色块对象列表
for blob in img.find_blobs([threshold1], pixels_threshold=200, area_threshold=200, merge=True):
#若一个色块的边界框区域小于 area_threshold ,则会被过滤掉。
#若一个色块的像素数小于 pixel_threshold ,则会被过滤掉。
#merge_cb 可设置为用以调用两个即将合并的色块的函数,以禁止或准许合并。
img.draw_rectangle(blob.rect())#画矩形框 blob.rect() ---> 返回一个矩形元组(可当作roi区域)
img.draw_cross(blob.cx(), blob.cy())#画十字 blob.cx(), blob.cy() --->返回中心点x和y坐标
if blob.cy() >120:
blob_down.append(blob)
else:
blob_up.append(blob)
#检测T
if len(blob_up) == 2 and len(blob_down) == 1:
now_T = True
#print('T')
else:
now_T = False
#判断过了几个T
if now_T == True:
real_time+=1 #滤波
if real_time==5:
T_time+=1
else:
real_time=0
out_str1 += 's'; # 校验用,可以注释掉
out_str1 += '%.d' % int(now_T); # 当前是否有T
out_str1 += '%.d' % int(T_time); # T个数
if largest_blob:
out_str1 += '%.d' % int(largest_blob[0].cy()); # 与车库距离,用来巡线
# 发送
uart.write(out_str1)
print(now_T)
print(out_str1);
# 串口数组清零
out_str1 = '' # 清除之前的数据
#print(clock.fps())#clock.fps() ---> 停止追踪运行时间,并返回当前FPS(必须先调用tick)。
記事が役に立った場合は、「いいね!」をお願いします。ありがとうございます。