猫狗识别—静态图像识别

news2024/10/7 4:22:31

猫狗识别—静态图像识别

  • 1. 导入必要的库:
  • 2. 设置数据目录和模型路径:
  • 3. 定义图像转换
  • 4. 使用GPU
  • 5. 加载没有预训练权重的ResNet模型
  • 6. 创建Tkinter窗口:
  • 7.定义选择图片的函数:
  • 8.定义预测图片的函数:
  • 9.退出程序的函数:
  • 10.创建按钮:
  • 11.运行Tkinter事件循环:
  • 12. 完整代码+运行结果
    • 完整代码:
    • 运行结果:

1. 导入必要的库:

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变量设置了预训练模型的路径。
#设置数据目录和模型路径
data_dir = r'data'
model_path = 'cat_dog_classifier.pth'

3. 定义图像转换

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

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

5. 加载没有预训练权重的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()

6. 创建Tkinter窗口:

#创建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.定义选择图片的函数:

#定义一个函数来打开文件选择对话框并显示图片
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.定义预测图片的函数:

#定义一个函数来使用模型进行预测
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.退出程序的函数:

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

10.创建按钮:

#创建按钮
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事件循环:

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

12. 完整代码+运行结果

完整代码:

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()

运行结果:

在这里插入图片描述

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

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

相关文章

不止是只有维度建模,数据仓库还有Data Vault建模

引言 在数据仓库设计中,传统的星型和雪花型模型有着各自的优势和劣势。随着数据量的增大和数据源的多样化,Data Vault(数据仓库)建模方法逐渐受到关注和应用。Data Vault建模是一种灵活、可扩展、适应性强的建模方法,…

视频多功能闪剪助手,智能去重去水印一键剪辑

这款软件具有全平台去水印的功能,无论视频来自哪个平台,无论水印的位置如何变换,它都能轻松去除。同时,它还支持各种去重方法,无论重复内容的形式如何,它都能一一识别并移除,让你的视频内容始终…

HarmonyOS Next开发学习手册——层叠布局 (Stack)

概述 层叠布局(StackLayout)用于在屏幕上预留一块区域来显示组件中的元素,提供元素可以重叠的布局。层叠布局通过 Stack 容器组件实现位置的固定定位与层叠,容器中的子元素依次入栈,后一个子元素覆盖前一个子元素&…

SpringCloud Alibaba Sentinel规则持久化实践总结

默认情况下&#xff0c;一旦我们重启应用&#xff0c;sentinel规则将消失&#xff0c;生产环境需要将配置规则进行持久化。这里我们实践将Sentinel持久化到Nacos中。 ① pom依赖 我们引入sentinel-datasource-nacos&#xff1a; <dependency><groupId>com.aliba…

【Android Studio】Notification通知提醒功能完整代码以及踩坑记录

前言&#xff1a;在最近学习安卓通知功能的开发中&#xff0c;遇到了一些坑&#xff0c;困扰了我一些时间&#xff0c;搜集了大量资料写个博客总结一下&#xff0c;希望对大家有帮助。 目录 一、启动项目闪退 1.1、问题详情 1.2、解决方法 二、点击通知无法跳转 2.1、问题…

计算机缺失OpenCL.dll怎么办,OpenCL.dll丢失的多种解决方法

在使用电脑的过程中&#xff0c;我们经常会遇到一些开机弹窗问题。其中&#xff0c;开机弹窗找不到OpenCL.dll是一种常见的情况。本文将详细介绍开机弹窗找不到OpenCL.dll的原因分析、解决方法以及预防措辞&#xff0c;帮助大家更好地解决这一问题。 一&#xff0c;了解OpenCL.…

[AIGC] Doris:一款高效的MPP数据仓库引擎

在大数据处理的领域中&#xff0c;Apache Doris&#xff08;原百度 Palo&#xff09;是一个高效的MPP&#xff08;大规模并行处理&#xff09;数据仓库&#xff0c;最初由百度开发&#xff0c;现在已经成为Apache的孵化项目。 (图片取自百度) – 文章目录 1. Doris的基础知识…

并发 多线程

目录 thread thread 类总览 构造函数 join joinable ​编辑 detach swap yield swap 成员函数的调用 namespace::this_thread 线程同步--锁 互斥锁mutex 递归锁recursive_mutex 定时锁 Lock 锁辅助类 lock_guard​编辑 unique_lock std::lock 解决死锁问题 消息…

华为认证hcna题库背诵技巧有哪些?hcna和hcia有什么区别?

大家都知道华为认证hcna是有题库供考生刷题备考的&#xff0c;但题库中海量的题目想要在短时间背诵下来可并不是一件容易的事情&#xff0c;这就需要我们掌握一定的技巧才行。华为认证hcna题库背诵技巧有哪些? hcna和hcna这二者又有什么区别呢?今天的文章将为大家进行详细解…

鸿蒙开发设备管理:【@ohos.batteryInfo (电量信息)】

电量信息 该模块主要提供电池状态和充放电状态的查询接口。 说明&#xff1a; 本模块首批接口从API version 6开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 导入模块 import batteryInfo from ohos.batteryInfo;属性 描述电池信息。 系统能…

汇川学习笔记7 - 雕刻机项目

1、系统上电轴准备好之后&#xff0c;自动复回原点一次&#xff0c; 2、在雕刻机面板上有三个按钮用来控制画三种图形 3、注意cnc代码放置的文件夹 4、FILE0文件内容 5、FILE1文件内容 6、FILE2文件内容 7、程序代码下载地址 https://download.csdn.net/download/qq_6191667…

设置日历程序

目录 一 设计原型 二 后台源码 一 设计原型 二 后台源码 namespace 设置日历 {public partial class Form1 : Form{public Form1(){InitializeComponent();}private void dateTimePicker1_ValueChanged(object sender, EventArgs e){richTextBox1.Text dateTimePicker1.T…

CCSP自考攻略+经验总结

备考攻略 备考攻略准备阶段通读阶段精度阶段总复习阶段刷题阶段命运审判 写到最后 备考攻略 趁着对ssp知识点的理解还在&#xff0c;开始ccsp的考证之路&#xff0c;文章结构还是按照cissp备考篇的结构梳理。本次备考和cissp的离职在家备考不同&#xff0c;ccsp是在职利用非工…

鸿蒙开发Ability Kit(程序框架服务):【ServiceAbility切换】 组件切换

ServiceAbility切换 FA模型中的ServiceAbility对应Stage模型中的ServiceExtensionAbility。Stage模型下的ServiceExtensionAbility为系统API&#xff0c;只有系统应用才可以创建。因此&#xff0c;FA模型的ServiceAbility的切换&#xff0c;对于系统应用和三方应用策略有所不同…

【深度学习】实践方法论

李宏毅深度学习笔记 优化问题 训练数据的损失不够低的时候&#xff0c;到底是模型偏差&#xff0c;还是优化的问题&#xff1f; 判断方法是通过比较不同的模型来判断模型现在到底够不够大 看到一个从来没有做过的问题&#xff0c;可以先跑一些比较小的、比较浅的网络&#x…

React@16.x(42)路由v5.x(7)常见应用场景(4)- 路由切换动画

目录 1&#xff0c;实现路由切换基础样式 2&#xff0c;使用 CSSTransition 添加动画1&#xff0c;自定义动画组件 *TransitionRoute.jsx*2&#xff0c;*App.jsx*3&#xff0c;样式改动 3&#xff0c;注意点 通过一个例子来说明如何实现。 1&#xff0c;实现路由切换 基础样式…

【Linux:文件描述符】

文件描述符&#xff1a; 文件描述符的分配原则&#xff1a;最小未分配原则 每一个进程中有一个task_struct结构体&#xff08;PCB)&#xff0c;而task_struct中含有struct file_sturct*file的指针&#xff0c;该指针指向了一个struct files_struct的结构体该结构体中含有一个f…

win10系统打开Windows更新是空白的如何解决?

最近装wsl的时候&#xff0c;遇到了这个问题。查阅了很多相关资料&#xff0c;发现导致wsl --install安装不了的主要原因都集中在于windows更新组件损坏导致的&#xff0c;经过排查&#xff0c;我的这个组件确实不能够正常使用&#xff0c;可能是因为之前使用了windows激活工具…

网络治理新模式:Web3时代的社会价值重构

随着Web3技术的崛起&#xff0c;传统的网络治理模式正在经历革新&#xff0c;这不仅仅是技术的进步&#xff0c;更是对社会价值观念的挑战和重构。本文将深入探讨Web3时代的网络治理新模式&#xff0c;其背后的技术基础、社会影响以及未来的发展方向。 1. 引言 Web3时代&#…

【机器学习300问】134、什么是主成分分析(PCA)?

假设你的房间堆满了各种各样的物品&#xff0c;书籍、衣服、玩具等等&#xff0c;它们杂乱无章地散落各处。现在&#xff0c;你想要清理房间&#xff0c;但又不想扔掉任何东西&#xff0c;只是希望让房间看起来更整洁&#xff0c;更容易管理。 你开始思考&#xff0c;能否将物品…