PyQt(Python+Qt)实战:使用QCamera、QtMultimedia等实现摄像头拍照
一、概述
在PyQt中,可以使用QCamera、QCameraViewfinder、QCameraViewfinderSettings等一系列多媒体操作相关类实现摄像头操作。用这些类不足50行代码+UI界面就可以快速实现简单的摄像头拍照。
二、相关类介绍
2.1、QCamera类
QCamera类是直接对应摄像头的类,包括如下方法:
1、QCamera()
创建摄像头类对象实例。
2、setViewfinder(viewfinder)
设置取景器,取景器就是将图像实时在屏幕显示,就跟相机的屏幕一样,参数是取景器类的实例对象。
3、setViewfinderSettings(viewFinderSettings)
设置取景器相关参数如分辨率等,请见QCameraViewfinderSettings类的介绍。
4、setCaptureMode(mode)
设置捕获图像(拍照)的保存模式,参数mode类型为枚举类型QCamera.CaptureModes,包括如下取值:
※ CaptureViewfinder:相机仅配置为显示取景器
※ CaptureStillImage:相机配置为静态帧捕获
※ CaptureVideo:相机配置为视频捕获
以上三个值可以通过or操作组合起来使用,经老猿验证,如果是拍照以上三个值都支持,CaptureVideo在windows系列操作系统下不支持。
5、start()打开相机
相机打开后取景器就能显示镜头范围内的内容。
6、stop()关闭相机
关闭相机后,取景器不再显示视频。
2.2、QCameraViewfinderSettings类
QCameraViewfinderSettings类是专门用于设置取景器参数的,常用的设置方法(读取方法名去掉set后首字母改为小写就可以了)如下:
1、setResolution(width,height)
以像素为单位设置取景器的分辨率。
2、setPixelAspectRatio(int horizontal, int vertical)
设置取景器的纵横比
3、setMinimumFrameRate(qreal rate)
设置取景器的最小帧速率(以每秒帧数为单位)
4、setMaximumFrameRate(qreal rate)
设置取景器的最大帧速率(以每秒帧数为单位)
5、setPixelFormat(QVideoFrame.PixelFormat format)
设置取景器图像的像素格式,即在内存中的存放格式(或编码方式),其类型为枚举类型enum QVideoFrame.PixelFormat,取值范围如下:
以上方法不需要都使用,具体看应用的要求。
2.3、QCameraViewfinder类
QCameraViewfinder类是取景器对应类,这个类主要的方法就是构造方法,带一个参数指向取景器放置的父对象,不过多介绍。
2.4、QCameraImageCapture类
QCameraImageCapture是用于捕获图像的,主要有如下方法:
1、setCaptureDestination(CaptureDestinations destination)
setCaptureDestination方法设置捕获的图像是输出到文件还是在内存中缓存,参数destination是枚举类型CaptureDestinations ,有如下2个取值:
*※ CaptureToFile:对应值为 1,表示输出到文件
*※ CaptureToBuffer:,对应值为2,表示输出到缓存,可以在缓存中进一步处理
2、capture( QString filename )
capture从当前视频中捕获一帧作为图像保存,保存到参数指定的文件中。
三、实现步骤
3.1、设计界面
通过Qt Designer设计界面如下,窗口为QMainWindow(也可以为QWidget):
在该界面上有两个按钮用于操作,一个GroupBox用于在内存放取景器界面,同时设计了多个布局,为了取景器显示在安排的位置,且能正常显示,在GroupBox内放了一个名字为camerLayout水平布局。
3.2 设计信号和槽的连接
在两个按钮的clicked信号上各自连接了一个槽函数,分别为switchCamera(相机的开关)和takePic(拍照),如图:
3.3、通过PyUIC生成界面代码
将设计的界面保存到CamerWin.ui中,按照《第15.7节 PyQt入门学习:PyQt5应用构建详细过程介绍》将界面生成代码CamerWin.py,对应的界面类为Ui_CameraWin。
3.4、从界面类派Ui_CameraWin生子类
3.4.1、从界面类及QMainWindow派生自定义类CameraMainWin
class CameraMainWin(QtWidgets.QMainWindow,CameraWin.Ui_CameraWin):
注意:如窗口是QWidget类,则要将QMainWindow换为QWidget。
3.4.2、定义CameraMainWin的构造方法
构造方法首先要执行标准化的自定义类构造必须执行代码以完成界面初始化:
super(CameraMainWin, self).__init__()
self.setupUi(self)
然后完成QCamera对象、取景器参数对象、取景器对象、图像捕获对象的定义和初始化:
self.camera = QCamera()
self.camera.setCaptureMode(QCamera.CaptureViewfinder)
self.cameraOpened = False# 设置相机打开状态为未打开
#设置取景器分辨率
viewFinderSettings = QCameraViewfinderSettings ()
viewFinderSettings.setResolution(800,600)
self.camera.setViewfinderSettings(viewFinderSettings)
#初始化取景器
self.viewCamera = QtMultimediaWidgets.QCameraViewfinder(self)
self.camera.setViewfinder(self.viewCamera)
self.camerLayout.addWidget(self.viewCamera) #取景器放置到预留的布局中
#设置图像捕获
self.capImg = QCameraImageCapture(self.camera )
self.capImg.setCaptureDestination(QCameraImageCapture.CaptureToFile)
注意:在构造方法中将取景器放置到了预留的布局中
3.4.3、定义槽函数switchCamera执行相机的开关处理
def switchCamera(self):
if not self.cameraOpened :
self.camera.start() #打开相机
self.cameraOpened = True
self.btnSwitchCamera.setText("关闭摄像头")
else:
self.camera.stop() #关闭相机
self.cameraOpened = False
self.btnSwitchCamera.setText("打开摄像头")
3.4.4、定义槽函数takePic执行拍照
def takePic(self):#拍照响应槽函数,照片保存到文件
FName = fr"c:\temp\capimg\cap{time.strftime('%Y%m%d%H%M%S', time.localtime())}" #文件名初始化
self.capImg.capture(FName)
print(f"捕获图像保存到文件:{FName}.jpg")
3.4.5、主代码中创建自定义类实例并打开窗口
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
W = CameraMainWin()
W.show()
sys.exit(app.exec_())
四、完整的主程序代码
主程序完整代码才46行,如下:
import time,sys
from PyQt5 import QtWidgets,QtMultimediaWidgets
from PyQt5.QtMultimedia import QCamera,QCameraImageCapture,QCameraViewfinderSettings
import CameraWin
class CameraMainWin(QtWidgets.QMainWindow,CameraWin.Ui_CameraWin):
def __init__(self):
super(CameraMainWin, self).__init__()
self.setupUi(self)
#定义相机实例对象并设置捕获模式
self.camera = QCamera()
self.camera.setCaptureMode(QCamera.CaptureViewfinder)
self.cameraOpened = False# 设置相机打开状态为未打开
#设置取景器分辨率
viewFinderSettings = QCameraViewfinderSettings ()
viewFinderSettings.setResolution(800,600)
self.camera.setViewfinderSettings(viewFinderSettings)
#初始化取景器
self.viewCamera = QtMultimediaWidgets.QCameraViewfinder(self)
self.camera.setViewfinder(self.viewCamera)
self.camerLayout.addWidget(self.viewCamera) #取景器放置到预留的布局中
#设置图像捕获
self.capImg = QCameraImageCapture(self.camera )
self.capImg.setCaptureDestination(QCameraImageCapture.CaptureToFile) #CaptureToBuffer
#相机(摄像头)开关处理
def switchCamera(self):
if not self.cameraOpened :
self.camera.start()
self.cameraOpened = True
self.btnSwitchCamera.setText("关闭摄像头")
else:
self.camera.stop()
self.cameraOpened = False
self.btnSwitchCamera.setText("打开摄像头")
def takePic(self):#拍照响应槽函数,照片保存到文件
FName = fr"c:\temp\capimg\cap{time.strftime('%Y%m%d%H%M%S', time.localtime())}" #文件名初始化
self.capImg.capture(FName)
print(f"捕获图像保存到文件:{FName}.jpg")
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
W = CameraMainWin()
W.show()
sys.exit(app.exec_())
五、运行截图
运行后开启摄像头后的界面如下:
另外如果没有将取景器放到对应布局中,则运行界面会如下:
可以看到取景器已经缩小到左上角黄色荧光笔标记的角落。
六、小结
本节详细介绍了PyQt中使用QCamera类实现使用电脑摄像头拍照的步骤及相关类,通过不到50行代码就实现了相关功能。当然如果要做功能更完善的代码还可以有许多方面的功能需要实现,包括取景器、相机、图像等都有更多的可以设置的参数,几个类还有些信号如error信号、状态变更信号等可以定义槽函数响应。
另外需要说明的一点是,通过PyQt的多媒体操作类QMediaRecorder可以捕获视频流,但该类只能在安卓或Mac操作系统下使用,windows下不能使用。详细请参考官网相关说明(https://doc.qt.io/qt-5/qtmultimedia-windows.html)。
老猿Python,跟老猿学Python!
博文目录
博客地址
PyQt(Python+Qt)实战:使用QCamera、QtMultimedia等实现摄像头拍照的更多相关文章
- 第15.25节 PyQt(Python+Qt)入门学习:Model/View开发实战--使用QTableView展示Excel文件内容
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.概述 在前面的订阅专栏<第十九章.Model/View开发:QTableView的功能及属 ...
- PyQt(Python+Qt)学习随笔:利用QWidget部件的palette以及ColorGroup、colorRole局部调整部件的特定范围颜色
专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 在<PyQt(Python+Qt)学习随笔:QWidget部件的 ...
- 第15.33节 PyQt(Python+Qt)入门学习:containers容器类部件QTabWidget选项窗部件简介
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.概述 容器部件就是可以在部件内放置其他部件的部件,在Qt Designer中可以使用的容器部件有 ...
- 第15.31节 PyQt(Python+Qt)入门学习:containers容器类部件GroupBox分组框简介
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.概述 容器部件就是可以在部件内放置其他部件的部件,在Qt Designer中可以使用的容器部件有 ...
- 第15.29节 PyQt(Python+Qt)入门学习:containers容器类部件QScrollArea滚动区域详解
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.概述 Scroll Area提供了一个呈现在其他部件上的可滚动区域视图,滚动区域用于显示框架内的 ...
- 第15.28节 PyQt(Python+Qt)入门学习:Model/View架构中的便利类QTableWidget详解
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.引言 表格部件为应用程序提供标准的表格显示工具,在表格内可以管理基于行和列的数据项,表格中的最大 ...
- 第15.27节 PyQt(Python+Qt)入门学习:Model/View架构中的便利类QTreeWidget详解
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.引言 树部件(Tree Widget)是Qt Designer中 Item Widgets(It ...
- 第15.26节 PyQt(Python+Qt)入门学习:Model/View架构中的便利类QListWidget详解
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.概述 列表部件(List Widget)对应类QListWidget,是从QListView派生 ...
- PyQt(Python+Qt)学习随笔:视图中类QAbstractItemView的dragDropOverwriteMode属性不能覆盖写的问题
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 在<PyQt(Python+Qt)学习随笔:视图中类QAbstractItemView的dra ...
- PyQt(Python+Qt)学习随笔:视图中类QAbstractItemView的dragDropOverwriteMode属性
老猿Python博文目录 老猿Python博客地址 一.属性的作用 dragDropOverwriteMode属性用于控制视图的拖放行为,如果其值为True,则视图中选定的数据将在拖拽数据放下时被覆盖 ...
随机推荐
- C++变量的存储类型
C++变量和函数包括两个属性:数据类型和数据的存储类型.存储类型是指数据在内存中存储的方式.变量的存储类型分为四种:自动类型(auto),寄存器类型(register).静态类型(static)外部类 ...
- 使用switch计算出某年某月某日是今年的第几天,输出一直是当月天数
package com.cx.Switch; import java.util.Scanner; /** * 计算出某年某月某日是今年的第几天 * 使用switch */ public class S ...
- 执行 yarn init报错,如何解决?
安装yarn以后执行yarn init 命令来初始化项目 报错如下所示: 解决方法: 1.先用npm init初始化项目 在初始化的最后一步 is this ok(yes)? 输入yes回车后,可能会 ...
- 前端性能优化之 gzip+cache-control
刚刚在Node.js环境下使用gzippo模块进行了测试. 使用gzip的压缩率惊人的好,达到了50%以上. 再加上express的staticCache,配合cache-control max-ag ...
- 转 Cache一致性和内存模型
卢本伟牛逼,写得很好 https://wudaijun.com/2019/04/cpu-cache-and-memory-model/ 本文主要谈谈CPU Cache的设计,内存屏障的原理和用法,最后 ...
- 如何实现Http请求报头的自动转发[应用篇]
如今的应用部署逐渐向微服务化发展,导致一个完整的事务往往会跨越很多的应用或服务,出于分布式链路跟踪的需要,我们往往将从上游服务获得的跟踪请求报头无脑地向下游服务进行转发.本文介绍的这个名为Header ...
- 五:key关键字 string字符串 list列表 set集合 Zset有序集合
key 1.keys 命令用于查找所有符合给定模式 pattern 的 key . keys * 查找所有的key返回一个列表 2.EXISTS xxx 检查是否有指定名字为xxx的key 有就返回 ...
- python执行rados命令例子
前言 我们以前的管理平台在python平台下面做的,内部做的一些操作采用的是命令执行,然后解析的方式去做的,ceph自身有python的rados接口,可以直接调用原生接口,然后直接解析json的方式 ...
- 如何在所有的mon的损坏情况下将数据恢复如初
本篇主题 在mon无法启动,或者所有的mon的数据盘都损坏的情况下,如何把所有的数据恢复如初 写本章的缘由 在ceph中国的群里有看到一个技术人员有提到,在一次意外机房掉电后,三台mon的系统盘同时损 ...
- Boost命令行解释器的简单使用:Boost.Program_options
简介 如果使用比较多的命令行程序的话,对于命令行参数的输入肯定不会陌生,大部分的程序都是通过类似下面的形式进行输入的,比如熟悉的ls ls --all -l --color=auto 这里面包含了三种 ...