【摘要】 写在前面
之前我已经写过一些树莓派通过python发送命令控制底盘子系统按照预定轨迹行走的博客了,传送门在下面:
STM32F427IIH6芯片通过DMA+USART(UART)与树莓派进行双工通信购物机器人底盘控制之STM32F427IIH6芯片处理串口数据方案树莓派中Python控制购物机器人完成预定轨迹行走
完成了底盘子系统的运动控制之后,就需要做图像识别…
写在前面
之前我已经写过一些树莓派通过python发送命令控制底盘子系统按照预定轨迹行走的博客了,传送门在下面:
- STM32F427IIH6芯片通过DMA+USART(UART)与树莓派进行双工通信
- 购物机器人底盘控制之STM32F427IIH6芯片处理串口数据方案
- 树莓派中Python控制购物机器人完成预定轨迹行走
完成了底盘子系统的运动控制之后,就需要做图像识别了,那么完成图像识别的前提就是拍照,拍照就需要用到摄像头,我们小组选用的摄像头是KS2A242,那么在我驱动2个KS2A242摄像头过程中,遇到了一些问题,特此写这篇摄像头记录一下。
图片概览
KS2A242摄像头
摄像头摆放方式
遇到的问题
在我刚开始驱动这个摄像头的时候的python程序长这样
self.cap0 = MyThreadCapture(0, CAPTURE_FRAME_WIDTH, CAPTURE_FRAME_HEIGHT) self.cap1 = MyThreadCapture(1, CAPTURE_FRAME_WIDTH, CAPTURE_FRAME_HEIGHT) if self.cap0.is_opened() is False: self.cap0 = MyThreadCapture(0, CAPTURE_FRAME_WIDTH, CAPTURE_FRAME_HEIGHT) if self.cap1.is_opened() is False: self.cap1 = MyThreadCapture(1, CAPTURE_FRAME_WIDTH, CAPTURE_FRAME_HEIGHT) self.cap0.setDaemon(True) self.cap0.start() self.cap1.setDaemon(True) self.cap1.start()
摄像头的驱动类如下
class MyThreadCapture(threading.Thread): def __init__(self, capture_source, capture_frame_width, capture_frame_height): threading.Thread.__init__(self) self.cap = cv2.VideoCapture(capture_source) self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, capture_frame_width) self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, capture_frame_height) self.img = None self.lock = threading.Lock() self.stop_cap = False print('cap ' + str(capture_source) + str(self.cap.isOpened())) def is_opened(self): return self.cap.isOpened() def run(self): # ret, frame = self.cap.read() while True: if self.stop_cap is True: print('cap stop !') self.cap.release() break if self.lock.acquire(): ret, frame = self.cap.read() if ret is True: self.img = frame self.lock.release() time.sleep(0.01) def get_img(self): frame = None while True: if self.lock.acquire(): frame = self.img self.lock.release() break return frame def stopp(self): self.stop_cap = True
在网上搜索树莓派驱动2个摄像头的回答或者博客里都是教我们这样写的,稍微特别一点的就是上述程序里专门写了一个类来做摄像头的初始化,但是,事情的发展总是不遂人愿的,python解释器报了的错误。
错误截图
摄像头0的初始化是正常的,而摄像头1的初始化出现了问题,这个语句就是告诉我们,程序需要根据index 1去找摄像头1,但是找不到,为什么呢?开始我也是百思不得其解,后来经过仔细分析,终于解决了问题。
解决方法
首先我们用ls /dev/video*
命令去查找接入树莓派的设备,通过插拔摄像头0和摄像头1的USB接口观察当前接入树莓派的设备
摄像头0,1都插上
只插了摄像头0
一个摄像头都没插
聪明的大家肯定已经发现了其中的规律,摄像头0对应的是/dev/video0
和/dev/video1
这2个设备,摄像头1对应的是/dev/video2
和/dev/video3
这2个设备,这说明一个KS2A242摄像头对应了2个设备,因此摄像头1的初始化时候的设备参数不应该是“1”,而应该是“2”,因此我将我的初始化程序修改成了如下:
while(1): self.cap0 = MyThreadCapture(0, CAPTURE_FRAME_WIDTH, CAPTURE_FRAME_HEIGHT) if(self.cap0.is_opened()): self.cap0.setDaemon(True) self.cap0.start() break while(1): self.cap1 = MyThreadCapture(2, CAPTURE_FRAME_WIDTH, CAPTURE_FRAME_HEIGHT) if(self.cap1.is_opened()): self.cap1.setDaemon(True) self.cap1.start() break
最终运行该python脚本,问题解决!
思考
其实接入单个外设之后树莓派的挂载设备数可能是多个的,因此我们需要根据实际接入的设备数量去操作对应的外设,网上的资源很多,查找的时候做为参考即可,更多的还是需要自己的思考。
文章来源: blog.csdn.net,作者:GYH_better_coder,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/weixin_43454320/article/details/116105369