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


前言

  本文将介绍如何使用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()

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小张Tt

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值