openmv学习
目录:
- 功能性函数:
延时函数(time库)
打开小灯(pyb库)
控制io口的输入与输出(pyb库)
控制串口的输出信息(pyb库)
关于创建新文档时候的代码
- 相应模块的学习:
- 感光元件包括了摄像头初始化,曝光等需求以及Roi区域提取和设置翻转
- 基本方法包括图像逻辑运算,图像大小输出以及像素点操作
- 统计信息(主要是对roi区域的处理)(包括了roi区域的平均数,中位数,众数,标准差,最小值,最大值等)
- 关于绘图(线,框,圆,十字,写字)
- 寻找色块(blob相关操作)【实验1:框定绿色色块】
- 多模板匹配【实验2:检测‘1’ ‘0’ ‘S’】(可以用多个模板保证精度,但是对于动态物体检测效果差)(NCC算法)
- 特征点检测(主要运用于检测动态的物体)
- 实验代码:
便携调用:
import sensor, image, time sensor.reset() sensor.set_pixformat(sensor.RGB565) sensor.set_framesize(sensor.QVGA) sensor.skip_frames(time = 2000) clock = time.clock() while(True): clock.tick() img = sensor.snapshot() print(clock.fps())
功能性函数--延时函数(time库)
import time # 导入库文件 time.sleep(1) # 延时1s time.sleep(0.5) # 延时0.5s [参数以秒为单位,可传入小数或整数] time.sleep_ms(500) # 延时500ms time.sleep_us(10) # 延时10us
功能性函数-----打开led 灯(pyb库)
首先OpenMV 4 plus上搭载了一个全彩RGB灯和两个红外LED,一个RGB LED内部包含3个LED,但是两个红外LED是受一个端口控制的,那么OpenMV 4 plus上就总共有4个控制LED的端口
import pyb,time led_R = pyb.LED(1) led_G = pyb.LED(2) led_B = pyb.LED(3) led_IR = pyb.LED(4) while(True) led_R.on() led_G.on() led_B.on() led_IR.on() time.sleep_ms(500) led_R.off() led_G.off() led_B.off() led_IR.off() time.sleep_ms(500)
功能性函数-----控制IO口输入输出(pyb库)
先附上相关参数:
from pyb import Pin p0_out = Pin('P0',Pin.OUT_PP)#推挽输出 p0_out.high() p0_out.low() p1_in=Pin('P1',Pin.IN,Pin.PULL_UP)#上拉输入 p1.value=p1_in.value()
功能性函数-----控制串口引脚输出信息(pyb库)
相关串口函数:
fron pyb import UART uart = UART(3,115200) num= 132 num_str = "[%d]"%num uart.write(num_str+"\r\n") while(True) if uart.any()>0: str = uart.read() uart.write("redata:"+str+"\r\n")
如果串口接收到数据【通过 P5端口】-----读取接收到的字符 ---将收到的数据通过串口3输出【通过 P4端口】
功能性函数------关于创建新文档时候的代码:
import sensor, image, time # 引入此例程依赖的模块,sensor是与摄像头参数设置相关的模块,image是图像处理相关的模块,time时钟控制相关的模块。import相当于c语言的#include <>,模块相当于c语言的库。 sensor.reset() # 复位并初始化摄像头,reset()是sensor模块里面的函数 sensor.set_pixformat(sensor.RGB565) # 设置图像色彩格式,有RGB565色彩图和GRAYSCALE灰度图两种 sensor.set_framesize(sensor.QVGA) # 将图像大小设置为QVGA (320x240) # 设置图像像素大小,QQVGA: 160x120,QQVGA2: 128x160,QVGA: 320x240,VGA: 640x480, QQCIF: 88x72,QCIF: 176x144,CIF: 352x288 sensor.skip_frames(time = 2000) # 等待设置生效。 clock = time.clock() # 初始化时钟,并创建一个时钟对象来跟踪FPS帧率。 while(True): # python while循环,一定不要忘记加冒号“:” clock.tick() # 更新FPS帧率时钟。 img = sensor.snapshot() # 拍一张照片并返回图像。截取当前图像,存放于变量img中。注意python中的变量是动态类型,不需要声明定义,直接用即可。 print(clock.fps()) # 打印当前的帧率。注意: 当连接电脑后,OpenMV会变成一半的速度。当不连接电脑,帧率会增加。
模块学习(1)---感光元件:(包括了摄像头初始化,曝光等需求以及Roi区域提取和设置翻转)
""" 0001实时获取摄像头图片例程 """ # 导入相应的库 import sensor, image, time # 初始化摄像头 sensor.reset() # 设置采集到照片的格式:彩色RGB sensor.set_pixformat(sensor.RGB565) # 设置采集到照片的大小: 320 * 240 sensor.set_framesize(sensor.QVGA) # 等待一段时间2s,等摄像头设置好 sensor.skip_frames(time = 2000) # 实时显示摄像头拍摄的照片 while(True): # 拍摄图片并返回img img = sensor.snapshot()
下面分模块整理:
关于sensor的api大全:https://www.e-learn.cn/topic/3328912
(1)关于sensor.set_pixformat(sensor.RGB565)
有两个参数分别对应彩色和黑白图像的获取:
sensor.GRAYSCALE: 灰度,每个像素8bit。
sensor.RGB565: 彩色,每个像素16bit。
(2)关于sensor.set_framesize() 设置图像的大小
有下列参数选择图像的大小:
sensor.QQCIF: 88x72 sensor.QCIF: 176x144 sensor.CIF: 352x288 sensor.QQSIF: 88x60 sensor.QSIF: 176x120 sensor.SIF: 352x240 sensor.QQQQVGA: 40x30 sensor.QQQVGA: 80x60 sensor.QQVGA: 160x120 sensor.QVGA: 320x240 sensor.VGA: 640x480 sensor.HQQQVGA: 80x40 sensor.HQQVGA: 160x80 sensor.HQVGA: 240x160 sensor.B64X32: 64x32 (用于帧差异 image.find_displacement()) sensor.B64X64: 64x64 用于帧差异 image.find_displacement()) sensor.B128X64: 128x64 (用于帧差异 image.find_displacement()) sensor.B128X128: 128x128 (用于帧差异 image.find_displacement()) sensor.LCD: 128x160 (用于LCD扩展板) sensor.QQVGA2: 128x160 (用于LCD扩展板) sensor.WVGA: 720x480 (用于 MT9V034) sensor.WVGA2:752x480 (用于 MT9V034) sensor.SVGA: 800x600 (仅用于 OV5640 感光元件) sensor.XGA: 1024x768 (仅用于 OV5640 感光元件) sensor.SXGA: 1280x1024 (仅用于 OV5640 感光元件) sensor.UXGA: 1600x1200 (仅用于 OV5640 感光元件) sensor.HD: 1280x720 (仅用于 OV5640 感光元件) sensor.FHD: 1920x1080 (仅用于 OV5640 感光元件) sensor.QHD: 2560x1440 (仅用于 OV5640 感光元件) sensor.QXGA: 2048x1536 (仅用于 OV5640 感光元件) sensor.WQXGA: 2560x1600 (仅用于 OV5640 感光元件) sensor.WQXGA2: 2592x1944 (仅用于 OV5640 感光元件)
(3)关于sensor.skip_frames(n=10) 跳过n张照片,在更改设置后,跳过一些帧,等待感光元件变稳定。其中,参数可以为times=xxx,表示等待时间。
(4)关于while内的图像输出:
# 拍摄图片并返回img
img = sensor.snapshot()
拍摄一张照片,返回一个image对象。
(5)关于自动曝光:(用于低亮度)
sensor.set_auto_gain()

(6)关于自动白平衡:(去除环境光影响)
sensor.set_auto_whitebal()
为了使得摄像机也具有颜色恒常性能力,需要使用自平衡技术。所谓白平衡( Wh ite Balance ,简单地说就是去除环境光的影响 ,还原物体 真实的颜色,把不同色温下的颜色调整正确, 从理论上说 白颜色调整正确了,其他色彩就都准确了。即在红色灯光照 射下,白色物体依然呈白色,在蓝色灯光照射下也呈现白色。
(7)关于自动曝光:(调整图片的亮度级别)
sensor.set_auto_exposure(enable[\, exposure_us])
enable 打开(True)或关闭(False)自动曝光。默认打开。
如果 enable 为False, 则可以用 exposure_us 设置一个固定的曝光时间(以微秒为单位)。
""" 002实时获取摄像头roi区域,加上翻转 """ import sensor, image, time sensor.reset() sensor.set_pixformat(sensor.RGB565) sensor.set_framesize(sensor.QVGA)#320*240 sensor.skip_frames(time = 2000) sensor.set_auto_gain(True) sensor.set_auto_exposure(True) sensor.set_framesize(sensor.QVGA) sensor.set_windowing((100, 240)) #取中间的80*80区域 sensor.set_hmirror(True)#水平方向旋转(左右) sensor.set_vflip(True)#竖直方向旋转 while(True): img = sensor.snapshot()
基本操作(1)操作像素点:
image.get_pixel(x, y)
对于灰度图: 返回(x,y)坐标的灰度值.
对于彩色图: 返回(x,y)坐标的(r,g,b)的tuple.
image.set_pixel(x, y, pixel)
对于灰度图: 设置(x,y)坐标的灰度值。
对于彩色图: 设置(x,y)坐标的(r,g,b)的值。
""" 003对于图像的像素点的操作 """ import sensor, image, time sensor.reset() sensor.set_pixformat(sensor.RGB565) sensor.set_framesize(sensor.QVGA)#320*240 sensor.skip_frames(time = 2000) while(True): img = sensor.snapshot() for i in range(100,220): for j in range(100,140): img.set_pixel(i,j,(255,255,0)) #在中间形成黄色的长方形 pixel_data = img.get_pixel(100,100) #获取位置为x,y的像素点(以后可以循环存储)
基本操作(2)读取图片大小:(没有必要,因为初始化时候已经设定,当然,图像切割的时候有用处,类似opencv)
image.width() 返回图像的宽度(像素) image.height() 返回图像的高度(像素) image.format() 灰度图会返回 sensor.GRAYSCALE,彩色图会返回 sensor.RGB565。 image.size() 返回图像的大小(byte)
基本操作(3)图像逻辑运算:
image.invert() 取反,对于二值化的图像,0(黑)变成1(白),1(白)变成0(黑)。 注: 图像可以是另一个image对象,或者是从 (bmp/pgm/ppm)文件读入的image对象。 两个图像都必须是相同的尺寸和类型(灰度图/彩色图)。 image.nand(image) 与另一个图片进行与非(NAND)运算。 image.nor(image) 与另一个图片进行或非(NOR)运算。 image.xor(image) 与另一个图片进行异或(XOR)运算。 image.xnor(image) 与另一个图片进行异或非(XNOR)运算。 image.difference(image) 从这张图片减去另一个图片。比如,对于每个通道的每个像素点,取相减绝对值操作。这个函数,经常用来做移动检测。
注释:关于源文件图片的导入函数:(得在sd卡上读取)
img_1= image.Image("/example.jpg")
还有就是openmv似乎没有自定义数组的库函数
统计信息: (roi区域的平均数,中位数,众数,标准差,最小值,最大值等)
打个比方:img.get_statistics(roi=(0,10,10,20)) 注意:roi的参数是x_min x_max y_min y_max
然后可以使用下列方式获取图像信息:
statistics.mean() 返回灰度的平均数(0-255) (int)。你也可以通过statistics[0]获得。 statistics.median() 返回灰度的中位数(0-255) (int)。你也可以通过statistics[1]获得。 statistics.mode() 返回灰度的众数(0-255) (int)。你也可以通过statistics[2]获得。 statistics.stdev() 返回灰度的标准差(0-255) (int)。你也可以通过statistics[3]获得。 statistics.min() 返回灰度的最小值(0-255) (int)。你也可以通过statistics[4]获得。 statistics.max() 返回灰度的最大值(0-255) (int)。你也可以通过statistics[5]获得。 statistics.lq() 返回灰度的第一四分数(0-255) (int)。你也可以通过statistics[6]获得。 statistics.uq() 返回灰度的第三四分数(0-255) (int)。你也可以通过statistics[7]获得。 上面的是灰度的值,接下来的 l_mean,l_median,l_mode,l_stdev,l_min,l_max,l_lq,l_uq, a_mean,a_median,a_mode,a_stdev,a_min,a_max,a_lq,a_uq, b_mean,b_median,b_mode,b_stdev,b_min,b_max,b_lq,b_uq, 是LAB三个通道的平均数,中位数,众数,标准差,最小值,最大值,第一四分数,第三四分数。
- 关于绘图(线,框,圆,十字,写字)
画线 image.draw_line(line_tuple, color=White) 在图像中画一条直线。 line_tuple的格式是(x0, y0, x1, y1),意思是(x0, y0)到(x1, y1)的直线。 颜色可以是灰度值(0-255),或者是彩色值(r, g, b)的tupple。默认是白色
画框 image.draw_rectangle(rect_tuple, color=White) 在图像中画一个矩形框。 rect_tuple 的格式是 (x, y, w, h)。
画圆 image.draw_circle(x, y, radius, color=White) 在图像中画一个圆。 x,y是圆心坐标 radius是圆的半径 画十字 image.draw_cross(x, y, size=5, color=White) 在图像中画一个十字 x,y是坐标 size是两侧的尺寸 写字 image.draw_string(x, y, text, color=White) 在图像中写字 8x10的像素 x,y是坐标。使用\n, \r, and \r\n会使光标移动到下一行。 text是要写的字符串。
""" 0004绘制十字,框,以及文字 """ import sensor, image, time # 引入此例程依赖的模块,sensor是与摄像头参数设置相关的模块,image是图像处理相关的模块,time时钟控制相关的模块。import相当于c语言的#include <>,模块相当于c语言的库。 import pyb sensor.reset() # 复位并初始化摄像头,reset()是sensor模块里面的函数 sensor.set_pixformat(sensor.RGB565) # 设置图像色彩格式,有RGB565色彩图和GRAYSCALE灰度图两种 sensor.set_framesize(sensor.QVGA) # 将图像大小设置为QVGA (320x240) # 设置图像像素大小,QQVGA: 160x120,QQVGA2: 128x160,QVGA: 320x240,VGA: 640x480, QQCIF: 88x72,QCIF: 176x144,CIF: 352x288 sensor.skip_frames(time = 2000) # 等待设置生效。 clock = time.clock() # 初始化时钟,并创建一个时钟对象来跟踪FPS帧率。 while(True): # python while循环,一定不要忘记加冒号“:” clock.tick() # 更新FPS帧率时钟。 img = sensor.snapshot() # 拍一张照片并返回图像。截取当前图像,存放于变量img中。注意python中的变量是动态类型,不需要声明定义,直接用即可。 img.draw_cross(159, 119, size=10, color=(255,0,0)) img.draw_rectangle((155,115,10,10), color=(0,255,0)) img.draw_string(160,120,'target',color=(255,0,0)) print(clock.fps()) # 打印当前的帧率。注意: 当连接电脑后,OpenMV会变成一半的速度。当不连接电脑,帧率会增加。
寻找色块:
image.find_blobs(thresholds, roi=Auto, x_stride=2, y_stride=1, invert=False, area_threshold=10, pixels_threshold=10, merge=False, margin=0, threshold_cb=None, merge_cb=None)
(1)thresholds就是一个列表的数据类型,可以通过定义来调用它。
比如说定义:
unkown_color = (0,0,0,234,32,12) img = sensor.snapshot() img.find_bolbs([unkown_color])
(2)roi区域的选定:
left_roi = [0,0,160,240]
img = sensor.snapshot()
blobs = img.find_blobs([red],roi=left_roi)
(3)色块宽度查找:
x_stride 就是查找的色块的x方向上最小宽度的像素,默认为2,如果你只想查找宽度10个像素以上的色块,那么就设置这个参数为10: blobs = img.find_blobs([red],x_stride=10) y_stride 就是查找的色块的y方向上最小宽度的像素,默认为1,如果你只想查找宽度5个像素以上的色块,那么就设置这个参数为5: blobs = img.find_blobs([red],y_stride=5)
(4)翻转阈值(就是取补集)
invert = True
invert 反转阈值,把阈值以外的颜色作为阈值进行查找
(5)area_threshold
area_threshold 面积阈值,如果色块被框起来的面积小于这个值,会被过滤掉
是框起来的整个面积(可能会包含其他的一些背景的像素数)
(6)pixels_threshold
pixels_threshold 色块的像素个数(面积)阈值,如果色块像素数量小于这个值,会被过滤掉。
是指的框中的所有的色块的颜色,不包含其他(比如背景的颜色)
(7)merge
merge 合并,如果设置为True,那么合并所有重叠的blob为一个。
注意:这会合并所有的blob,无论是什么颜色的。如果你想混淆多种颜色的blob,只需要分别调用不同颜色阈值的find_blobs。
下面讨论blob相关的函数返回值(查询用)
blob.rect() 返回这个色块的外框——矩形元组(x, y, w, h),可以直接在image.draw_rectangle中使用。 blob.x() 返回色块的外框的x坐标(int),也可以通过blob[0]来获取。 blob.y() 返回色块的外框的y坐标(int),也可以通过blob[1]来获取。 blob.w() 返回色块的外框的宽度w(int),也可以通过blob[2]来获取。 blob.h() 返回色块的外框的高度h(int),也可以通过blob[3]来获取。 blob.pixels() 返回色块的像素数量(int),也可以通过blob[4]来获取。 blob.cx() 返回色块的外框的中心x坐标(int),也可以通过blob[5]来获取。 blob.cy() 返回色块的外框的中心y坐标(int),也可以通过blob[6]来获取。 blob.rotation() 返回色块的旋转角度(单位为弧度)(float)。如果色块类似一个铅笔,那么这个值为0~180°。如果色块是一个圆,那么这个值是无用的。如果色块完全没有对称性,那么你会得到0~360°,也可以通过blob[7]来获取。 blob.code() 返回一个16bit数字,每一个bit会对应每一个阈值。举个例子: blobs = img.find_blobs([red, blue, yellow], merge=True) 如果这个色块是红色,那么它的code就是0001,如果是蓝色,那么它的code就是0010。注意:一个blob可能是合并的,如果是红色和蓝色的blob,那么这个blob就是0011。这个功能可以用于查找颜色代码。也可以通过blob[8]来获取。 blob.count() 如果merge=True,那么就会有多个blob被合并到一个blob,这个函数返回的就是这个的数量。如果merge=False,那么返回值总是1。也可以通过blob[9]来获取。 blob.area() 返回色块的外框的面积。应该等于(w * h) blob.density() 返回色块的密度。这等于色块的像素数除以外框的区域。如果密度较低,那么说明目标锁定的不是很好。 比如,识别一个红色的圆,返回的blob.pixels()是目标圆的像素点数,blob.area()是圆的外接正方形的面积。
实验1:
""" 实验1:Single Color RGB565 Blob Tracking Example 这里经过改变,是显示绿色色块所在的区域并且用矩形框定 """ import sensor, image, time, math #这里建立了对于下面的列表的索引,好方法。 threshold_index = 0 # 0 for red, 1 for green, 2 for blue thresholds = [(30, 100, 15, 127, 15, 127), # generic_red_thresholds (30, 100, -64, -8, -32, 32), # generic_green_thresholds (0, 30, 0, 64, -128, 0)] # generic_blue_thresholds #这里可以采用阈值编辑器获取信息 thresholds_2 =(30, 100, -64, -8, -32, 32) sensor.reset() #重置感光元件,重置摄像机 sensor.set_pixformat(sensor.RGB565) #重置颜色格式为RGB56 sensor.set_framesize(sensor.QVGA) #图像的大小是QVGA sensor.skip_frames(time = 2000) sensor.set_auto_gain(False) # 务必要关闭白平衡 sensor.set_auto_whitebal(False) # 务必要关闭自动增益 clock = time.clock() #这里的time函数当固定格式记住了,主要是为了看运行的帧数应该。 while(True): clock.tick() img = sensor.snapshot() #先截取感光元件的一张图片 #在img.find_blobs这个函数中,进行颜色识别 for blob in img.find_blobs([thresholds_2], pixels_threshold=10, area_threshold=10, merge=True): #此处没有设置roi的值,便是对整个图像进行颜色识别 if blob.elongation() > 0.1: #返回一个从0到1的数字,表示这个物体的长度,应该就是检测到了这个色块,输出长度(?) #img.draw_edges(blob.min_corners(), color=(255,0,0)) #img.draw_line(blob.major_axis_line(), color=(0,255,0)) #img.draw_line(blob.minor_axis_line(), color=(0,0,255)) img.draw_rectangle(blob.rect()) #上面下面都是对于这个色块的框定的代码,blob相关函数的返回值要清楚 #img.draw_cross(blob.cx(), blob.cy()) #img.draw_keypoints([(blob.cx(), blob.cy(), int(math.degrees(blob.rotation())))], size=40) print(clock.fps())
多模板匹配:
""" 实验2:多模板匹配 """ import time, sensor, image from image import SEARCH_EX, SEARCH_DS #从imgae模块引入SEARCH_EX和SEARCH_DS。使用from import仅仅引入SEARCH_EX, #SEARCH_DS两个需要的部分,而不把image模块全部引入。 # Reset sensor sensor.reset() # Set sensor settings sensor.set_contrast(1) sensor.set_gainceiling(16) # Max resolution for template matching with SEARCH_EX is QQVGA sensor.set_framesize(sensor.QQVGA) # You can set windowing to reduce the search image. #sensor.set_windowing(((640-80)//2, (480-60)//2, 80, 60)) sensor.set_pixformat(sensor.GRAYSCALE) # Load template. # Template should be a small (eg. 32x32 pixels) grayscale image. templates = ["/0.pgm", "/1.pgm", "/2.pgm"] #保存多个模板 #加载模板图片 clock = time.clock() # Run template matching while (True): clock.tick() img = sensor.snapshot() for t in templates: template = image.Image(t) #对每个模板遍历进行模板匹配 r = img.find_template(template, 0.60, step=4, search=SEARCH_EX) #, roi=(10, 0, 60, 60)) #find_template(template, threshold, [roi, step, search]),threshold中 #的0.7是相似度阈值,roi是进行匹配的区域(左上顶点为(10,0),长80宽60的矩形), #注意roi的大小要比模板图片大,比frambuffer小。 #把匹配到的图像标记出来 if r: img.draw_rectangle(r) img.draw_string(10,10,'done',color=(255,0,0)) print(t) #打印模板名字 #print(clock.fps())
关于NCC算法补充:
https://blog.csdn.net/qq_43653930/article/details/105766355
把两幅图搞成均值,方差一样,然后用相关性来比较他们。相关性度量可以理解为两个单位长度向量的内积。内积越大,夹角越小,相似度越高。
特征点检测:
""" 实验三:特征点检测 """ import sensor, time, image sensor.reset() sensor.set_contrast(3) #调整对比度(-3——3) sensor.set_gainceiling(16) #设置相机图像增益上限为16 sensor.set_framesize(sensor.VGA) #设置相机模块一帧的大小 sensor.set_windowing((320, 240)) #设置roi区域的大小,也就是右边显示的window大小 sensor.set_pixformat(sensor.GRAYSCALE) #选择像素模式为灰度图像 sensor.skip_frames(time = 2000) #跳过2s,以便初始化 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) #这里的kpts表示的就是物体的特征之类的数据,这是由img.findkeypoints函数返回的值。 kpts1 = None #先初始化为None #kpts1保存目标物体的特征,可以从文件导入特征,但是不建议这么做。 #kpts1 = image.load_descriptor("/desc.orb") #img = sensor.snapshot() #draw_keypoints(img, kpts1) #clock = time.clock() while (True): clock.tick() img = sensor.snapshot() if (kpts1 == None): #如果是刚开始运行程序,提取最开始的图像作为目标物体特征,kpts1保存目标物体的特征 #默认会匹配目标特征的多种比例大小,而不仅仅是保存目标特征时的大小,比模版匹配灵活。 kpts1 = img.find_keypoints(max_keypoints=150, threshold=10, scale_factor=2) #image.find_keypoints(roi=Auto, threshold=20, normalized=False, scale_factor=1.5, max_keypoints=100, corner_detector=CORNER_AGAST) #roi表示识别的区域,是一个元组(x,y,w,h),默认与framsesize大小一致。 #threshold是0~255的一个阈值,用来控制特征点检测的角点数量。用默认的AGAST特征点检测,这个阈值大概是20。用FAST特征点检测,这个阈值大概是60~80。阈值越低,获得的角点越多。 #normalized是一个布尔数值,默认是False,可以匹配目标特征的多种大小(比ncc模版匹配效果灵活)。如果设置为True,关闭特征点检测的多比例结果,仅匹配目标特征的一种大小(类似于模版匹配),但是运算速度会更快一些。 #scale_factor是一个大于1.0的浮点数。这个数值越高,检测速度越快,但是匹配准确率会下降。一般在1.35~1.5左右最佳。 #max_keypoints是一个物体可提取的特征点的最大数量。如果一个物体的特征点太多导致RAM内存爆掉,减小这个数值。 #corner_detector是特征点检测采取的算法,默认是AGAST算法。FAST算法会更快但是准确率会下降。 draw_keypoints(img, kpts1) #画出此时的目标特征,就是识别时候的圆与线条。 else: #当与最开始的目标特征进行匹配时,默认设置normalized=True,只匹配目标特征的一种大小。 kpts2 = img.find_keypoints(max_keypoints=150, threshold=10, normalized=True) #如果检测到特征物体 if (kpts2): #匹配当前找到的特征和最初的目标特征的相似度 match = image.match_descriptor(kpts1, kpts2, threshold=85) #image.match_descriptor(descritor0, descriptor1, threshold=90, filter_outliers=False)。本函数返回kptmatch对象。 #前一个是之前检测到的物体特征,第二个是待检测物体的特征,进行匹配。 #threshold阈值设置匹配的准确度,用来过滤掉有歧义的匹配。这个值越小,准确度越高。阈值范围0~100,默认70 #filter_outliers默认关闭. #match.count()是kpt1和kpt2的匹配的近似特征点数目。 #如果大于10,证明两个特征相似,匹配成功。 if (match.count()>8): # If we have at least n "good matches" # Draw bounding rectangle and cross. #在匹配到的目标特征中心画十字和矩形框。 img.draw_rectangle(match.rect()) img.draw_cross(match.cx(), match.cy(), size=20) #match.theta()是匹配到的特征物体相对目标物体的旋转角度。 #print(kpts2, "matched:%d dt:%d"%(match.count(), match.theta())) #不建议draw_keypoints画出特征角点。 #打印帧率。 #img.draw_string(0, 0, "FPS:%.2f"%(clock.fps()))
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· 2 本地部署DeepSeek模型构建本地知识库+联网搜索详细步骤