python - 相机视频和使用 Python Kivy 拍照
问题描述
我正在使用屏幕管理器,并希望在访问 ScreenThree 时显示相机图像。我希望使用 cv2 相机代码。单击按钮后,我希望捕获一张图片,然后使用该图像执行代码。到目前为止,我在互联网上找到了一个线程版本,可以很好地显示相机输入。通过单击按钮捕获图片正在挫败我的努力。
Screen3 包含一个放置视频的地方和一个执行代码拍照的按钮。
<ScreenThree>:
name: "screenthree"
FloatLayout:
Image:
id: vid #Vido image
pos_hint: {'x':0.0, 'y':0.2}
size_hint: 1.0, 0.8
Image:
source: "clue.png" # Decorative image
size_hint:(0.20,0.20)
pos_hint: {"x":0.05,"y":0.75}
Button:
text: "Click to scan"
background_color : 0, 0, 1, 1
size_hint: 0.2,0.05
pos_hint: {"x":0.25,"y":0.85}
on_press: root.takepic()
Button:
text: "Go to next screen" # Screen4
background_color : 1, 0, 1, 1
size_hint: 0.2,0.05
pos_hint: {"x":0.45,"y":0.85}
on_press:
root.manager.transition.direction = 'left'
root.manager.transition.duration = 1
root.manager.current = 'screen_four'
线程代码是(我不知道隐藏窗口是关于什么的);
class ScreenApp(App):
def build(self):
threading.Thread(target=self.doit, daemon=True).start()
self.new_screen = ScreenThree()
return screen_manager
def doit(self):
self.do_vid = True
cv2.namedWindow('Hidden', cv2.WINDOW_NORMAL | cv2.WINDOW_FREERATIO)
cv2.resizeWindow('Hidden', 0, 0)
cam=cv2.VideoCapture('/dev/video0', cv2.CAP_V4L)
while (self.do_vid):
ret, frame = cam.read()
Clock.schedule_once(partial(self.display_frame, frame))
cv2.imshow('Hidden', frame)
cv2.waitKey(1)
cam.release()
cv2.destroyAllWindows()
def display_frame(self, frame, dt):
texture = Texture.create(size=(frame.shape[1], frame.shape[0]), colorfmt='bgr')
texture.blit_buffer(frame.tobytes(order=None), colorfmt='bgr', bufferfmt='ubyte')
texture.flip_vertical()
self.root.get_screen('screen_three').ids.vid.texture = texture
我将捕获图像的代码放在 ScreenThree 类中。单击按钮会转移到 takepic() 方法,但无法读取图像,尝试写入空图像时会崩溃。/dev/video0 上的摄像头仍由线程代码持有。如何访问相机以捕捉照片,或者如何提示线程例程为我拍照。
class ScreenThree(Screen):
def takepic(self):
cap = cv2.VideoCapture('/dev/video0', cv2.CAP_V4L)
# set dimensions
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
# take frame
ret, frame = cap.read()
# write frame to file
cv2.imwrite('image.jpg', frame)
# release camera
cap.release()
解决方案
由于您的线程已经从相机捕获帧,您可以只使用已捕获的当前帧,如下所示:
def doit(self):
self.do_vid = True
self.frame = None # add reference to the current frame
cv2.namedWindow('Hidden', cv2.WINDOW_NORMAL | cv2.WINDOW_FREERATIO)
cv2.resizeWindow('Hidden', 0, 0)
cam=cv2.VideoCapture('/dev/video0', cv2.CAP_V4L)
while (self.do_vid):
ret, self.frame = cam.read() # save the current frame
Clock.schedule_once(partial(self.display_frame, self.frame))
cv2.imshow('Hidden', self.frame)
cv2.waitKey(1)
cam.release()
cv2.destroyAllWindows()
在方法中使用当前帧takepic()
:
class ScreenThree(Screen):
def takepic(self):
# get current frame
frame = App.get_running_app().frame
# write frame to file
cv2.imwrite('image.jpg', frame)
推荐阅读
- laravel - Laravel 电子邮件验证问题并停止整个应用程序
- amazon-web-services - aws credentails 在安装在 EC2 中的容器中工作
- c# - 如何为 nuget 包构建具有多个 .net 框架的项目
- javascript - 如何使用初始化模型作为模态打开的唯一标识符?
- css - 使用材质 ui 中的 withStyle HOC 的 CSS 选择器
- python - describe().to_csv 缺少 csv 文件中的描述列
- swift - 打印字符串值并将其显示为纯文本的问题
- bash - 如何将 xargs -P 20 与 curl 和主机列表一起使用
- sql - 基于sql中输入范围的数字范围拆分
- mysql - 如何以正确的顺序创建计算日期字段(MySQL)