基于Python和Tkinter的双目相机驱动界面

news2024/10/2 14:32:33

文章目录

    • 前言
    • 准备工作
    • 代码分析
      • 初始化
      • 创建按钮
      • 创建图像显示区域
      • 创建信息标签
      • 启动摄像头捕捉
      • 主函数
      • 结论
      • 效果展示


前言

  本文将介绍如何使用Python和Tkinter库来创建一个简单的摄像头应用程序。这个应用程序可以打开摄像头,显示摄像头捕捉的图像,并允许用户拍摄快照。

准备工作

需要安装以下Python库:
tkinter:用于创建GUI界面。
cv2:OpenCV库,用于处理图像和捕捉摄像头帧。
PIL:Python Imaging Library,用于图像处理。
numpy:用于数值计算。

代码分析

  程序由一个MyWindow类组成,该类包含了应用程序的主要逻辑和GUI元素。

初始化

class MyWindow:
    def __init__(self, root):
        self.root = root
        root.title("Camera")
        root.geometry("960x640")
        # ...

  创建了一个MyWindow类,该类在初始化时创建一个Tkinter窗口,设置窗口标题和大小。

创建按钮

 def create_buttons(self):
        # ...

  创建了两个按钮,一个用于启动摄像头捕捉,另一个用于拍摄快照。

创建图像显示区域

def create_image_displays(self):
        # ...

  创建了两个Canvas,用于显示摄像头捕捉到的左半边和右半边的图像。

创建信息标签

def create_info_label(self):
    # ...

  创建了一个Label,用于显示交互信息,例如拍摄的快照文件名。

启动摄像头捕捉

def start_capture(self):
    while True:
        ret, frame = self.camera.read()
        # ...

  这个方法启动了摄像头捕捉循环,不断捕捉摄像头帧并在左侧和右侧Canvas上显示它们。
拍摄快照

def take_snapshot(self):
      # ...

  这个方法允许用户拍摄快照,将左半边和右半边的图像保存为PNG文件,并在信息标签上显示已保存的文件名。

主函数

def main():
    root = tk.Tk()
    my_window = MyWindow(root)
    root.mainloop()

if __name__ == "__main__":
    main()

在主函数中,创建了Tkinter窗口并实例化MyWindow类,然后启动了Tkinter的主循环。

结论

通过上述代码和解释,可以创建一个简单的摄像头应用程序,用于捕捉图像并保存快照。你可以根据需要对应用程序进行扩展,添加更多功能,如图像处理等。

效果展示

运行
在这里插入图片描述
启动
在这里插入图片描述
拍摄
在这里插入图片描述
在这里插入图片描述

完整的程序代码如下:

import tkinter as tk
from tkinter import Canvas, Label, Button
import cv2
import numpy as np
from PIL import Image, ImageTk
import os
from PIL import Image

class MyWindow:
    def __init__(self, root):
        self.root = root
        root.title("Camera")
        root.geometry("960x640")

        self.create_buttons()
        self.create_image_displays()
        self.create_info_label()
        self.camera = cv2.VideoCapture(0)  # 打开相机
        self.left_photo = tk.PhotoImage()
        self.right_photo = tk.PhotoImage()
        self.snapshot_count = 0  # 用于递增文件名编号

    def create_buttons(self):
        # 创建一个框架,用于水平居中排列按钮
        button_frame = tk.Frame(self.root)
        button_frame.pack(side="top")

        # 创建拍摄按钮,绑定事件处理函数
        self.capture_button = tk.Button(button_frame, text="启动", width=10, height=2, command=self.start_capture)
        self.capture_button.pack(side="left", padx=10, pady=20)

        # 创建拍摄按钮
        self.start_button = tk.Button(button_frame, text="拍摄", width=10, height=2, command=self.take_snapshot)
        self.start_button.pack(side="left", padx=10)

    def create_image_displays(self):
        # 创建一个框架,用于容纳两个Canvas并在水平方向上居中排列
        image_frame = tk.Frame(self.root)
        image_frame.pack(side="top", pady=20)  # 添加垂直间距以使其垂直居中

        # 创建左侧Canvas并设置背景颜色为白色
        self.left_canvas = Canvas(image_frame, width=320, height=240, bg="white")
        self.left_canvas.pack(side="left", padx=20)

        # 创建右侧Canvas并设置背景颜色为白色
        self.right_canvas = Canvas(image_frame, width=320, height=240, bg="white")
        self.right_canvas.pack(side="left", padx=10)

    def create_info_label(self):
        # 创建一个Label用于显示交互信息,设置背景颜色为白色,放置在底部并铺满整个宽度
        self.info_label = Label(self.root, text="This is 信息", font=("Arial", 12), bg="white", height=10)
        self.info_label.pack(side="bottom", fill="x")

    def start_capture(self):
        while True:
            ret, frame = self.camera.read()

            if not ret:
                print("无法读取帧")
                break

            # 将画面分为左半边和右半边
            height, width, _ = frame.shape
            left_half = frame[:, :width // 2]
            right_half = frame[:, width // 2:]

            # 使用PIL库将图像数据从OpenCV格式转换为Tkinter PhotoImage格式
            left_image = Image.fromarray(cv2.cvtColor(left_half, cv2.COLOR_BGR2RGB))
            right_image = Image.fromarray(cv2.cvtColor(right_half, cv2.COLOR_BGR2RGB))
            self.left_photo = ImageTk.PhotoImage(image=left_image)
            self.right_photo = ImageTk.PhotoImage(image=right_image)

            # 调整左半边和右半边的图像大小为Canvas的大小(320x240)
            left_resized = left_image.resize((320, 240), Image.ANTIALIAS)
            right_resized = right_image.resize((320, 240), Image.ANTIALIAS)

            self.left_photo_resized = ImageTk.PhotoImage(image=left_resized)
            self.right_photo_resized = ImageTk.PhotoImage(image=right_resized)

            # 在Canvas上显示调整大小后的左半边和右半边图像
            self.left_canvas.create_image(0, 0, anchor="nw", image=self.left_photo_resized)
            self.right_canvas.create_image(0, 0, anchor="nw", image=self.right_photo_resized)

            self.root.update()  # 更新Tkinter窗口

    def take_snapshot(self):
        # 获取当前的左半边和右半边图像
        left_image = Image.fromarray(cv2.cvtColor(self.camera.read()[1], cv2.COLOR_BGR2RGB))
        right_image = Image.fromarray(cv2.cvtColor(self.camera.read()[1], cv2.COLOR_BGR2RGB))

        # 递增文件名编号
        self.snapshot_count += 1

        # 保存左半边和右半边图像为PNG文件
        left_filename = f"left{self.snapshot_count}.png"
        right_filename = f"right{self.snapshot_count}.png"

        left_image.save(left_filename, "png")
        right_image.save(right_filename, "png")

        # 更新信息标签
        self.info_label.config(text=f"Left: {left_filename}, Right: {right_filename}均已保存!!")

def main():
    root = tk.Tk()
    my_window = MyWindow(root)
    root.mainloop()

if __name__ == "__main__":
    main()

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

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

相关文章

Nosql redis高可用和持久化

Nosql redis高可用和持久化 1、redis高可用2、redis持久化2.1redis持久化2.2Redis 持久化方法2.3RDB 持久化2.3.1RDB持久化工作原理2.3.2触发条件2.3.3其他自动触发机制2.3.4执行流程2.3.5启动时加载 2.4AOF 持久化2.4.1AOF持久化原理2.4.2开启AOF2.4.3执行流程2.4.4文件重写的…

8+结合10种机器学习算法构建模型,可复现。

今天给同学们分享一篇机器学习的生信文章“Comprehensive machine-learning survival framework develops a consensus model in large-scale multicenter cohorts for pancreatic cancer”,这篇文章于2022年10月25日发表在eLife期刊上,影响因子为8.713。…

小游戏开发者应该如何入局赛道

一、微信小游戏赛道发展史 第一阶段:轻度试水期,2017~2019年 微信小游戏于2017年底上线,初期以轻度休闲为主,例如棋牌、合成消除以及益智相关游戏类型。一是开发门槛不高,产品可以快速上线; 二是大部分厂…

功率信号源在电子测试中的应用有哪些方面

功率信号源在电子测试中有着广泛的应用,可以提供稳定、可调的功率信号,用于各种测量和验证工作。下面西安安泰将介绍功率信号源在电子测试中的几个主要应用方面。 图:ATG-2000系列功率信号源 无线通信测试:功率信号源在无线通信测…

【three.js】结合vue进行开发第一个3d页面

一、创建vue项目 新建一个项目目录,在集成终端打开,输入 npm init vitelatest 回车后,依次输入项目名,选择vue和js开发 然后安装依赖并运行项目 二、安装three 接下来我们开始安装three npm install three 三、Three.js 的…

【Unity3D赛车游戏制作】开始场景搭建——UGUI复合控件Button

👨‍💻个人主页:元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏:Uni…

leetcode 每日一题复盘(10.9~10.15)

leetcode 101 对称二叉树 这道题一开始想是用层序遍历,看每一层是否都对称,遇到一个问题就是空指针(子树为空)无法记录下来,同时会导致操作空指针的问题,因此需要修改入队条件,并用一个标志去表示空指针 vector<int>numv;for(int i0;i<size;i){TreeNode*frontque.fro…

JavaScript ES5实现继承

一、对象和函数的原型 1.认识对象的原型 JavaScript当中每个对象都有一个特殊的内置属性 [[prototype]]&#xff0c;这个特殊的对象可以指向另外一个对象。 那么这个对象有什么用呢&#xff1f; 当我们通过引用对象的属性key来获取一个value时&#xff0c;它会触发 **[[Get…

uni-app:实现页面效果4(echarts数据可视化)

效果 代码 <template><view><view><view class"title">概况</view><view class"line_position"><view class"line1"><view class"item"><view class"one">今日销售…

公众号突破注册操作流程

一般可以注册多少个公众号&#xff1f;众所周知&#xff0c;在2013年前后&#xff0c;公众号申请是不限制数量的&#xff0c;后来企业开始限制申请50个&#xff0c;直到2018年的11月tx又发布&#xff0c;其中个人主体可申请公众号由2个调整为1个&#xff0c;企业主体由50个调整…

Java中树形菜单的实现方式(超全详解!)

前言 这篇文中&#xff0c;我一共会用两种方式来实现目录树的数据结构&#xff0c;两种写法逻辑是一样的&#xff0c;只是一种适合新手理解&#xff0c;一种看着简单明了但是对于小白不是很好理解。在这里我会很详细的讲解每一步代码&#xff0c;主要是方便新人看懂&#xff0…

北邮22级信通院数电:Verilog-FPGA(5)第四第五周实验 密码保险箱的设计

北邮22信通一枚~ 跟随课程进度更新北邮信通院数字系统设计的笔记、代码和文章 持续关注作者 迎接数电实验学习~ 获取更多文章&#xff0c;请访问专栏&#xff1a; 北邮22级信通院数电实验_青山如墨雨如画的博客-CSDN博客 目录 一.密码箱的功能和安全性 显示&#xff1a;…

Qt 对界面类重命名的步骤

有些时候因为一些原因&#xff0c;需要修改Qt中创建的界面类&#xff0c;修改的地方比较多&#xff0c;一定要留意有没有修改完全&#xff0c;否则会出现各种奇怪报错。 比如&#xff0c;将MainWindow界面类名修改为lb_logdisplay 修改步骤&#xff1a; 修改文件名&#xff1a;…

【Redis】字符串类型命令

目录 字符串类型命令SETGETMGETSETNXINCRINCRBYDECRDECYBYINCRBYFLOATAPPENDGETRANGESETRANGESTRLEN 字符串类型命令 SET 将string类型的value设置到key中。如果key之前存在&#xff0c;则覆盖&#xff0c;⽆论原来的数据类型是什么。之前关于此key的TTL也全部失效。 SET key…

一文拿捏线程池

1 谈谈你对线程池理解 1 概念 线程池是一种用于管理线程的机制&#xff0c;核心思想是资源复用&#xff0c;避免频繁地创建和销毁线程所带来的性 能开销。 2 原理 线程池的原理是预先创建一定数量的线程&#xff0c;并将它们放入一个线程池中。当有任务需要执行时&#xff0…

人工智能(AI)技术的实际应用

人工智能&#xff08;AI&#xff09;技术在各个领域都有广泛的实际应用。这些示例只是AI技术的一小部分应用&#xff0c;AI正在不断演化中。以下是一些常见的实际AI应用示例&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#…

动态内存管理之经典笔试题

目录 C/C程序的内存开辟 题目1 题目2 题目3 题目4 今天我们来接着讲几道经典的笔试题。首先来了解一下c\c程序的内存开辟&#xff0c;使我们做题的头脑更加清晰。 C/C程序的内存开辟 内核空间 是用户代码不能读写的栈区是用来开辟 局部变量 形式参数&#xff0c;函数栈…

0基础学python,给大家首推这些书!

对于0基础的人来说&#xff0c;学习Python首推的书就是这本 《Python 编程&#xff1a;从入门到实践》 。 这本书常居各网站编程图书销量榜第一名&#xff0c;目前在全球范围内被翻译成 12 国语言&#xff0c;仅在中国就帮助了超过 120 万对 Python 有需求的学习者入门&#x…

【华为OD机考B卷 | 100分】五子棋迷(JAVA题解——也许是全网最详)

前言 本人是算法小白&#xff0c;甚至也没有做过Leetcode。所以&#xff0c;我相信【同为菜鸡的我更能理解作为菜鸡的你们的痛点】。 题干 1. 题目描述 张兵和王武是五子棋迷&#xff0c;工作之余经常切磋棋艺。走了一会儿&#xff0c;轮到张兵了&#xff0c;他对着一条线思…

Vue CLI和Vite区别

1.Vue CLI脚手架 什么是Vue脚手架&#xff1f; 在真实开发中我们不可能每一个项目从头来完成所有的webpack配置&#xff0c;这样显示开发的效率会大大的降低&#xff1b;所以在真实开发中&#xff0c;我们通常会使用脚手架来创建一个项目&#xff0c;Vue的项目我们使用的就是…