标注图像
为了更直观得到openmv返回的数据,一般对目标的信息进行标注。
以下是各个标注函数及其用法。
image.draw_line((x0, y0, x1, y1), color=White) #意思是(x0, y0)到(x1, y1)的直线。
image.draw_rectangle( (x, y, w, h), color=White) #在图像中画一个矩形框。
image.draw_circle(x, y, radius, color=White) #在图像中画一个圆。
image.draw_cross(x, y, size=5, color=White) #在图像中画一个十字size是两侧的尺寸
image.draw_string(x, y, text, color=White) #在图像中写字 8x10的像素
寻找色块 颜色识别
image.find_blobs(thresholds[, invert=False[, roi[, x_stride=2[,
y_stride=1[, area_threshold=10[, pixels_threshold=10[, merge=False[,
margin=0[, threshold_cb=None[, merge_cb=None[, x_hist_bins_max=0[,
y_hist_bins_max=0]]]]]]]]]]]])
查找图像中所有的色块,返回色块对象的列表,thresholds是元组列表,是你想追踪的颜色范围,在IDE中可以通过工具->机器视觉->阀值编辑器,拖动滑块,当屏幕中其他颜色都为黑色,所选的颜色为白色,即是我们想要的颜色阀值。
一、单色自动灰度颜色跟踪
import sensor, image, time
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()
#捕捉图像中心的颜色阈值。
r = [(320//2)-(50//2), (240//2)-(50//2), 50, 50] #最中心的50*50的区域
for i in range(60): #拍60次
img = sensor.snapshot()
img.draw_rectangle(r)
threshold = [128, 128]#取中间灰度值
for i in range(60):
img = sensor.snapshot()
hist = img.get_histogram(roi=r)#直方图对象
lo = hist.get_percentile(0.01) #在1%范围内获得直方图的CDF(根据需要调整)!
hi = hist.get_percentile(0.99) #计算直方图频道的CDF,返回一个传递 percentile (0.0 - 1.0) (浮点数)中的直方图的值。 因此,若您传入0.1,该方法会告知您,当累加入累加器时,哪一个二进制会使累加器跨过0.1。 在没有异常效用破坏您的自适应色跟踪结果时,这对于确定颜色分布的最小值(0.1)和max(0.9)甚是有效。range (ADJUST AS NECESSARY)!
threshold[0] = (threshold[0] + lo.value()) // 2
threshold[1] = (threshold[1] + hi.value()) // 2
for blob in img.find_blobs([threshold], pixels_threshold=100, area_threshold=100, merge=True, margin=10):
img.draw_rectangle(blob.rect())
img.draw_cross(blob.cx(), blob.cy())
img.draw_rectangle(r)
area_threshold 面积阈值,如果色块被框起来的面积小于这个值,会被过滤掉。
pixels_threshold 像素个数阈值,如果色块像素数量小于这个值,会被过滤掉。
merge 合并,如果设置为True,那么合并所有重叠的blob为一个。
二、 RGB颜色识别
import sensor, image, time
red_threshold_01 = (0, 30, 0, 50, -10, 40)#红色的阈值
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QQVGA)
sensor.skip_frames(10)
sensor.set_auto_whitebal(False)
clock = time.clock()
while(True):
clock.tick()
img = sensor.snapshot()
blobs = img.find_blobs([red_threshold_01],area_threshold=150)
if blobs:#如果找到了目标颜色
print(blobs)
for b in blobs: #迭代找到的目标颜色区域
img.draw_cross(b[5], b[6]) # cx, cy #在目标颜色区域的中心画十字形标记
print(clock.fps())
三、多种颜色的识别
all_blobs = img.find_blobs([red,blue,yellow],merge=True)
red_blobs = img.find_blobs([red],merge=True)
blue_blobs = img.find_blobs([blue],merge=True)
yellow_blobs = img.find_blobs([yellow],merge=True)
blob.cx() 返回色块的外框的中心x坐标(int)。
blob.cy() 返回色块的外框的中心y坐标(int)。
blob.rotation() 返回色块的旋转角度(单位为弧度)(float)。
blob.area() 返回色块的外框的面积。应该等于(w * h)
AprilTag图像
Apriltag具有3d定位的功能,可以贴在别的物体上测距,测角度,翻转。
# AprilTags Example
#
# This example shows the power of the OpenMV Cam to detect April Tags
# on the OpenMV Cam M7. The M4 versions cannot detect April Tags.
import sensor, image, time, math
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QQVGA) # we run out of memory if the resolution is much bigger...
sensor.skip_frames(30)
sensor.set_auto_gain(False) # must turn this off to prevent image washout...
sensor.set_auto_whitebal(False) # must turn this off to prevent image washout...
clock = time.clock()
# 注意!与find_qrcodes不同,find_apriltags 不需要软件矫正畸变就可以工作。
# 注意,输出的姿态的单位是弧度,可以转换成角度,但是位置的单位是和你的大小有关,需要等比例换算
# f_x 是x的像素为单位的焦距。对于标准的OpenMV,应该等于2.8/3.984*656,这个值是用毫米为单位的焦距除以x方向的感光元件的长度,乘以x方向的感光元件的像素(OV7725)
# f_y 是y的像素为单位的焦距。对于标准的OpenMV,应该等于2.8/2.952*488,这个值是用毫米为单位的焦距除以y方向的感光元件的长度,乘以y方向的感光元件的像素(OV7725)
# c_x 是图像的x中心位置
# c_y 是图像的y中心位置
f_x = (2.8 / 3.984) * 160 # 默认值
f_y = (2.8 / 2.952) * 120 # 默认值
c_x = 160 * 0.5 # 默认值(image.w * 0.5)
c_y = 120 * 0.5 # 默认值(image.h * 0.5)
def degrees(radians):
return (180 * radians) / math.pi
while(True):
clock.tick()
img = sensor.snapshot()
for tag in img.find_apriltags(fx=f_x, fy=f_y, cx=c_x, cy=c_y): # 默认为TAG36H11
img.draw_rectangle(tag.rect(), color = (255, 0, 0))
img.draw_cross(tag.cx(), tag.cy(), color = (0, 255, 0))
print_args = (tag.x_translation(), tag.y_translation(), tag.z_translation(), \
degrees(tag.x_rotation()), degrees(tag.y_rotation()), degrees(tag.z_rotation()))
# 位置的单位是未知的,旋转的单位是角度
print("Tx: %f, Ty %f, Tz %f, Rx %f, Ry %f, Rz %f" % print_args)
print(clock.fps())
特征点检测
特征点检测相对于模块检测能检测物体更加轻松,受到很小的外界因素的干扰。
特征点的保存
保存特征点到openmv里。
import sensor,time,image
sensor.reset()
sensor.set_contrast(3)#调整对比度为最大
sensor.set_gainceiling(16)#设置相机图像增益上限。2, 4, 8, 16, 32, 64, 128。
sensor.set_framesize(sensor.VGA)
sensor.set_windowing((320,420))
sensor.set_pixformat(sensor.GRAYSCALE)
sensor.skip_frames(time=2000)
sensor.set_auto_gain(False,value=100)
FILE_NAME='1'
img=sensor.snapshot()
kpts=img.find_keypoints(max_keypoints=150,threshold=10,scale_factor=1.2)
if(kpts==None):
raise(Exception("no keypoints"))
image.save_descriptor(kpts,"/%s.orb"%(FILE_NAME))
img.save("/%s.pgm"%(FILE_NAME))
img.draw_keypoints(kpts)
sensor.snapshot()
time.sleep_ms(1000)
raise(Exception("ok"))
特征点的检测
import sensor,time,image
sensor.reset()
sensor.set_contrast(3)
sensor.set_gainceiling(16)
sensor.set_framesize(sensor.VGA)
sensor.set_windowing((320, 240))
sensor.set_pixformat(sensor.GRAYSCALE)
sensor.skip_frames(time = 2000)
sensor.set_auto_gain(False, value=100)
def draw_keypoints(img,kpts)
if kpts:
print(kpts)
img.draw_keypoints(kpts)
img=sensor.snapshot()
time.sleep_ms(1000)
kpts1=None
clock=time.clock()
while(True):
clock.tick()
img.sensor.snapshot()
if(kpts1==None):
kpts1=img.find_keypoints(max_keypoints=150,threshold=10, scale_factor=1.35)#记录特征点
draw_keypoints()
else:
kpts2 = img.find_keypoints(max_keypoints=150, threshold=10, normalized=True)#如果找到特征点
if(kets2):
match = image.match_descriptor(kpts1, kpts2, threshold=85)#这个测度值越接近0,LBPF特征点匹配得就越好。
if (match.count()>10):
img.draw_rectangle(match.rect())
img.draw_cross(match.cx(), match.cy(), size=10)
print(kpts2, "matched:%d dt:%d"%(match.count(), match.theta()))