首页 > 其他分享 >视觉捕捉 New

视觉捕捉 New

时间:2024-11-06 21:15:18浏览次数:3  
标签:self cv2 results event 捕捉 tk 视觉 New frame

import cv2
import tkinter as tk
from tkinter import ttk
from PIL import Image, ImageTk
import numpy as np

class Application(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("MatchesV2")
        self.geometry("800x600")

        # 初始化全局变量
        self.ix, self.iy = -1, -1
        self.roi_set = False
        self.roi = None
        self.drawing = False
        self.template_loaded = False
        self.match_done = False
        self.template = None
        self.match_status = tk.StringVar(value="等待开始")
        self.results_text = ""

        # 打开摄像头
        self.cap = cv2.VideoCapture(0)

        # 创建主画布
        self.canvas = tk.Canvas(self, width=640, height=480)
        self.canvas.pack(side=tk.TOP, padx=10, pady=10)

        # 创建状态标签
        self.status_label = tk.Label(self, textvariable=self.match_status, font=("Arial", 16), fg="red")
        self.status_label.pack(side=tk.TOP)

        # 创建退出按钮
        self.quit_button = tk.Button(self, text="退出", command=self.quit)
        self.quit_button.pack(side=tk.TOP, padx=10, pady=10)

        # 创建用于显示操作记录和匹配结果的区域
        self.results_frame = tk.Frame(self)
        self.results_frame.pack(side=tk.TOP, fill=tk.X, padx=10, pady=10)

        self.results_label = tk.Label(self.results_frame, text="操作记录与匹配结果:")
        self.results_label.pack(side=tk.TOP, padx=5, pady=5)

        self.results_textbox = tk.Text(self.results_frame, wrap='word', height=10, width=40)
        self.results_textbox.pack(side=tk.TOP, padx=5, pady=5)

        # 绑定鼠标事件
        self.canvas.bind("<ButtonPress-1>", self.on_button_press)
        self.canvas.bind("<B1-Motion>", self.on_mouse_motion)
        self.canvas.bind("<ButtonRelease-1>", self.on_button_release)

        # 启动摄像头读取和显示循环
        self.update_frame()

    def on_button_press(self, event):
        self.drawing = True
        self.ix, self.iy = event.x, event.y

    def on_mouse_motion(self, event):
        if self.drawing:
            self.canvas.delete("rect")
            self.canvas.create_rectangle(min(self.ix, event.x), min(self.iy, event.y),
                                         max(self.ix, event.x), max(self.iy, event.y),
                                         outline="green", tag="rect")

    def on_button_release(self, event):
        if self.drawing:
            self.drawing = False
            self.canvas.delete("rect")
            self.ix, self.iy = min(self.ix, event.x), min(self.iy, event.y)
            self.roi = self.frame[min(self.iy, event.y):max(self.iy, event.y),
                                  min(self.ix, event.x):max(self.ix, event.x)]
            self.roi_set = True
            self.template = self.roi
            self.results_text += f"选择了区域:({min(self.ix, event.x)}, {min(self.iy, event.y)}) -> ({max(self.ix, event.x)}, {max(self.iy, event.y)})\n"
            self.update_results_text()
            self.match_status.set("检测中")

    def update_results_text(self):
        self.results_textbox.delete(1.0, tk.END)
        self.results_textbox.insert(tk.END, self.results_text)

    def update_frame(self):
        ret, frame = self.cap.read()
        if ret:
            frame = cv2.flip(frame, 1)  # 镜像翻转图像

            # 确保 frame 是一个有效的 numpy 数组
            self.frame = frame.copy()  # 使用 .copy() 来避免引用问题

            # 如果已经设置了 ROI,则进行模板匹配
            if self.roi_set and self.template is not None and self.template.size > 0:
                res = cv2.matchTemplate(self.frame, self.template, cv2.TM_CCOEFF_NORMED)
                min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
                top_left = max_loc
                bottom_right = (top_left[0] + self.template.shape[1], top_left[1] + self.template.shape[0])

                # 计算旋转角度
                angle = self.calculate_rotation_angle(self.template, self.frame[top_left[1]:bottom_right[1], top_left[0]:bottom_right[0]])

                # 在匹配框周围绘制矩形和文本
                cv2.rectangle(self.frame, top_left, bottom_right, 255, 2)
                text = f"X: {top_left[0]}, Y: {top_left[1]}, Angle: {angle:.2f}°"
                cv2.putText(self.frame, text, (top_left[0], top_left[1] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 0), 2)

            # 将OpenCV BGR格式转换为Tkinter PhotoImage格式
            frame_tk = self.cv_to_tk(self.frame)
            self.canvas.create_image(0, 0, anchor=tk.NW, image=frame_tk)
            self.canvas.image = frame_tk

        # 更新并重复调用
        self.after(30, self.update_frame)

    @staticmethod
    def cv_to_tk(image_cv):
        image_cv_rgb = cv2.cvtColor(image_cv, cv2.COLOR_BGR2RGB)
        image_pil = Image.fromarray(image_cv_rgb)
        return ImageTk.PhotoImage(image_pil)

    @staticmethod
    def calculate_rotation_angle(template, matched_region):
        # 使用特征点匹配来计算旋转角度
        orb = cv2.ORB_create()
        kp1, des1 = orb.detectAndCompute(template, None)
        kp2, des2 = orb.detectAndCompute(matched_region, None)

        if des1 is None or des2 is None or len(des1) == 0 or len(des2) == 0:
            return 0.0

        bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
        matches = bf.match(des1, des2)
        matches = sorted(matches, key=lambda x: x.distance)

        if len(matches) < 2:
            return 0.0

        src_pts = np.float32([kp1[m.queryIdx].pt for m in matches[:2]])
        dst_pts = np.float32([kp2[m.trainIdx].pt for m in matches[:2]])

        M, _ = cv2.estimateAffinePartial2D(src_pts, dst_pts)
        if M is None or M.shape != (2, 3):
            return 0.0

        angle = np.arctan2(M[1, 0], M[0, 0]) * 180 / np.pi
        return angle

if __name__ == "__main__":
    app = Application()
    app.mainloop()

    # 释放资源
    app.cap.release()

标签:self,cv2,results,event,捕捉,tk,视觉,New,frame
From: https://blog.csdn.net/weixin_68067302/article/details/143494277

相关文章

  • new和malloc的区别,分别解释它们的用法
    new new是 C++的一个运算符,用于动态分配对象在堆内存中的空间。它不仅负责内存分配,还会调用对象的构造函数。分配基本的数据类型int*pInt=newint;//分配一个int类型的内存*pInt=10;//使用分配的内存分配数组int*pArray=newint[5];//......
  • new与malloc
    一、newnew是操作符,利用new在堆区开辟数据,开辟的数据需要手动开辟,在使用结束后用delete手动释放,利用new创建的数据,会返回该数据对应的类型指针用法1:在堆区申请一块空间存放一个数#include<iostream>usingnamespacestd;int*fun(){//new在堆区申请内存,返回的是申请......
  • 【毕业设计】基于机器视觉的学生课堂行为检测 目标检测 深度学习 计算机视觉 yolo
    一、背景意义    随着教育技术的不断进步,课堂管理和学生行为分析逐渐成为教育研究的重要课题。传统的课堂观察方法往往依赖于教师的主观判断,不仅效率低下,而且容易受到观察者偏差的影响。基于机器视觉的学生课堂行为检测系统,利用深度学习和计算机视觉技术,能够实现对学生......
  • 2024newstarweb题解
    w1headach3会赢吗源码flag碎片X1:ZmxhZ3tXQTB3再次查看源码flag碎片X2:IV95NF9yM2Fs第三个页面也是直接查看源码直接改源码flag碎片X3:MXlfR3I0c1B下一个页面直接禁用jsflag碎片X4:fSkpKcyF9ZmxhZ3tXQTB3IV95NF9yM2FsMXlfR3I0c1BfSkpKcyF9base64解码即......
  • Rockchip SoC 赋能 AI 与视觉创新:推动智能设备的未来发展
    随着人工智能(AI)和计算机视觉技术不断推动各行各业的创新,Rockchip已成为提供强大系统级芯片(SoC)解决方案的领先厂商。该公司已开发出多款集成AI功能并支持先进多媒体与视觉技术的SoC,非常适合用于AI驱动的边缘计算、安全监控、机器人技术等应用领域。armsomboard本文将探讨......
  • 智能 AI 视觉识别系统打造高效流量统计方案
    智能AI视觉算法解决方案,涵盖客流人数统计、车流量统计、牲畜养殖场计数、物品点包计数、超员报警、火焰识别报警及驾驶行为报警等功能。可精准统计商场、车站等地客流,区分车型统计车流量并预警拥堵,准确计数牲畜及物品,检测工厂超员并辅助管理,快速响应火焰降低损失,判断行为规范保......
  • NewStar CTF 2024 misc WP
    decompress压缩包套娃,一直解到最后一层,将文件提取出来提示给出了一个正则,按照正则爆破密码,一共五位,第四位是数字 ^([a-z]){3}\d[a-z]$一共就五位数,直接ARCHPR爆破,得到密码xtr4m,解压得到flagpleasingMusic题目描述中提到:一首歌可以好听到正反都好听根据提示(其实也能听出来后半段......
  • Golang new() make var []int 使用的具体区别
    一、数组和切片的初始化1var []int 格式funcmain(){ vart1[]int t1=append(t1,1) fmt.Println(t1)//正常输出1 vart11[]int t11[0]=11//panic:runtimeerror:indexoutofrange[0]withlength0 fmt.Println(t11) vart12[1]int t12[0]=......
  • 帝国CMS根据新闻正文字段[newstext]批量重新生成简介字段[smalltext]
    步骤:设置自动生成简介的字数:进入帝国CMS后台,设置自动获取简介的字数(默认160,可以改为320)。编写处理PHP脚本:创建 auto_smalltext.php 文件,内容如下:<?phpdefine('EmpireCMSAdmin','1');require("../class/connect.php");require("../class/db_sql.php");req......
  • 计算机视觉的研究方向和相应算法
    计算机视觉是一个广泛的领域,涵盖了多种研究方向和算法。以下是对计算机视觉研究方向及其相关算法的详细介绍:研究方向图像识别与分类:研究如何让计算机识别并分类图像中的对象,如车辆、人脸、动物等。目标检测与跟踪:研究如何让计算机在图像或视频中检测并跟踪特定的目标对象......