基于PySide2实现调用本地摄像头抓拍并保存照片(Python版本)

因为横向课题需要,这是其中的一个小小的功能,单独拎出来作为一个小demo,方便后续学习使用

项目实现功能:
点击open按钮,摄像头开启,实时捕获周围图像并显示
点击capture按钮,保存摄像头照片,类似截图功能
点击close按钮,关闭摄像头

一、Qt页面设计

创建一个Main Window
在这里插入图片描述
所用到的控件主要有:一个Label、三个Push Button
在这里插入图片描述
我这里保存的名称为:capture.ui

二、创建项目

其实就用到一个文件就行
项目结构如下:
在这里插入图片描述
一个主函数文件main.py,一个ui界面capture.ui

三、导包

from PySide2.QtWidgets import QApplication
from PySide2.QtUiTools import QUiLoader
import cv2
from PySide2.QtWidgets import *
from PySide2.QtGui import QImage, QPixmap
from PySide2.QtCore import Qt, QTimer
import time

四、系统初始化

self.ui = QUiLoader().load('./capture.ui')
把设计好的UI界面加载进来

self.camera_timer = QTimer()
设置一个定时器

    def __init__(self):# 加载ui文件self.ui = QUiLoader().load('./capture.ui')self.output_size = 150self.camera_timer = QTimer()# 获取显示器分辨率信息self.desktop = QApplication.desktop()self.screenRect = self.desktop.screenGeometry()self.screenheight = self.screenRect.height()self.screenwidth = self.screenRect.width()print("Screen height {}".format(self.screenheight))print("Screen width {}".format(self.screenwidth))self.ui.setFixedSize(self.ui.width(), self.ui.height())

五、窗口初始化

对每个按钮绑定不同的事件

self.ui.pushButton.clicked.connect(self.open_camera)
pushButton对应的是open,与打开摄像头功能open_camera这个函数进行事件绑定
同理
self.ui.pushButton_2.clicked.connect(self.getcapture)
pushButton_2对应的是capture,与拍摄保存照片功能getcapture这个函数进行事件绑定
self.ui.pushButton_3.clicked.connect(self.close_camera)
pushButton_3对应的是close,与关闭摄像头功能close_camera这个函数进行事件绑定
self.camera_timer.timeout.connect(self.show_image)
定时器超时show_image函数进行事件绑定

self.i = i = 0;
这里的i用于捕获多张照片的时候命名不重复

    def window_init(self):self.ui.pushButton.clicked.connect(self.open_camera)self.ui.pushButton_2.clicked.connect(self.getcapture)self.ui.pushButton_3.clicked.connect(self.close_camera)self.camera_timer.timeout.connect(self.show_image)self.i = i = 0;

六、打开摄像头函数——open_camera实现

cv2.VideoCapture(0),调用本地摄像头
若是外设就把参数0改为1
若要播放某段视频就把参数0改为视频的路径即可,记得是字符串形式哈

self.camera_timer.start(40),每40ms读取一次,只要读取速度够快,人眼感觉不出来,看到的就是流畅的实时视频

 def open_camera(self):self.capture = cv2.VideoCapture(0)  # 摄像头self.camera_timer.start(40)  # 每40毫秒读取一次,即刷新率为25帧print("open_camera is successful")

七、关闭摄像头函数——close_camera实现

camera_timer.stop(),摄像头定时器关闭,停止读取
capture.release(),用于捕获摄像头的每帧图片,释放摄像头资源
ui.label.clear(),将显示图片的lable控件内容给清除
ui.label.setText("TextLabel"),在控件上显示点字符串

    def close_camera(self):  # 关闭摄像头self.camera_timer.stop()  # 停止读取self.capture.release()  # 释放摄像头self.ui.label.clear()  # 清除DisplayInterface组件上的图片self.ui.label.setText("TextLabel")  # 设置文字在界面上

八、定时器超时绑定事件函数——show_image实现

打开摄像头之后每隔40ms捕获读取一张,那么这之间的空窗期都干些啥由show_image函数进行控制

flag, self.image = self.capture.read() # 从视频流中读取图片
学过OpenCV的同学就应该知道,flag是个bool类型表示是否读取成功,image就是每一帧的图像

width, height, _ = self.image.shape
得到摄像头照片的宽高信息

self.image_show = cv2.flip(self.image, 1)
因为摄像头拍摄都是镜像,需要中心反转一下

self.image_show = cv2.cvtColor(self.image_show, cv2.COLOR_BGR2RGB)
OpenCV中图像时BGR,但是PySide2里面的图像是RGB,故需要转换一下

self.image_file = QImage(self.image_show.data, height, width, QImage.Format_RGB888)
固定格式,用于PySide里面的图像显示

self.ui.label.setPixmap(QPixmap.fromImage(self.image_file))
将图片image_file显示到label控件上

    def show_image(self):  # 显示图片flag, self.image = self.capture.read()  # 从视频流中读取图片width, height, _ = self.image.shape  # 行:宽,列:高self.image_show = cv2.flip(self.image, 1)  # 水平翻转,因为摄像头拍的是镜像的。self.image_show = cv2.cvtColor(self.image_show, cv2.COLOR_BGR2RGB)  # opencv读的通道是BGR,要转成RGBself.image_file = QImage(self.image_show.data, height, width, QImage.Format_RGB888)self.ui.label.setPixmap(QPixmap.fromImage(self.image_file))self.ui.label.setScaledContents(True)  # 让图片自适应 label 大小

九、捕获摄像头函数——getcapture实现

self.i = self.i + 1
每次捕获照片都要自加一下,为了防止名称重复

date_name = time.strftime("%Y%m%d")
获取当前的年月日

image = cv2.flip(self.image, 1)
因为image是摄像头捕获得到的图片,是镜像过的,故需要通过flip函数镜像转换一下

cv2.imwrite("./{}_capture_{}.jpg".format(str(date_name), self.i), image)
将图片保存到当前路径下,命名格式为当前年月日_capture_第几次

self.camera_timer.stop() ,停止读取
self.capture.release(),释放摄像头资源

    def getcapture(self):self.i = self.i + 1;date_name = time.strftime("%Y%m%d")print("getcapture")print(date_name)image = cv2.flip(self.image, 1)cv2.imwrite("./{}_capture_{}.jpg".format(str(date_name), self.i), image)self.camera_timer.stop()  # 停止读取self.capture.release()  # 释放摄像头

十、主函数入口

gui = Mainwindow()
我的这个类为Mainwindow,当然要根据实际情况定义声明即可

if __name__ == '__main__':app = QApplication([])gui = Mainwindow()  #初始化gui.window_init()gui.ui.show() #将窗口控件显示在屏幕上app.exit(app.exec_())

十一、完整代码

main.py

from PySide2.QtWidgets import QApplication
from PySide2.QtUiTools import QUiLoader
import cv2
from PySide2.QtWidgets import *
from PySide2.QtGui import QImage, QPixmap
from PySide2.QtCore import Qt, QTimer
import timeclass Mainwindow(object):def __init__(self):# 加载ui文件self.ui = QUiLoader().load('./capture.ui')self.output_size = 150self.camera_timer = QTimer()# 获取显示器分辨率self.desktop = QApplication.desktop()self.screenRect = self.desktop.screenGeometry()self.screenheight = self.screenRect.height()self.screenwidth = self.screenRect.width()print("Screen height {}".format(self.screenheight))print("Screen width {}".format(self.screenwidth))self.ui.setFixedSize(self.ui.width(), self.ui.height())def window_init(self):self.ui.pushButton.clicked.connect(self.open_camera)self.ui.pushButton_2.clicked.connect(self.getcapture)self.ui.pushButton_3.clicked.connect(self.close_camera)self.camera_timer.timeout.connect(self.show_image)self.i = i = 0def getcapture(self):self.i = self.i + 1date_name = time.strftime("%Y%m%d")print("getcapture")print(date_name)image = cv2.flip(self.image, 1)cv2.imwrite("./{}_capture_{}.jpg".format(str(date_name), self.i), image)self.camera_timer.stop()  # 停止读取self.capture.release()  # 释放摄像头def open_camera(self):self.capture = cv2.VideoCapture(0)  # 摄像头self.camera_timer.start(40)  # 每40毫秒读取一次,即刷新率为25帧print("open_camera is successful")def close_camera(self):  # 关闭摄像头self.camera_timer.stop()  # 停止读取self.capture.release()  # 释放摄像头self.ui.label.clear()  # 清除DisplayInterface组件上的图片self.ui.label.setText("TextLabel")  # 设置文字在界面上def show_image(self):  # 显示图片flag, self.image = self.capture.read()  # 从视频流中读取图片width, height, _ = self.image.shape  # 行:宽,列:高self.image_show = cv2.flip(self.image, 1)  # 水平翻转,因为摄像头拍的是镜像的。self.image_show = cv2.cvtColor(self.image_show, cv2.COLOR_BGR2RGB)  # opencv读的通道是BGR,要转成RGBself.image_file = QImage(self.image_show.data, height, width, QImage.Format_RGB888)self.ui.label.setPixmap(QPixmap.fromImage(self.image_file))self.ui.label.setScaledContents(True)  # 让图片自适应 label 大小if __name__ == '__main__':app = QApplication([])gui = Mainwindow()  #初始化gui.window_init()gui.ui.show() #将窗口控件显示在屏幕上app.exit(app.exec_())

十二、运行结果

在这里插入图片描述
目前项目下一张图片都没
在这里插入图片描述

open
在这里插入图片描述

capture
捕捉之后项目下会保存刚才抓拍的图片
在这里插入图片描述

close
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/736622.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

日期工具的逻辑与数据请求函数的完善

src\libs\utils.js 获取当前日期格式 /*** 获取当前日期格式* param {*} field * returns */ function getNowDate(field) {const date new Date()let year date.getFullYear(),month date.getMonth() 1,day date.getDate()switch (field) {case day:return ${year}-${mo…

02- 使用Docker安装RabbitMQ

使用Docker安装RabbitMQ 下载安装镜像 方式一: 启动docker服务,然后在线拉取 # 在线拉取镜像 docker pull rabbitmq:3-management# 使用docker images查看是否已经成功拉取方式二: 从本地加载 ,将RabbitMQ上传到虚拟机中后使用命令加载镜像即可 docker load -i mq.tar启动M…

LLM实施的五个阶段

原文地址:Five Stages Of LLM Implementation 大型语言模型显着提高了对话式人工智能系统的能力,实现了更自然和上下文感知的交互。这导致各个行业越来越多地采用人工智能驱动的聊天机器人和虚拟助手。 2024 年 2 月 20 日 介绍 从LLMs的市场采用情况可以…

LabelImg:一个简单易用的图像标注工具

目录 LabelImg是什么? 如何使用LabelImg进行图像标注? LabelImg的优势和应用场景 在哪里下载它 随着人工智能技术的不断发展,机器学习和深度学习在图像识别、目标检测等领域中得到了广泛的应用。而要训练一个有效的模型,通常需…

Vue3+ts(day02:CompositionAPI、setup)

学习源码可以看我的个人前端学习笔记 (github.com):qdxzw/frontlearningNotes 觉得有帮助的同学,可以点心心支持一下哈(笔记是根据b站上学习的尚硅谷的前端视频【张天禹老师】,记录一下学习笔记,用于自己复盘,有需要学…

备忘录怎么导出数据 备忘录数据导出方法

在忙碌的生活中,我时常依赖于备忘录来记录重要的信息,从工作截止日期到生活琐事,无一不靠它来帮我分担记忆的压力。但随着时间的推移,我发现有时候我不仅仅需要在软件内查看这些信息,还需要将它们导出,或许…

【数据库】软件测试之MySQL数据库练习题目

有表如下: Student 学生表 SC 成绩表 Course 课程表 Teacher 老师表 每个学生可以学习多门课程,每一个课程都有得分,每一门课程都有老师来教,一个老师可以教多个学生 1、查询姓‘朱’的学生名单 select * from Student whe…

【深度学习笔记】优化算法——Adam算法

Adam算法 🏷sec_adam 本章我们已经学习了许多有效优化的技术。 在本节讨论之前,我们先详细回顾一下这些技术: 在 :numref:sec_sgd中,我们学习了:随机梯度下降在解决优化问题时比梯度下降更有效。在 :numref:sec_min…

力扣--动态规划5.最长回文子串

class Solution { public:string longestPalindrome(string s) {// 获取输入字符串的长度int n s.size();// 如果字符串长度为1,直接返回原字符串,因为任何单个字符都是回文串if (n 1)return s;// 创建一个二维数组dp,用于记录子串是否为回…

React-路由小知识

1.默认路由 说明:当访问的是一级路由时,默认的二级路由组件可以得到渲染,只需要在二级路由的位置去掉path,设置index.属性为true。 2.404路由 说明:当浏览器输入ul的路径在整个路由配置中都找不到对应的pth,为了用户体验&#x…

《农商网》商业计划书(附模板下载)

在当今互联网高速发展的时代,农业与电子商务的结合成为了新的经济增长点。《农商网》商业计划书详细阐述了一个以大学生创业为核心的创新项目,旨在通过打造一个全新的农产品在线交易平台,实现农产品的高效流通和价值最大化。该计划书首先对市…

amv是什么文件格式?如何播放amv视频?

AMV文件格式源自于中国公司Actions Semiconductor,最初作为其MP4播放器中使用的专有视频格式。产生于数码媒体发展的需求下,AMV格式为小屏幕便携设备提供了一种高度压缩的视频存储方案。 AMV文件格式的主要特性与使用场景 AMV格式以其独特的特性在小尺寸…

【活动】探索人工智能的“迷惑瞬间”:真实体验与技术挑战

🌈个人主页: 鑫宝Code 🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础 ​💫个人格言: "如无必要,勿增实体" 文章目录 标题:探索人工智能的“迷惑瞬间”:真实体验与技术挑战引言…

Elasticsearch:dense vector 数据类型及标量量化

密集向量(dense_vector)字段类型存储数值的密集向量。 密集向量场主要用于 k 最近邻 (kNN) 搜索。 dense_vector 类型不支持聚合或排序。 默认情况下,你可以基于 element_type 添加一个 dend_vector 字段作为 float 数值数组: …

学习Java的第七天

目录 一、什么是数组 二、作用 三、如何使用数组 1、声明数组变量 2、创建数组 示例: 3、数组的使用 示例: 4、数组的遍历 for循环示例(不知道for循环的可以查看我之前发的文章) for-each循环(也就是增强for…

Unity基础学习

目录 基础知识点3D数学——基础Mathf三角函数坐标系 3D数学——向量向量模长和单位向量向量的加减乘除向量点乘向量叉乘向量插值运算 3D数学——四元数为何使用四元数四元数是什么四元数常用方法四元数计算 MonoBehavior中的重要内容延迟函数协同程序协同程序原理 Resources资源…

STM32CubeIDE基础学习-STM32CubeIDE软件工程文件拷贝粘贴

STM32CubeIDE基础学习-STM32CubeIDE软件工程文件拷贝粘贴 前言 在后面开发程序时,往往不需要再重新新建工程的了,可以直接在原有的工程基础上直接复制粘贴新增功能就可以了。 具体的操作方法步骤如下介绍: 第一步:找到一个原有的…

力扣中档题的简单写法:在链表中插入最大公约数

其实暴力遍历开数组也可以,但不如以下新建链表块的方法简单 int FindCommDivisor(int num1, int num2) {int n;int i;n fmin(num1, num2);for (i n; i > 1; i--) {if (num1 % i 0 && num2 % i 0) {return i;}}return 0; }struct ListNode *insertGr…

Mock.js 基本语法与应用笔记

🌟 前言 欢迎来到我的技术小宇宙!🌌 这里不仅是我记录技术点滴的后花园,也是我分享学习心得和项目经验的乐园。📚 无论你是技术小白还是资深大牛,这里总有一些内容能触动你的好奇心。🔍 &#x…

python 导入excel空间三维坐标 生成三维曲面地形图 5-3、线条平滑曲面且可通过面观察柱体变化(三)

环境 python:python-3.12.0-amd64 包: matplotlib 3.8.2 pandas 2.1.4 openpyxl 3.1.2 scipy 1.12.0 import pandas as pd import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D from scipy.interpolate import griddata from matplotlib.c…