猫狗识别—静态图像识别

猫狗识别---静态图像识别

1. 导入必要的库:

python 复制代码
import torch
import numpy as np
import torchvision
from os import path
from torchvision import datasets, models
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader
import torchvision.transforms as transforms
import os
import tkinter as tk
from PIL import Image, ImageTk
from tkinter import filedialog
import cv2
import subprocess
from tkinter import messagebox

2. 设置数据目录和模型路径:

  • data_dir变量设置了数据目录的路径,model_path变量设置了预训练模型的路径。
python 复制代码
#设置数据目录和模型路径
data_dir = r'data'
model_path = 'cat_dog_classifier.pth'

3. 定义图像转换

python 复制代码
data_transforms = {
    'test': transforms.Compose([
        transforms.Resize(size=224),
        transforms.CenterCrop(size=224),
        transforms.ToTensor(),
        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
    ]),
}

4. 使用GPU

python 复制代码
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

5. 加载没有预训练权重的ResNet模型

python 复制代码
model = models.resnet50(pretrained=False)  # 使用pretrained=False
num_ftrs = model.fc.in_features
model.fc = nn.Linear(num_ftrs, 2)
model.load_state_dict(torch.load(model_path))
model = model.to(device)
model.eval()

6. 创建Tkinter窗口:

python 复制代码
#创建Tkinter窗口
root = tk.Tk()
root.title('图像识别猫狗')
root.geometry('800x650')

image = Image.open("图像识别背景.gif")
image = image.resize((800, 650))  # 调整背景图片大小
photo1 = ImageTk.PhotoImage(image)
canvas = tk.Label(root, image=photo1)
canvas.pack()


#添加文本标签来显示识别结果
result_label = tk.Label(root, text="", font=('Helvetica', 18))
result_label.place(x=280, y=450)

#原始图像标签
image_label = tk.Label(root, text="", image="")
image_label.place(x=210, y=55)

#保存用户选择的图片路径
selected_image_path = None

#加载测试数据集
image_datasets = {x: datasets.ImageFolder(root=os.path.join(data_dir, x),
                                          transform=data_transforms[x])
                  for x in ['test']}
dataloaders = {x: DataLoader(image_datasets[x], batch_size=1, shuffle=False)
               for x in ['test']}
dataset_sizes = {x: len(image_datasets[x]) for x in ['test']}
class_names = image_datasets['test'].classes  # 定义class_names


#加载Haar特征级联分类器
cat_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalcatface.xml')
dog_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_alt2.xml')

7.定义选择图片的函数:

python 复制代码
#定义一个函数来打开文件选择对话框并显示图片
def choose_image():
    global selected_image_path
    file_path = filedialog.askopenfilename(initialdir=data_dir, title="选择图片",
                                           filetypes=(("图片文件", "*.png *.jpg *.jpeg *.gif *.bmp"), ("所有文件", "*.*")))
    if file_path:
        selected_image_path = file_path
        img = Image.open(file_path)
        img = img.resize((400, 350), Image.LANCZOS)
        imgTk = ImageTk.PhotoImage(img)
        image_label.config(image=imgTk)
        image_label.image = imgTk

8.定义预测图片的函数:

python 复制代码
#定义一个函数来使用模型进行预测
def predict_image():
    global selected_image_path
    if selected_image_path:
        img = Image.open(selected_image_path)
        transform = data_transforms['test']
        img_tensor = transform(img).unsqueeze(0).to(device)

        with torch.no_grad():
            outputs = model(img_tensor)
            _, preds = torch.max(outputs, 1)

        prediction = class_names[preds.item()]  # 使用str()来将整数转换为字符串
        result_label.config(text=f"检测到的结果为: {prediction}")

        # 使用OpenCV在原始图像上绘制矩形框
        img_cv2 = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)

        if prediction == 'cats':
            cats = cat_cascade.detectMultiScale(img_cv2, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
            for (x, y, w, h) in cats:
                cv2.rectangle(img_cv2, (x, y), (x + w, y + h), (0, 0, 255), 2)  # 红色矩形框
            if len(cats) > 0:
                cv2.imwrite("detected_cats_image.jpg", img_cv2)  # 保存带有猫矩形框的图像
                img_detected_cats = Image.open("detected_cats_image.jpg").resize((350, 300), Image.LANCZOS)
                imgTk_detected_cats = ImageTk.PhotoImage(img_detected_cats)
                image_label.config(image=imgTk_detected_cats)
                image_label.image = imgTk_detected_cats
        elif prediction == 'dogs':
            dogs = dog_cascade.detectMultiScale(img_cv2, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
            for (x, y, w, h) in dogs:
                cv2.rectangle(img_cv2, (x, y), (x + w, y + h), (0, 0, 255), 2)  # 红色矩形框
            if len(dogs) > 0:
                cv2.imwrite("detected_dogs_image.jpg", img_cv2)  # 保存带有狗矩形框的图像
                img_detected_dogs = Image.open("detected_dogs_image.jpg").resize((350, 300), Image.LANCZOS)
                imgTk_detected_dogs = ImageTk.PhotoImage(img_detected_dogs)
                image_label.config(image=imgTk_detected_dogs)
                image_label.image = imgTk_detected_dogs
        else:
            print("未检测到猫或狗。")
            # 显示修改后的图像
        img = cv2.cvtColor(img_cv2, cv2.COLOR_BGR2RGB)
        img = cv2.resize(img, (400, 350))
        imgTk = ImageTk.PhotoImage(image=Image.fromarray(img))
        image_label.config(image=imgTk)
        image_label.image = imgTk
    else:
        print("请先选择一张图片。")

9.退出程序的函数:

python 复制代码
#退出程序的函数
def close():
    subprocess.Popen(["python","主页面.py"])
    root.destroy()

10.创建按钮:

python 复制代码
#创建按钮
image = Image.open("选择图片.gif")  # 加载一张图片
photo2 = ImageTk.PhotoImage(image)
bt1 = tk.Button(root, image=photo2, width=200, height=32, command=choose_image)
bt1.place(x=60, y=530)

image = Image.open("开始识别.gif")  # 加载一张图片
photo3 = ImageTk.PhotoImage(image)
bt1 = tk.Button(root, image=photo3, width=200, height=32, command=predict_image)
bt1.place(x=300, y=530)

image = Image.open("退出程序.gif")  # 加载一张图片
photo4 = ImageTk.PhotoImage(image)
bt1 = tk.Button(root, image=photo4, width=200, height=32, command=close)
bt1.place(x=535, y=530)

11.运行Tkinter事件循环:

python 复制代码
#运行Tkinter事件循环
root.mainloop()

12. 完整代码+运行结果

完整代码:

python 复制代码
import torch
import numpy as np
import torchvision
from os import path
from torchvision import datasets, models
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader
import torchvision.transforms as transforms
import os
import tkinter as tk
from PIL import Image, ImageTk
from tkinter import filedialog
import cv2
import subprocess
from tkinter import messagebox

# 设置数据目录和模型路径
data_dir = r'data'
model_path = 'cat_dog_classifier.pth'

# 定义图像转换
data_transforms = {
    'test': transforms.Compose([
        transforms.Resize(size=224),
        transforms.CenterCrop(size=224),
        transforms.ToTensor(),
        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
    ]),
}

# 使用GPU
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

# 加载没有预训练权重的ResNet模型
model = models.resnet50(pretrained=False)  # 使用pretrained=False
num_ftrs = model.fc.in_features
model.fc = nn.Linear(num_ftrs, 2)
model.load_state_dict(torch.load(model_path))
model = model.to(device)
model.eval()

# 创建Tkinter窗口
root = tk.Tk()
root.title('图像识别猫狗')
root.geometry('800x650')

image = Image.open("图像识别背景.gif")
image = image.resize((800, 650))  # 调整背景图片大小
photo1 = ImageTk.PhotoImage(image)
canvas = tk.Label(root, image=photo1)
canvas.pack()


# 添加文本标签来显示识别结果
result_label = tk.Label(root, text="", font=('Helvetica', 18))
result_label.place(x=280, y=450)

# 原始图像标签
image_label = tk.Label(root, text="", image="")
image_label.place(x=210, y=55)

# 保存用户选择的图片路径
selected_image_path = None

# 加载测试数据集
image_datasets = {x: datasets.ImageFolder(root=os.path.join(data_dir, x),
                                          transform=data_transforms[x])
                  for x in ['test']}
dataloaders = {x: DataLoader(image_datasets[x], batch_size=1, shuffle=False)
               for x in ['test']}
dataset_sizes = {x: len(image_datasets[x]) for x in ['test']}
class_names = image_datasets['test'].classes  # 定义class_names


# 加载Haar特征级联分类器
cat_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalcatface.xml')
dog_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_alt2.xml')

# 定义一个函数来打开文件选择对话框并显示图片
def choose_image():
    global selected_image_path
    file_path = filedialog.askopenfilename(initialdir=data_dir, title="选择图片",
                                           filetypes=(("图片文件", "*.png *.jpg *.jpeg *.gif *.bmp"), ("所有文件", "*.*")))
    if file_path:
        selected_image_path = file_path
        img = Image.open(file_path)
        img = img.resize((400, 350), Image.LANCZOS)
        imgTk = ImageTk.PhotoImage(img)
        image_label.config(image=imgTk)
        image_label.image = imgTk

# 定义一个函数来使用模型进行预测
def predict_image():
    global selected_image_path
    if selected_image_path:
        img = Image.open(selected_image_path)
        transform = data_transforms['test']
        img_tensor = transform(img).unsqueeze(0).to(device)

        with torch.no_grad():
            outputs = model(img_tensor)
            _, preds = torch.max(outputs, 1)

        prediction = class_names[preds.item()]  # 使用str()来将整数转换为字符串
        result_label.config(text=f"检测到的结果为: {prediction}")

        # 使用OpenCV在原始图像上绘制矩形框
        img_cv2 = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)

        if prediction == 'cats':
            cats = cat_cascade.detectMultiScale(img_cv2, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
            for (x, y, w, h) in cats:
                cv2.rectangle(img_cv2, (x, y), (x + w, y + h), (0, 0, 255), 2)  # 红色矩形框
            if len(cats) > 0:
                cv2.imwrite("detected_cats_image.jpg", img_cv2)  # 保存带有猫矩形框的图像
                img_detected_cats = Image.open("detected_cats_image.jpg").resize((350, 300), Image.LANCZOS)
                imgTk_detected_cats = ImageTk.PhotoImage(img_detected_cats)
                image_label.config(image=imgTk_detected_cats)
                image_label.image = imgTk_detected_cats
        elif prediction == 'dogs':
            dogs = dog_cascade.detectMultiScale(img_cv2, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
            for (x, y, w, h) in dogs:
                cv2.rectangle(img_cv2, (x, y), (x + w, y + h), (0, 0, 255), 2)  # 红色矩形框
            if len(dogs) > 0:
                cv2.imwrite("detected_dogs_image.jpg", img_cv2)  # 保存带有狗矩形框的图像
                img_detected_dogs = Image.open("detected_dogs_image.jpg").resize((350, 300), Image.LANCZOS)
                imgTk_detected_dogs = ImageTk.PhotoImage(img_detected_dogs)
                image_label.config(image=imgTk_detected_dogs)
                image_label.image = imgTk_detected_dogs
        else:
            print("未检测到猫或狗。")
            # 显示修改后的图像
        img = cv2.cvtColor(img_cv2, cv2.COLOR_BGR2RGB)
        img = cv2.resize(img, (400, 350))
        imgTk = ImageTk.PhotoImage(image=Image.fromarray(img))
        image_label.config(image=imgTk)
        image_label.image = imgTk
    else:
        print("请先选择一张图片。")


# 退出程序的函数
def close():
    subprocess.Popen(["python","主页面.py"])
    root.destroy()

# 创建按钮
image = Image.open("选择图片.gif")  # 加载一张图片
photo2 = ImageTk.PhotoImage(image)
bt1 = tk.Button(root, image=photo2, width=200, height=32, command=choose_image)
bt1.place(x=60, y=530)

image = Image.open("开始识别.gif")  # 加载一张图片
photo3 = ImageTk.PhotoImage(image)
bt1 = tk.Button(root, image=photo3, width=200, height=32, command=predict_image)
bt1.place(x=300, y=530)

image = Image.open("退出程序.gif")  # 加载一张图片
photo4 = ImageTk.PhotoImage(image)
bt1 = tk.Button(root, image=photo4, width=200, height=32, command=close)
bt1.place(x=535, y=530)

# 运行Tkinter事件循环
root.mainloop()

运行结果:

相关推荐
GuWenyue9 分钟前
Cursor黑盒拆解!1套LangChain.js手写Mini编程Agent,自动生成React项目,效率提升60%
前端·数据库·人工智能
GuWenyue9 分钟前
传统Agent工具两大痛点!300行代码落地MCP跨语言工具,彻底解耦LLM与工具
前端·人工智能·算法
老云讲算力市场20 分钟前
WAIC首日观察:国产算力与机器人加速落地,奇点算力迎来产业新机遇
人工智能·科技
小林ixn34 分钟前
大模型随机说话的秘密:Temperature 和 Top K 深度解析,LangChain 实战调优
人工智能·langchain
ALINX技术博客1 小时前
ALINX 亮相 2026 WAIC 世界人工智能大会,展示 AI 视觉 FPGA+GPU 异构计算与电子后视镜解决方案
人工智能·ai·fpga·世界人工智能大会·电子后视镜
程序员老猫1 小时前
当 AI 能写 80% 的代码时,后端工程师的核心价值还剩什么?
人工智能
想会飞的蒲公英1 小时前
计算机怎样读取中文文本:编码、清洗与标准化
人工智能·python·自然语言处理
CIO_Alliance2 小时前
AI+iPaaS解决方案深度整合:让跨系统业务流程自动化一步到位
人工智能·ipaas·系统集成·ai+ipaas·企业cio联盟·企业级ai化转型
苏州IT威翰德2 小时前
算力资产“续命”专家:苏州威翰德科技赋能NVIDIA高端AI芯片芯片级维修
大数据·人工智能
天上路人2 小时前
A59P双波束语音模块:神经网络降噪在远场拾音中的工程实现分析
人工智能·深度学习·神经网络·ai降噪·ai语音·麦克风·回音消除