基于pyqt5的图书管理系统(python)(开源)

序言

        源项目是从github上下载的开源,后续笔者加入了一些视觉处理的元素(人脸注册、人脸识别、二维码扫描、YOLOv10),因为是为了应付课设,所以有些功能可能比较鸡肋。多说无益,下边是相关介绍。

程序框架

(程序框架图)

        程序的页面部分使用的pyqt5的pycharm插件生成的,然后通过中间层代码与数据库进行连接,完成对数据的操作,人脸识别部分应用在登录和注册部分,二维码扫描应用在添加图书的部分,其中监控部分指的是YOLOv10的相关功能,下边会具体介绍。

 (代码结构)

         face_image存放的是经过人脸注册的照片,res存放的软件图标以及界面的相关属性,ui存放的是qt生成的界面代码和.ui文件,view存放的是连接ui界面用户编写的相关代码,generate_date.py是用来生成图书管理系统的相关数据库,delet.py是用来删除生成的数据库,main.py是主程序入口。

代码介绍

        由于笔者仅仅是添加了一些功能,原有代码并未做太多更改,所以只对自己的功能进行介绍。

        人脸注册

        实现界面效果,用户输入用户名和密码,初始状态关闭相机和开始注册为不可点击状态,点击开始注册后,当识别到人脸时便可点击,点击确认注册后,便会将当前帧保存,具体见代码。

(登录主界面) 

 (人脸注册窗口)

        人脸注册的接口位于login_window.py内,部分代码如下

    def face_login(self):

        self.face_window = FaceWindow()#唤起人脸注册窗口
        self.face_window.show()
        self.face_window.face_don_signal.connect(self.face_logein_sucess)#将完成信号连接到函数

    def face_logein_sucess(self,username):

        db = DBHelp()
        count, res = db.query_super(table_name='user', column_name='username', condition=username)#查找是否已经有同名用户名
        if count == 0:#如果没有
            self.login_done_signal.emit(1)#发送注册完成信号
            return
        self.role = res[0][3]
        self.main_window = MainWindow(login=self, username=username, role=self.role)
        #以该用户名登录
        self.main_window.show()#显示主窗口
        self.close()#关闭当前窗口

        face_register_window.py代码,主要实现调用了face_recognition开源库实现的人脸识别,将注册的人脸保存于face_image文件夹内,文件名为"用户名.jpg"便于人脸登录。

'''
文件名:face_register_window.py
概述:人脸识别注册窗口
'''

import os
import sys
import cv2
import face_recognition
import numpy as np
from PyQt5.QtCore import pyqtSignal, Qt, QTimer
from PyQt5.QtGui import QIcon, QImage, QPixmap
from PyQt5.QtWidgets import QMainWindow, QMessageBox, QApplication
from ui.face_register_window import Ui_FaceregisterWindow
from util.common_util import APP_ICON, SYS_STYLE, CLOSE_IMAGE, msg_box, get_uuid, get_md5, get_current_time, FACE_IMAGE
from util.dbutil import DBHelp


class Face_register_Window(QMainWindow, Ui_FaceregisterWindow):
    face_register_don_signal = pyqtSignal(str)  # 自定义信号
    def __init__(self, login):
        super(Face_register_Window, self).__init__()
        # UI界面

        self.setupUi(self)
        self.setWindowIcon(QIcon(APP_ICON))
        self.loginWindow = login
        self.cap = cv2.VideoCapture()
        self.background()
        self.pushButton.setProperty('class', 'Aqua')
        self.pushButton_2.setProperty('class', 'Aqua')
        self.pushButton_3.setProperty('class', 'Aqua')
        self.pushButton.setMinimumWidth(60)
        self.pushButton_2.setMinimumWidth(60)
        self.pushButton_3.setMinimumWidth(60)
        self.setStyleSheet(SYS_STYLE)
        self.setWindowFlags(Qt.WindowCloseButtonHint|Qt.WindowMinimizeButtonHint)
        self.color = (0, 0, 255)
        self.name = "Unknown"

        height, width = 256, 256
        channels = 3  # 例如,RGB图像

        # 创建一个全零的图像数组,数据类型为uint8
        self.userimg = np.zeros((height, width, channels), dtype=np.uint8)
        global save_img
        close_image = cv2.imread(CLOSE_IMAGE, cv2.IMREAD_COLOR)
        # 视频流的长和宽
        height, width = close_image.shape[:2]
        close_image = QImage(close_image, width, height, QImage.Format_RGB888)
        close_image = QPixmap.fromImage(close_image)
        # 视频流置于label中间部分播放
        self.label.setAlignment(Qt.AlignCenter)
        self.label.setPixmap(close_image)
        # 加载奥巴马的样例图片并学习如何识别它
        # 设置包含人脸图片的文件夹路径
        folder_path = FACE_IMAGE

        # 初始化已知人脸编码的数组和对应的姓名列表
        self.known_face_encodings = []
        self.known_face_names = []

        # 遍历文件夹中的所有文件
        for filename in os.listdir(folder_path):
            # 检查文件扩展名是否为.jpg或.jpeg(或其他你想要识别的图像格式)
            if filename.lower().endswith(('.jpg', '.jpeg', '.png', '.bmp')):
                # 构建完整的文件路径
                file_path = os.path.join(folder_path, filename)

                # 加载图像并提取人脸编码
                image = face_recognition.load_image_file(file_path)
                self.face_encodings = face_recognition.face_encodings(image)

                if self.face_encodings:  # 确保图像中有可识别的人脸
                    face_encoding = self.face_encodings[0]  # 假设每个图像只有一个主要人脸

                    # 添加人脸编码和对应的姓名到列表
                    self.known_face_encodings.append(face_encoding)
                    self.known_face_names.append(os.path.splitext(filename)[0])  # 使用文件名(不含扩展名)作为姓名

        # 现在known_face_encodings和known_face_names包含了所有已知的人脸编码和对应的姓名
        # 初始化一些变量
        self.face_locations = []
        self.face_encodings = []
        self.face_names = []
        self.process_this_frame = True  # 用于控制处理频率的变量


        # 在label中播放视频
        self.init_timer()

    def open_camera(self):
        # 检测该设备是否能打开
        flag = self.cap.open(0)
        print(flag)
        if flag is False:
            QMessageBox.information(self, "警告", "该设备未正常连接", QMessageBox.Ok)
        else:
            # 幕布可以播放
            self.label.setEnabled(True)
            # 打开摄像头按钮不能点击
            self.pushButton.setEnabled(False)
            # 关闭摄像头按钮可以点击
            self.pushButton_2.setEnabled(True)
            self.pushButton_3.setEnabled(True)
            self.timer.start()
            print("beginning!")

    # 关闭相机
    def close_camera(self):
        self.cap.release()
        self.pushButton.setEnabled(True)
        self.pushButton_2.setEnabled(False)
        self.pushButton_3.setEnabled(False)

        close_image = cv2.imread(CLOSE_IMAGE, cv2.IMREAD_COLOR)
        # 视频流的长和宽
        height, width = close_image.shape[:2]
        close_image = QImage(close_image, width, height, QImage.Format_RGB888)
        close_image = QPixmap.fromImage(close_image)
        # 视频流置于label中间部分播放
        self.label.setAlignment(Qt.AlignCenter)
        self.label.setPixmap(close_image)

        self.timer.stop()
        msg_box(self, "提示", "相机已关闭")

    # 播放视频画面
    def init_timer(self):
        self.timer = QTimer(self)
        self.timer.timeout.connect(self.show_pic)

    # 显示视频图像
    def show_pic(self):
        global save_img
        ret, img = self.cap.read()
        # cv2.imwrite("7772.jpg", img)
        save_img = img
        self.userimg = save_img
        if ret:
            # 从视频流中捕获一帧
            frame = img
            save_img = img
            # 将视频帧大小调整为原来的1/4,以加快人脸识别处理速度
            small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25)

            # cv2.imwrite("")
            # 将图像从BGR颜色(OpenCV使用)转换为RGB颜色(face_recognition使用)
            rgb_small_frame = np.ascontiguousarray(small_frame[:, :, ::-1])

            # 仅处理每隔一帧的视频,以节省时间
            if self.process_this_frame:
                # 在当前视频帧中找到所有的人脸及其编码
                self.face_locations = face_recognition.face_locations(rgb_small_frame)
                self.face_encodings = face_recognition.face_encodings(rgb_small_frame, self.face_locations)
                self.face_names = []
                for face_encoding in self.face_encodings:
                    # 检查人脸是否与已知人脸匹配
                    matches = face_recognition.compare_faces(self.known_face_encodings, face_encoding)


                    # 如果在known_face_encodings中找到匹配,只使用第一个匹配项
                    if True in matches:

                        first_match_index = matches.index(True)
                        self.name = self.known_face_names[first_match_index]
                    else:
                        self.name = "Unknown"

                    self.face_names.append(self.name)
            self.process_this_frame = not self.process_this_frame  # 切换处理帧的变量

            # 显示结果
            for (top, right, bottom, left), self.name in zip(self.face_locations, self.face_names):
                # 因为我们检测的是缩放后的帧,所以需要将人脸位置坐标放回到原始大小
                top *= 4
                right *= 4
                bottom *= 4
                left *= 4

                # 在人脸周围画一个矩形框
                cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)

                # 在人脸下方绘制一个标签显示姓名
                cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED)
                font = cv2.FONT_HERSHEY_DUPLEX
                cv2.putText(frame, self.name, (left + 6, bottom - 6), font, 1.0, (255, 255, 255), 1)
            # print(f"{name}")
            # 视频流的长和宽
            frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            height, width = frame.shape[:2]
            pixmap = QImage(frame, width, height, QImage.Format_RGB888)
            pixmap = QPixmap.fromImage(pixmap)
            # 获取是视频流和label窗口的长宽比值的最大值,适应label窗口播放,不然显示不全
            ratio = max(width / self.label.width(), height / self.label.height())
            pixmap.setDevicePixelRatio(ratio)
            # 视频流置于label中间部分播放
            self.label.setAlignment(Qt.AlignCenter)
            self.label.setPixmap(pixmap)

    def face_registern(self):
        self.name = self.username.text()
        password = self.password.text()
        file_name = f"{self.name}.jpg" # 这是保存的文件名
        save_path = "C:\\Users\\wangshichang\\Desktop\\Book\\face_image\\" + file_name  # 这是保存的路径,替换为实际的目录
        self.name = self.username.text()
        ret, img = self.cap.read()
        cv2.imwrite(save_path, img)
        self.close_camera()
        if '' in [self.name, password]:
            msg_box(self, '提示', '关键信息不能为空!')
            return
        db = DBHelp()
        count, res = db.query_super(table_name='user', column_name='username', condition=self.name)
        if count != 0:
            msg_box(self, '提示', '用户名已存在!')
            return
        user_info = [get_uuid(), self.name, get_md5(password), 1, get_current_time(), 0, get_current_time()]
        db.add_user(user_info)
        db.db_commit()
        db.instance = None
        del db
        msg_box(self, '提示', '注册成功!')

        self.loginWindow.show()
        self.close()


    def background(self):
        # 文件选择按钮
        self.pushButton.clicked.connect(self.open_camera)
        self.pushButton_2.clicked.connect(self.close_camera)
        self.pushButton_3.clicked.connect(self.face_registern)
        self.pushButton.setEnabled(True)
        # 初始状态不能关闭摄像头
        self.pushButton_2.setEnabled(False)
        self.pushButton_3.setEnabled(False)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = Face_register_Window()
    main.show()
    sys.exit(app.exec_())

        人脸登录

        实现效果,点击开始人脸识别打开电脑摄像机开始识别,识别到人脸后点击登录以此用户名登录,无需密码,关闭指关闭摄像头。

        face_window.py代码,检测face_image文件夹内的所有图片,并将除去后缀的文件名作为用户名,进行登录。

'''
文件名:face_window.py
概述:人脸识别窗口
'''

import os
import sys
import cv2
import face_recognition
import numpy as np
from PyQt5.QtCore import pyqtSignal, Qt, QTimer
from PyQt5.QtGui import QIcon, QImage, QPixmap
from PyQt5.QtWidgets import QMainWindow, QMessageBox, QApplication
from ui.face_window import Ui_faceWindow
from util.common_util import APP_ICON, SYS_STYLE, CLOSE_IMAGE, msg_box, FACE_IMAGE


class FaceWindow(QMainWindow, Ui_faceWindow):
    face_don_signal = pyqtSignal(str)  # 自定义信号
    def __init__(self, parent=None):
        super(FaceWindow, self).__init__()
        # UI界面

        self.setupUi(self)
        self.setWindowIcon(QIcon(APP_ICON))

        self.cap = cv2.VideoCapture()
        self.background()
        self.pushButton.setProperty('class', 'Aqua')
        self.pushButton_2.setProperty('class', 'Aqua')
        self.pushButton_3.setProperty('class', 'Aqua')
        self.pushButton.setMinimumWidth(60)
        self.pushButton_2.setMinimumWidth(60)
        self.pushButton_3.setMinimumWidth(60)
        self.setStyleSheet(SYS_STYLE)
        self.setWindowFlags(Qt.WindowCloseButtonHint|Qt.WindowMinimizeButtonHint)
        self.color = (0, 0, 255)
        self.name = "Unknown"
        close_image = cv2.imread(CLOSE_IMAGE, cv2.IMREAD_COLOR)
        # 视频流的长和宽
        height, width = close_image.shape[:2]
        close_image = QImage(close_image, width, height, QImage.Format_RGB888)
        close_image = QPixmap.fromImage(close_image)
        # 视频流置于label中间部分播放
        self.label.setAlignment(Qt.AlignCenter)
        self.label.setPixmap(close_image)
        # 设置包含人脸图片的文件夹路径
        folder_path = FACE_IMAGE
        # 初始化已知人脸编码的数组和对应的姓名列表
        self.known_face_encodings = []
        self.known_face_names = []

        # 遍历文件夹中的所有文件
        for filename in os.listdir(folder_path):
            # 检查文件扩展名是否为.jpg或.jpeg(或其他你想要识别的图像格式)
            if filename.lower().endswith(('.jpg', '.jpeg', '.png', '.bmp')):
                # 构建完整的文件路径
                file_path = os.path.join(folder_path, filename)
                # 加载图像并提取人脸编码
                image = face_recognition.load_image_file(file_path)
                self.face_encodings = face_recognition.face_encodings(image)
                if self.face_encodings:  # 确保图像中有可识别的人脸
                    face_encoding = self.face_encodings[0]  # 假设每个图像只有一个主要人脸
                    # 添加人脸编码和对应的姓名到列表
                    self.known_face_encodings.append(face_encoding)
                    self.known_face_names.append(os.path.splitext(filename)[0])  # 使用文件名(不含扩展名)作为姓名
        # known_face_encodings和known_face_names包含了所有已知的人脸编码和对应的姓名
        # 初始化一些变量
        self.face_locations = []
        self.face_encodings = []
        self.face_names = []
        self.process_this_frame = True  # 用于控制处理频率的变量

        # 在label中播放视频
        self.init_timer()

    def open_camera(self):
        # 检测该设备是否能打开
        flag = self.cap.open(0)
        print(flag)
        if flag is False:
            QMessageBox.information(self, "警告", "该设备未正常连接", QMessageBox.Ok)
        else:
            # 幕布可以播放
            self.label.setEnabled(True)
            # 打开摄像头按钮不能点击
            self.pushButton.setEnabled(False)
            # 关闭摄像头按钮可以点击
            self.pushButton_2.setEnabled(True)
            self.timer.start()
            print("beginning!")

    # 关闭相机
    def close_camera(self):
        self.cap.release()
        self.pushButton.setEnabled(True)
        self.pushButton_2.setEnabled(False)
        self.pushButton_3.setEnabled(False)

        close_image = cv2.imread(CLOSE_IMAGE, cv2.IMREAD_COLOR)
        # 视频流的长和宽
        height, width = close_image.shape[:2]
        close_image = QImage(close_image, width, height, QImage.Format_RGB888)
        close_image = QPixmap.fromImage(close_image)
        # 视频流置于label中间部分播放
        self.label.setAlignment(Qt.AlignCenter)
        self.label.setPixmap(close_image)

        self.timer.stop()
        msg_box(self, "提示", "相机已关闭")

    # 播放视频画面
    def init_timer(self):
        self.timer = QTimer(self)
        self.timer.timeout.connect(self.show_pic)

    # 显示视频图像
    def show_pic(self):
        ret, img = self.cap.read()
        if ret:
            # 从视频流中捕获一帧
            frame = img
            # 将视频帧大小调整为原来的1/4,以加快人脸识别处理速度
            small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25)

            # 将图像从BGR颜色(OpenCV使用)转换为RGB颜色(face_recognition使用)
            rgb_small_frame = np.ascontiguousarray(small_frame[:, :, ::-1])

            # 仅处理每隔一帧的视频,以节省时间
            if self.process_this_frame:
                # 在当前视频帧中找到所有的人脸及其编码
                self.face_locations = face_recognition.face_locations(rgb_small_frame)
                self.face_encodings = face_recognition.face_encodings(rgb_small_frame, self.face_locations)
                self.face_names = []
                for face_encoding in self.face_encodings:
                    # 检查人脸是否与已知人脸匹配
                    matches = face_recognition.compare_faces(self.known_face_encodings, face_encoding)


                    # 如果在known_face_encodings中找到匹配,只使用第一个匹配项
                    if True in matches:
                        self.pushButton_3.setEnabled(True)
                        first_match_index = matches.index(True)
                        self.name = self.known_face_names[first_match_index]
                    else:
                        self.name = "Unknown"

                    self.face_names.append(self.name)
            self.process_this_frame = not self.process_this_frame  # 切换处理帧的变量

            # 显示结果
            for (top, right, bottom, left), self.name in zip(self.face_locations, self.face_names):
                # 因为我们检测的是缩放后的帧,所以需要将人脸位置坐标放回到原始大小
                top *= 4
                right *= 4
                bottom *= 4
                left *= 4

                # 在人脸周围画一个矩形框
                cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)

                # 在人脸下方绘制一个标签显示姓名
                cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED)
                font = cv2.FONT_HERSHEY_DUPLEX
                cv2.putText(frame, self.name, (left + 6, bottom - 6), font, 1.0, (255, 255, 255), 1)
            # print(f"{name}")
            # 视频流的长和宽
            frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            height, width = frame.shape[:2]
            pixmap = QImage(frame, width, height, QImage.Format_RGB888)
            pixmap = QPixmap.fromImage(pixmap)
            # 获取是视频流和label窗口的长宽比值的最大值,适应label窗口播放,不然显示不全
            ratio = max(width / self.label.width(), height / self.label.height())
            pixmap.setDevicePixelRatio(ratio)
            # 视频流置于label中间部分播放
            self.label.setAlignment(Qt.AlignCenter)
            self.label.setPixmap(pixmap)

    def face_login(self):
        self.close_camera()
        self.face_don_signal.emit(self.name)
        self.close()


    def background(self):
        # 文件选择按钮
        self.pushButton.clicked.connect(self.open_camera)
        self.pushButton_2.clicked.connect(self.close_camera)
        self.pushButton_3.clicked.connect(self.face_login)
        self.pushButton.setEnabled(True)
        # 初始状态不能关闭摄像头
        self.pushButton_2.setEnabled(False)
        self.pushButton_3.setEnabled(False)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = FaceWindow()
    main.show()
    sys.exit(app.exec_())

        二维码扫描

(功能接口按钮位置)

         识别界面基本一摸一样就不放图了(同样的代码改来改去),主要用到的是pyzbar库中的decode方法,注意二维码所含的数据格式为“书名,作者,出版社,年-月-日,库存数量”(不带引号,以逗号分隔,库存数量为整数)。

        QRcode_window.py代码如下

'''
文件名:QRcode_window.py
概述:二维码扫描窗口
'''

import sys
from PyQt5.QtWidgets import QMessageBox, QFileDialog, QLineEdit
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from ui.Camera_window import Ui_xiangji
import cv2

from util.common_util import CLOSE_IMAGE, APP_ICON, SYS_STYLE, msg_box, get_uuid, get_current_time
from pyzbar.pyzbar import decode
import numpy as np

import sys

from util.dbutil import DBHelp

class CameraWindow(QMainWindow, Ui_xiangji):
    camera_don_signal = pyqtSignal()  # 自定义信号
    def __init__(self, parent=None):
        super(CameraWindow, self).__init__(parent)
        # UI界面

        self.setupUi(self)
        self.setWindowIcon(QIcon(APP_ICON))
        self.CAM_NUM = 0

        self.cap = cv2.VideoCapture()
        self.background()
        self.pushButton.setProperty('class', 'Aqua')
        self.pushButton_2.setProperty('class', 'Aqua')
        self.comboBox.setProperty('class', 'Aqua')
        self.pushButton.setMinimumWidth(60)
        self.pushButton_2.setMinimumWidth(60)
        self.comboBox.setMinimumWidth(60)
        self.setStyleSheet(SYS_STYLE)
        self.setWindowFlags(Qt.WindowCloseButtonHint|Qt.WindowMinimizeButtonHint)
        self.color = (0, 0, 255)

        close_image = cv2.imread(CLOSE_IMAGE, cv2.IMREAD_COLOR)
        # 视频流的长和宽
        height, width = close_image.shape[:2]
        close_image = QImage(close_image, width, height, QImage.Format_RGB888)
        close_image = QPixmap.fromImage(close_image)
        # 视频流置于label中间部分播放
        self.label.setAlignment(Qt.AlignCenter)
        self.label.setPixmap(close_image)


        # 在label中播放视频
        self.init_timer()

    def background(self):
        # 文件选择按钮
        self.pushButton.clicked.connect(self.open_camera)
        self.pushButton_2.clicked.connect(self.close_camera)

        self.pushButton.setEnabled(True)
        # 初始状态不能关闭摄像头
        self.pushButton_2.setEnabled(False)

    # 打开相机采集视频
    def open_camera(self):
        # 获取选择的设备名称
        index = self.comboBox.currentIndex()
        print(f"摄像头设备号为{index}")
        self.CAM_NUM = index
        # 检测该设备是否能打开
        flag = self.cap.open(self.CAM_NUM)
        # if flag:
        #     msg_box(self,"提示","相机正常工作")
        #     print(f"相机正常工作")
        if flag is False:
            QMessageBox.information(self, "警告", "该设备未正常连接", QMessageBox.Ok)
        else:
            # 幕布可以播放
            self.label.setEnabled(True)
            # 打开摄像头按钮不能点击
            self.pushButton.setEnabled(False)
            # 关闭摄像头按钮可以点击
            self.pushButton_2.setEnabled(True)
            self.timer.start()
            print("开始二维码检测!")
            self.show_pic()

    # 关闭相机
    def close_camera(self):
        self.cap.release()
        self.pushButton.setEnabled(True)
        self.pushButton_2.setEnabled(False)

        close_image = cv2.imread(CLOSE_IMAGE, cv2.IMREAD_COLOR)
        # 视频流的长和宽
        height, width = close_image.shape[:2]
        close_image = QImage(close_image, width, height, QImage.Format_RGB888)
        close_image = QPixmap.fromImage(close_image)
        # 视频流置于label中间部分播放
        self.label.setAlignment(Qt.AlignCenter)
        self.label.setPixmap(close_image)

        self.timer.stop()
        msg_box(self, "提示", "相机已关闭")

    # 播放视频画面
    def init_timer(self):
        self.timer = QTimer(self)
        self.timer.timeout.connect(self.show_pic)

    # 显示视频图像
    def show_pic(self):
        success,image = self.cap.read()
        if success:
            for code in decode(image):
                data = code.data.decode('utf-8')
                print("条形码/二维码数据:", data)  # 解码数据
                # 多边形获取(矩形的框)
                pts_poly = np.array(code.polygon, np.int32)  # 获取多边形坐标
                cv2.polylines(image, [pts_poly], True, self.color, 5)  # 画多边形框
                self.data = data.split(",")
                if len(self.data) >= 5:
                    book_name = self.data[0]
                    author = self.data[1]
                    publish_company = self.data[2]
                    publish_date = self.data[3]
                    # store_num = self.store_num_lineEdit.text()
                    store_num = int(self.data[4])
                    if '' in [book_name, author, publish_company, publish_date, store_num]:
                        msg_box(self, '错误', '请输入图书的关键信息!')
                        return
                    db = DBHelp()
                    # 看是否已经有添加过同名的书籍
                    count, res = db.query_super(table_name='book', column_name='book_name', condition=book_name)
                    if count:
                        msg_box(self, '错误', '已存在同名书籍!')
                        return
                    book_info = [get_uuid(), book_name, author, publish_company, store_num, 0, get_current_time(),
                                 publish_date]
                    db.add_book(data=book_info)
                    db.db_commit()
                    db.instance = None
                    del db
                    self.camera_don_signal.emit()  # 条件满足时发出添加图书的信号
                    # self.close()
                    msg_box(self, '提示', '添加新图书成功!')
                else:
                    msg_box(self, '错误', '二维码数据错误')
            cur_frame = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
            # 视频流的长和宽
            height, width = cur_frame.shape[:2]
            pixmap = QImage(cur_frame, width, height, QImage.Format_RGB888)
            pixmap = QPixmap.fromImage(pixmap)
            # 获取是视频流和label窗口的长宽比值的最大值,适应label窗口播放,不然显示不全
            ratio = max(width / self.label.width(), height / self.label.height())
            pixmap.setDevicePixelRatio(ratio)
            # 视频流置于label中间部分播放
            self.label.setAlignment(Qt.AlignCenter)
            self.label.setPixmap(pixmap)



if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = CameraWindow()
    main.show()
    sys.exit(app.exec_())

        YOLOv10检测

         这部分仅仅是因为笔者对yolo接触较多,一时兴起(为了高分)加上的,并无实际作用。

        代码部分较为简单,仅仅是在之前的基础上将YOLO的推理代码与qt界面结合在了一起,YOLO算法经过多次迭代,运用起来已经非常简洁方便,越来越偏向傻瓜式操作,这里仅给出最简单常用的代码。

from ultralytics import YOLO

model = YOLO("yolov10n.pt")#加载模型

results = model("0",show = True,device = 'cpu',show_labels = True)#使用摄像头推理,展示推理结果,使用cpu推理,展示标签
#这里仅仅使用cpu进行推理,一方面是应为pytorch环境比较难配,另一方面是在图书管理系统中使用gpu推理的时候与人脸识别产生了某种冲突,导致人脸识别帧率很低。

        这里仅仅使用cpu进行推理,一方面是应为pytorch环境比较难配,另一方面是在图书管理系统中使用gpu推理的时候与人脸识别产生了某种冲突,导致人脸识别帧率很低,权衡之后使用cpu,imsize=320,vid_stride=3,达到了不错的帧率识别效果,一秒20帧左右。

        总结

        在这次实验中还是学到了挺多的,短时间内熟悉了pyqt5,以及人脸识别与二维码扫描功能的实现,尝鲜体验了YOLOv10,因为代码并不是完全自己创作,所以完整代码暂时不发出来,如有需要在评论区留下邮箱,遇到问题欢迎评论区讨论交流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值