本帖最后由 不爱胡萝卜的仓鼠 于 2024-10-5 17:26 编辑
图像识别最基础的就是各种线条、形状的识别,今天就来完成这个第一步。
今天使用的代码的基础框架就是沿用上一篇的代码(但是我把帧率的代码去掉了,那个对我来说没什么用,还会耗费资源),如果不出意外的话,这将会是后续测试的一个基础模板。由于使用之前的1920*1080分辨率再增加图像识别代码会导致内存不够用,所以我这边把分辨率调低,改成教程推荐的320x240。具体代码如下:
import time, os, sys
from media.sensor import *
from media.media import *
from media.display import *
def camera_test():
print("camera_test")
#用默认配置构造一个Sensor对象
sensor = Sensor()
#复位摄像头
sensor.reset()
#设置摄像头水平翻转
sensor.set_hmirror(False)
#设置摄像头垂直翻转
sensor.set_vflip(False)
#设置指定通道的输出图像尺寸, 320x240
sensor.set_framesize(width=320, height=240)
#设置指定sensor设备和通道的输出图像格式
sensor.set_pixformat(Sensor.RGB565)
#通过IDE缓冲区显示图像
Display.init(Display.VIRT, sensor.width(), sensor.height())
#初始化media manager
MediaManager.init()
#摄像头开始工作
sensor.run()
try:
while True:
os.exitpoint()
#摄像头拍一张照片
img = sensor.snapshot()
Display.show_image(img)
except KeyboardInterrupt as e:
print("user stop: ", e)
except BaseException as e:
print(f"Exception {e}")
#摄像头停止工作
sensor.stop()
# deinit display
Display.deinit()
os.exitpoint(os.EXITPOINT_ENABLE_SLEEP)
time.sleep_ms(100)
#media manager去初始化
MediaManager.deinit()
if __name__ == "__main__":
os.exitpoint(os.EXITPOINT_ENABLE)
camera_test()
一.线条检测
线条检测有2个函数可以使用,分别是find_lines、find_line_segments。他们在官方文档中的链接:https://developer.canaan-creative.com/k230_canmv/main/zh/api/openmv/image.html#find-lines、https://developer.canaan-creative.com/k230_canmv/main/zh/api/openmv/image.html#find-line-segments
前者是找直线,后者是找线段。
我们这里就用一下找线段吧。
代码如下
import time, os, sys
from media.sensor import *
from media.media import *
from media.display import *
def camera_test():
print("camera_test")
#用默认配置构造一个Sensor对象
sensor = Sensor()
#复位摄像头
sensor.reset()
#设置摄像头水平翻转
sensor.set_hmirror(False)
#设置摄像头垂直翻转
sensor.set_vflip(False)
#设置指定通道的输出图像尺寸, 320x240
sensor.set_framesize(width=320, height=240)
#设置指定sensor设备和通道的输出图像格式
sensor.set_pixformat(Sensor.RGB565)
#通过IDE缓冲区显示图像
Display.init(Display.VIRT, sensor.width(), sensor.height())
#初始化media manager
MediaManager.init()
#摄像头开始工作
sensor.run()
try:
while True:
os.exitpoint()
#摄像头拍一张照片
img = sensor.snapshot()
###################图像识别代码#######################
#循环找线段,把所有线段找出来
for l in img.find_line_segments(merge_distance = 10, max_theta_diff = 15):
#在画面上画线,把找到的线段画出来
img.draw_line(l.line(), color = (255, 0, 0), thickness=2)
###################图像识别代码#######################
Display.show_image(img)
except KeyboardInterrupt as e:
print("user stop: ", e)
except BaseException as e:
print(f"Exception {e}")
#摄像头停止工作
sensor.stop()
# deinit display
Display.deinit()
os.exitpoint(os.EXITPOINT_ENABLE_SLEEP)
time.sleep_ms(100)
#media manager去初始化
MediaManager.deinit()
if __name__ == "__main__":
os.exitpoint(os.EXITPOINT_ENABLE)
camera_test()
我在纸上画了横、竖、斜的三条线段,通过调整2个参数,成功识别到了
二.矩形检测
矩形检测函数官方文档说明:https://developer.canaan-creative.com/k230_canmv/main/zh/api/openmv/image.html#find-rects
代码如下:
import time, os, sys
from media.sensor import *
from media.media import *
from media.display import *
def camera_test():
print("camera_test")
#用默认配置构造一个Sensor对象
sensor = Sensor()
#复位摄像头
sensor.reset()
#设置摄像头水平翻转
sensor.set_hmirror(False)
#设置摄像头垂直翻转
sensor.set_vflip(False)
#设置指定通道的输出图像尺寸, 320x240
sensor.set_framesize(width=320, height=240)
#设置指定sensor设备和通道的输出图像格式
sensor.set_pixformat(Sensor.RGB565)
#通过IDE缓冲区显示图像
Display.init(Display.VIRT, sensor.width(), sensor.height())
#初始化media manager
MediaManager.init()
#摄像头开始工作
sensor.run()
try:
while True:
os.exitpoint()
#摄像头拍一张照片
img = sensor.snapshot()
###################图像识别代码#######################
#循环找矩形,把所有矩形找出来
for r in img.find_rects(threshold = 10000):
#把矩形画到图片上
img.draw_rectangle(r.rect(), color = (255, 0, 0),thickness=2)
###################图像识别代码#######################
Display.show_image(img)
except KeyboardInterrupt as e:
print("user stop: ", e)
except BaseException as e:
print(f"Exception {e}")
#摄像头停止工作
sensor.stop()
# deinit display
Display.deinit()
os.exitpoint(os.EXITPOINT_ENABLE_SLEEP)
time.sleep_ms(100)
#media manager去初始化
MediaManager.deinit()
if __name__ == "__main__":
os.exitpoint(os.EXITPOINT_ENABLE)
camera_test()
三.圆形检测
矩形检测函数官方文档说明:https://developer.canaan-creative.com/k230_canmv/main/zh/api/openmv/image.html#find-rects
代码如下:
import time, os, sys
from media.sensor import *
from media.media import *
from media.display import *
def camera_test():
print("camera_test")
#用默认配置构造一个Sensor对象
sensor = Sensor()
#复位摄像头
sensor.reset()
#设置摄像头水平翻转
sensor.set_hmirror(False)
#设置摄像头垂直翻转
sensor.set_vflip(False)
#设置指定通道的输出图像尺寸, 320x240
sensor.set_framesize(width=320, height=240)
#设置指定sensor设备和通道的输出图像格式
sensor.set_pixformat(Sensor.RGB565)
#通过IDE缓冲区显示图像
Display.init(Display.VIRT, sensor.width(), sensor.height())
#初始化media manager
MediaManager.init()
#摄像头开始工作
sensor.run()
try:
while True:
os.exitpoint()
#摄像头拍一张照片
img = sensor.snapshot()
###################图像识别代码#######################
for c in img.find_circles(threshold = 3500, x_margin = 10, y_margin= 10,
r_margin = 10,r_min = 2, r_max = 100, r_step = 2):
#画红色圆做指示
img.draw_circle(c.x(), c.y(), c.r(), color = (255, 0, 0),thickness=2)
###################图像识别代码#######################
Display.show_image(img)
except KeyboardInterrupt as e:
print("user stop: ", e)
except BaseException as e:
print(f"Exception {e}")
#摄像头停止工作
sensor.stop()
# deinit display
Display.deinit()
os.exitpoint(os.EXITPOINT_ENABLE_SLEEP)
time.sleep_ms(100)
#media manager去初始化
MediaManager.deinit()
if __name__ == "__main__":
os.exitpoint(os.EXITPOINT_ENABLE)
camera_test()
我在纸上放了一个一元钱硬币,识别成功
四.中途出现的BUG
在刚开始测试时,我遇到了一个很奇怪的BUG,代码停止运行时即使已经调用了去初始化的代码,但是在此运行时只要有图像识别的代码,例如线条检测,一运行到线条检测代码日志就报“Exception Out of fast frame buffer stack memory”,如下图所示
意思就是说“超出快速帧缓冲区堆栈内存”,简单来说就是内存炸了。但是我们这块开发板可是有1G内存的,不管怎么说都不会说内存不够用啊
我查了网上,基本上就是说代码消耗内存太厉害了,要降级分辨率,但是我尝试把分辨率调整到最小的88x72的QQCIF,并且关闭了display都不行,一运行线条检测的函数就报错,把这句话去掉,就可以正常工作。折腾我快一个小时,也没折腾出结果,我裂开了
最终的解决方案是:重启(按一下开发板的RST按钮)。。。。。。果然遇到问题就重启