猫狗识别(三)
三、摄像头识别
使用OpenCV和Tkinter构建的实时摄像头识别猫狗的应用程序。它允许用户通过摄像头实时查看视频,并使用Haar级联分类器检测视频中的猫和狗。
1.导入所需的库:
cv2用于视频捕获和图像处理,tkinter用于创建GUI,Image和ImageTk用于处理图像,threading用于创建新线程以更新视频帧。
import cv2
import tkinter as tk
from PIL import Image, ImageTk
import threading
2.创建Tkinter主窗口,设置窗口标题、宽度和高度。
# 创建窗口
root = tk.Tk()
root.title("摄像头识别猫狗") # 设置窗口标题
window_width, window_height = 800, 600
root.geometry(f'{window_width}x{window_height}')
3.创建一个Canvas,它将用于显示视频帧。
canvas = tk.Canvas(root, width=window_width, height=window_height)
canvas.pack()
4.打开默认的摄像头。
# 打开摄像头
cap = cv2.VideoCapture(0)
5.定义一个函数update_frame,用于更新Canvas上的视频帧。
# 更新摄像头帧
def update_frame():
while True:
ret, frame = cap.read()
if ret:
# 直接转换为RGB(取消BGR到RGBA的转换)
cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# 转换为PIL格式
pil_image = Image.fromarray(cv2image)
# 转换为PhotoImage格式
img = ImageTk.PhotoImage(image=pil_image)
# 更新图片
canvas.image = img # Keep a reference!
canvas.create_image(0, 0, anchor='nw', image=img)
root.update_idletasks()
else:
break
在一个无限循环中读取摄像头的帧,并将其显示在Canvas上。如果读取帧失败,循环将结束。
6.定义一个函数detect_cats_and_dogs,用于检测视频帧中的猫和狗。
# 检测猫和狗
def detect_cats_and_dogs():
while True:
ret, frame = cap.read()
if ret:
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cat_cascade = cv2.CascadeClassifier('haarcascade_frontalcatface.xml')
dog_cascade = cv2.CascadeClassifier('haarcascade_frontalface_alt.xml')
if cat_cascade.empty() or dog_cascade.empty():
print("Haar cascade文件加载失败")
break
cats = cat_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
dogs = dog_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
# 在Canvas上绘制绿框
detected_objects = list(cats) + list(dogs)
if len(detected_objects) > 0:
# 清除之前的矩形
canvas.delete('rectangles')
for (x, y, w, h) in detected_objects:
# 绘制新矩形,并添加tag以便于清除
canvas.create_rectangle(x, y, x+w, y+h, outline='green', width=3, tag='rectangles')
else:
print("未检测到猫或狗")
root.update_idletasks()
else:
break
7.定义一个函数exit_program,用于退出程序并释放摄像头资源。
# 退出程序
def exit_program():
cap.release() # 释放摄像头资源
root.quit() # 退出Tkinter事件循环
8.创建一个按钮,用于退出程序。
# 创建按钮
button2 = tk.Button(root, text="退出程序", command=exit_program, width=10, height=2)
button2.place(x=400, y=500, width=100, height=50)
9.启动两个线程,一个用于更新视频帧,另一个用于检测猫和狗。然后启动Tkinter的事件循环,这将显示窗口并开始处理用户事件。
# 启动线程
threading.Thread(target=update_frame).start()
threading.Thread(target=detect_cats_and_dogs).start()
root.mainloop()