image类
图像可以是另一个image对象,或者是从 (bmp/pgm/ppm)文件读入的image对象。
两个图像都必须是相同的尺寸和类型(灰度图/彩色图)
获取/设置像素点:通过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)的值。
img = sensor.snapshot()
img.get_pixel(10,10)
img.set_pixcel(10,10,(255,0,0))#设置坐标(10,10)的像素点为红色(255,0,0)
获取图像的宽度和高度
返回图像的宽度(像素) image.width()
返回图像的高度(像素) image.height()
灰度图会返回 sensor.GRAYSCALE,彩色图会返回 sensor.RGB565 image.format()
返回图像的大小(byte) image.size()
image.invert():取反,对于二值化的图像,0(黑)变成1(白),1(白)变成0(黑)
统计信息——Statistics
image.get_statistics(roi=Auto)
其中roi是目标区域。注意,这里的roi,bins之类的参数,一定要显式地标明,如果是 img.get_statistics((0,0,10,20)),ROI不会起作用。这里在python中有点像默认参数一样。
img.get_statistics(roi=(0,0,10,20))
可以调用mean() ,.median(),mode() 返回平均数,中位数,众数(灰度)。
l(a,b)_mean,l(a,b)_median,l(a,b)_mode 返回LAB的平均数,中位数,众数
画图
image.draw_line(line_tuple, color=White) 在图像中画一条直线
line_tuple的格式是(x0, y0, x1, y1),意思是(x0, y0)到(x1, y1)的直线。
颜色可以是灰度值(0-255),或者是彩色值(r, g, b)的tupple。默认是白色
其中的color关键字必须显示的标明color=。
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是要写的字符串。
import sensor, image, time
sensor.reset() # 初始化摄像头
sensor.set_pixformat(sensor.RGB565) # 格式为 RGB565.
sensor.set_framesize(sensor.QQVGA)
sensor.skip_frames(10) # 跳过10帧,使新设置生效
while(True):
img = sensor.snapshot() # Take a picture and return the image.
img.draw_line((20, 30, 40, 50))
img.draw_line((80, 50, 100, 100), color=(255,0,0))
img.draw_rectangle((20, 30, 41, 51), color=(255,0,0))
img.draw_circle(50, 50, 30)
img.draw_cross(90,60,size=10)
img.draw_string(10,10, "hello world!")
寻找色块
find_blobs函数
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)
'''thresholds是颜色的阈值,注意:这个参数是一个列表,可以包含多个颜色。如果你只需要一个颜色,那么在这个列表中只需要有一个颜色值,如果你想要多个颜色阈值,那这个列表就需要多个颜色阈值。注意:在返回的色块对象blob可以调用code方法,来判断是什么颜色的色块。
'''
#一个颜色阈值的结构是这样的:
#red = (minL, maxL, minA, maxA, minB, maxB)
red = (xxx,xxx,xxx,xxx,xxx,xxx)
blue = (xxx,xxx,xxx,xxx,xxx,xxx)
yellow = (xxx,xxx,xxx,xxx,xxx,xxx)
img=sensor.snapshot()
red_blobs = img.find_blobs([red])
color_blobs = img.find_blobs([red,blue, yellow])
#roi是“感兴趣区
#x_stride/y_stride 就是查找的色块的x/y方向上最小宽度的像素,默认为2,如果你只想查找宽度10个像素以上的色块,那么就设置这个参数为10
#invert 反转阈值,把阈值以外的颜色作为阈值进行查找
#area_threshold 面积阈值,如果色块被框起来的面积小于这个值,会被过滤掉
#pixels_threshold 像素个数阈值,如果色块像素数量小于这个值,会被过滤掉
#merge 合并,如果设置为True,那么合并所有重叠的blob为一个。注意:这会合并所有的blob,无论是什么颜色的。如果你想混淆多种颜色的blob,只需要分别调用不同颜色阈值的find_blobs。
#margin 边界,如果设置为1,那么两个blobs如果间距1一个像素点,也会被合并
find_blobs对象返回的是多个blob的列表。(注意区分blobs和blob,用来区分多个色块,和一个色块)。
列表类似与C语言的数组,一个blobs列表里包含很多blob对象,blobs对象就是色块,每个blobs对象包含一个色块的信息。blobs就是很多色块。
blobs = img.find_blobs([red])
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.code() 返回一个16bit数字,每一个bit会对应每一个阈值。举个例子:
blobs = img.find_blobs([red, blue, yellow], merge=True)
如果这个色块是红色,那么它的code就是0001,如果是蓝色,那么它的code就是0010。这个功能可以用于查找颜色代码。也可以通过blob[8]来获取。
blob.area() 返回色块的外框的面积。应该等于(w * h)
pyb库
延时函数
pyb.delay(50) # 延时 50 毫秒
pyb.millis() # 获取从启动开始计时的毫秒数
LED
from pyb import LED
'''
LED(1) -> 红LED
LED(2) -> 绿LED
LED(3) -> 蓝LED
LED(4) -> 红外LED,两个
'''
led = LED(1) # 红led
led.toggle()#翻转LED。如果原来状态是开,将变为关;原来是关,现在就变为 开。
led.on()#亮
led.off()#灭
IO
from pyb import Pin
p_out = Pin('P7', Pin.OUT_PP)#设置p_out为输出引脚
p_out.high()#设置p_out引脚为高
p_out.low()#设置p_out引脚为低
p_in = Pin('P7', Pin.IN, Pin.PULL_UP)#设置p_in为输入引脚,并开启上拉电阻
value = p_in.value() # get value, 0 or 1#读入p_in引脚的值
定时器
Timer 1 Channel 3 Negative -> P0
Timer 1 Channel 2 Negative -> P1
Timer 1 Channel 1 Negative -> P2
Timer 2 Channel 3 Positive -> P4
Timer 2 Channel 4 Positive -> P5
Timer 2 Channel 1 Positive -> P6
Timer 4 Channel 1 Negative -> P7
Timer 4 Channel 2 Negative -> P8
OpenMV M7上增加:Timer 4 Channel 3 Positive -> P9
from pyb import Timer
tim = Timer(4, freq=1000)
tim.counter() # get counter value
tim.freq(0.5) # 0.5 Hz
tim.callback(lambda t: pyb.LED(1).toggle())
PWM
from pyb import Pin, Timer
p = Pin('P7') # P7 has TIM4, CH1
tim = Timer(4, freq=1000)
ch = tim.channel(1, Timer.PWM, pin=p)
ch.pulse_width_percent(50)
ADC
from pyb import Pin, ADC
adc = ADC('P6')
adc.read() # read value, 0-4095
DAC
from pyb import Pin, DAC
dac = DAC('P6')
dac.write(120) # output between 0 and 255
UART
UART 3 RX -> P5 (PB11)
UART 3 TX -> P4 (PB10)
OpenMV3 M7 / OpenMV4 H7/ OpenMV4 H7 Plus上增加:
UART 1 RX -> P0 (PB15)
UART 1 TX -> P1 (PB14)
from pyb import UART
uart = UART(3, 9600)
uart.write('hello')
uart.read(5) # read up to 5 bytes
SPI
from pyb import SPI
spi = SPI(2, SPI.MASTER, baudrate=200000, polarity=1, phase=0)
spi.send('hello')
spi.recv(5) # receive 5 bytes on the bus
spi.send_recv('hello') # send a receive 5 bytes
I2C
I2C 2 SCL (Serial Clock) -> P4 (PB10)
I2C 2 SDA (Serial Data) -> P5 (PB11)
OpenMV3 M7 / OpenMV4 H7 / OpenMV4 H7 Plus上增加:
I2C 4 SCL (Serial Clock) -> P7 (PD13)
I2C 4 SDA (Serial Data) -> P8 (PD12)
machine库是软件模拟的I2C协议,所以使用任何引脚都可以,但是还是推荐使用上面所说的引脚
from machine import I2C, Pin
i2c = I2C(sda=Pin('P5'),scl=Pin('P4'))
i2c.scan()
i2c.writeto(0x42, b'123') # write 3 bytes to slave with 7-bit address 42
i2c.readfrom(0x42, 4) # read 4 bytes from slave with 7-bit address 42
i2c.readfrom_mem(0x42, 8, 3) # read 3 bytes from memory of slave 42,
# starting at memory-address 8 in the slave
i2c.writeto_mem(0x42, 2, b'\x10') # write 1 byte to memory of slave 42
# starting at address 2 in the slave