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(100100)    #获取位置为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是进行匹配的区域(左上顶点为(100),长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()))
复制代码

 

posted @   0MrMKG  阅读(1501)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· 2 本地部署DeepSeek模型构建本地知识库+联网搜索详细步骤
点击右上角即可分享
微信分享提示