医学YOLOv8 | 脑肿瘤检测 Accuracy 99%

news2024/9/23 13:21:36

b6351a31a8ecfb57ba30eea1e7fd4ffc.png

在医疗保健领域,准确和高效地识别脑肿瘤是一个重大挑战。本文中,我们将探讨一种使用 YOLOv8,一种先进的目标检测模型,将脑肿瘤进行分类的新方法,其准确率达到了 99%。通过将深度学习与医学图像相结合,我们希望这种方法将提高脑肿瘤识别的速度和准确性。

首先,我们将从 Kaggle 获取脑肿瘤分类数据集。然后,我们将利用各种数据清理方法来准备数据,以输入到我们的模型中。接下来,我们将从 Ultralytics 下载 YOLOv8,并对其进行调整以适应我们的具体情况。最后,我们将创建一个 FastAPI 应用程序以实现简化的使用。

1. 探索数据集

让我们仔细看看刚刚从 Kaggle 下载的数据集。数据集已经被分为训练集和测试集。数据集中有四种不同的肿瘤类别:胶质瘤、脑膜瘤、垂体瘤和无肿瘤。每个类别在训练集中约有 1300 个示例,在测试集中约有 300 个示例。

2. 数据准备

在此过程中,我们将利用各种技术来清理数据集图像。这些技术包括识别和删除损坏的图像,以及消除尺寸明显较小的图像。

2.1 删除损坏的图像

在这个过程中,我们必须检查每个类别中的所有图像,并验证它们是否可以使用 cv.imread 打开。如果无法打开,就必须从数据集中删除它,因为它可能是损坏的图像或根本不是图像文件。

2.2 删除尺寸不合格的图像

另一个数据清理技术涉及检查图像是否低于某个尺寸阈值并将其删除。这很重要,因为冗余数据可能会对我们的模型性能产生负面影响。下面的代码可以一次删除所有损坏的和低于阈值的图像。

import os
import cv2


train_dir = "BrainTumor/train"


categories = ["glioma", "meningioma", "notumor", "pituitary"]


size_threshold = (10,10)
valid_extensions=('.jpg', '.png', '.jpeg')


def is_image_corrupt(image_path):
    try:
        img = cv2.imread(image_path)
        if img is None:
            return True
        return False
    except:
        return True
    




def is_image_below_threshold(img_path):
    img = cv2.imread(image_path)
    if img.shape <= size_threshold:
        print(img.shape)
        return True
    return False
    


for each_category in categories:
    folder_path = os.path.join(train_dir, each_category)
    for each_file in os.listdir(folder_path):
        image_path = os.path.join(folder_path, each_file)
        if os.path.isfile(image_path) and each_file.lower().endswith(valid_extensions):
            if is_image_corrupt(image_path) or is_image_below_threshold(image_path):
                os.remove(image_path)
                print(f"Removed corrupt image: {each_file}")

3. 数据分析

作为分析的一部分,我们将检查数据集以确定总记录数和每个类别的图像数量。我们还将评估类别的分布,并生成图表以增进对数据的理解。

这种方法允许我们从数据中获得洞察,以防止在将其输入模型时出现过拟合和欠拟合问题。

import matplotlib.pyplot as plt
import os


train_dir = "/BrainTumor/train"
valid_extensions=('.jpg', '.png', '.jpeg')


categories = ["glioma", "meningioma", "notumor", "pituitary"]
category_count = {}


for each_category in categories:
    folder_path = os.path.join(train_dir, each_category)
    valid_images = [file for file in os.listdir(folder_path) if file.lower().endswith(valid_extensions)]
    category_count[each_category] = len(valid_images)


fig, ax = plt.subplots(figsize=(10, 4))


# Bar chart
bar_plot = plt.barh(list(category_count.keys()), list(category_count.values()), 0.5)
plt.title('Tumor Type Distribution')
plt.xlabel('Count')
plt.ylabel('Tumor Type')
for i, bar in enumerate(bar_plot):
    plt.text(bar.get_width(), bar.get_y() + bar.get_height() / 2, str(list(category_count.values())[i]), ha='left', va='center')


plt.show()






sample_size = sum(category_count.values())


class_dist = {key : val/sample_size for key, val in category_count.items()}




fig, ax = plt.subplots(figsize=(10, 4))




# Bar chart
bar_plot = plt.barh(list(class_dist.keys()), list(class_dist.values()), 0.6)
plt.title('Class Distribution')
plt.xlabel('Class')
plt.ylabel('Percentage')


for i, bar in enumerate(bar_plot):
    plt.text(bar.get_width(), bar.get_y() + bar.get_height() / 2, str(round(list(class_dist.values())[i], 3)), ha='left', va='center')


plt.show()

所展示的代码将创建两个条形图,表示每个类别的图像数量和类别分布。图表显示我们的数据分布均匀,虽然在“无肿瘤”类中的图像数量稍多,但与其他类别相比仍然相对平衡。

824715383b88df3fcaeb4d782f38af40.png

4. 数据可视化

在将数据输入之前,用肉眼查看它对于更好的理解是很重要的。下面提供的代码显示了每个类别的一张图像。

import matplotlib.pyplot as plt
import os
train_dir = "/BrainTumor/train"
valid_extensions=('.jpg', '.png', '.jpeg')


categories = ["glioma", "meningioma", "notumor", "pituitary"]


plt.figure(figsize=(12, 8))
for i, category in enumerate(categories):
    folder_path = os.path.join(train_dir, category)
    image_path = os.path.join(folder_path, os.listdir(folder_path)[0])
    if not image_path.lower().endswith(valid_extensions):
        continue
    img = plt.imread(image_path)
    plt.subplot(2, 2, i+1)
    plt.imshow(img)
    plt.title(category)
    plt.axis("off")
plt.tight_layout()
plt.show()

输出:

7d5133b35b0a53ec46710f5206f9a687.png

5. 训练模型

在脑肿瘤分类项目中,我们将使用 YOLOv8 预训练模型。我们的第一步将是将这个模型导入项目中。接下来,我们将用我们的数据集微调预训练模型。最后,我们将在测试数据上评估模型,以确定每个类别的准确性。

from ultralytics import YOLO


model = YOLO('yolov8m-cls.pt')  # load a pretrained YOLOv8n classification model


# train/pre-tuned the model on our dataset
model.train(data='BrainTumor', epochs=3)


# run the model on test data
res = model.val()


# Result saved to runs/classify/val

要获得归一化混淆矩阵,导航到当前目录中的 runs/classify/val 文件夹。一旦进入那里,您将能够以以下图像的形式查看它。

5cdae64608fe4355af7c21ebbd8d9064.png

从所提供的数据中,模型在三个类别上达到了 100% 的性能,而在一个类别(脑膜瘤)上达到了 96%。因此,总准确性可以计算如下: (100 x 3 + 96) / 4 = 99%。

6. 测试自定义图像

在项目的最后一步,我们将在 FastAPI 中建立一个端点。这个端点将接受图像作为输入,并返回图像的标签预测。有了这个功能,我们可以轻松地在任何选择的图像上测试我们的模型。在微调模型后,它将生成另一个预训练模型文件(.pt),位于/run/classify/train/weights/best.pt 中。我们将将此文件集成到我们的 FastAPI 项目中。

以下是运行在端口 8000 上的 FastAPI 代码,它有一个 /images 的端点。这个端点将以图像作为输入,并返回由我们的模型(best.pt)预测的图像标签。

import subprocess
from fastapi import FastAPI, UploadFile, File
from ultralytics import YOLO




def model_train():
    model = YOLO('./runs/classify/train/weights/best.pt')  # load a pretrained YOLOv8n classification model
    return model




app = FastAPI()


model_data = None




@app.post("/images/")
def create_upload_file(image: UploadFile = File(...)):
    global model_data
    if model_data is None:
        model_data = model_train()


    with open(f"./images/{image.filename}", "wb+") as f:
        f.write(image.file.read())


    result = model_data(f"./images/{image.filename}")


    return {"result": result[0].names[result[0].probs.top1]}




def run_uvicon():
    uvicorn_command = [
        "uvicorn",
        "main:app",
        "--host", "127.0.0.1",
        "--port", "8000",
        "--reload",
    ]


    subprocess.run(uvicorn_command, check=True)




if __name__ == "__main__":
    run_uvicon()

输出:

0bdd2448b348f1bd57d05d01dbc598dc.png

结论

总之,我们文章中使用的数据是从 Kaggle 平台获取的。在此之后,我们对数据进行了清理处理,然后将其输入到模型中,最终生成了归一化混淆矩阵。作为最后一步,我们使用 FastAPI 建立了一个端点,使我们能够以高度准确和高效的方式进行预测,并随后返回输入系统的任何肿瘤图像的类别。

·  END  ·

HAPPY LIFE

f911e04d4d0341a3db2c5373bacc4f0f.png

本文仅供学习交流使用,如有侵权请联系作者删除

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

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

相关文章

Python算法例1 完美平方

例1 完美平方 1. 问题描述 给定一个正整数n&#xff0c;找到若干个完全平方数&#xff08;例如&#xff1a;1&#xff0c;4&#xff0c;9&#xff0c;…&#xff09;&#xff0c;使得它们的和等于n&#xff0c;完全平方数的个数最少。 2.问题示例 给出n8&#xff0c;返回2&…

【51单片机】:智能施工电梯系统

项目效果&#xff1a; 基于51单片机的智能施工电梯系统 摘 要 智能施工电梯系统目前广泛应用于人们建筑工程中&#xff0c;为人们施工时上下搬运提供了极大的便利。智能施工电梯系统包括密码开启、超重提示&#xff0c;电梯运作及相关信息显示等等功能&#xff0c;施工电梯为我…

数组中出现次数超过一半的数字整型数组有一个数字出现的次数超过总数的一半,请找出该数字

例如长度为 9 的数组{1,2,3,2,4,2,5,2,2}。 由于 2 出现的次数是 5 次,超过一半,所以结果为2。 算法一&#xff1a; 先排序,然后中间值就是要找的数字 图解&#xff1a; int Cmp_int(const void* vp1, const void* vp2) //定义排序规则 {return * (int*)vp1 - *(int*)vp2; } …

ts | js | 爬虫小公举分享

Curl转Code 快速将curl转为各种语言的代码; 便于提取请求头之类, 或者微改直接使用 https://curlconverter.com/node-axios/ (有点慢, 但是很全)https://www.lddgo.net/convert/curl-to-code (没有axios, 我喜欢用axios) 使用… 抓取地址, 使用浏览器或者其他抓包工具都可, 这…

IP地址在互联网中有哪些作用?

在互联网中&#xff0c;IP地址是一种用于唯一标识网络中设备的地址。IP地址不会与其他网络地址&#xff08;如MAC地址、URL、域名等&#xff09;发生冲突&#xff0c;因为它们各自在不同的网络层次上起作用&#xff0c;用于不同的目的。 IP地址&#xff08;Internet Protocol A…

vue3中常用的新组件

一、Fragment vue2中&#xff0c;组件必须有一个根标签 vue3中&#xff0c;组件可以没有根标签&#xff0c;内部会将多个标签包含在一个Fragment虚拟元素中。 优点&#xff1a;减少标签层级。 二、Teleport&#xff08;传送门&#xff09; 作用&#xff1a;将组件的 html …

企事业单位/公司电脑文件透明加密保护 | 防泄密软件\系统!

推荐——「天锐绿盾电脑文件防泄密系统」 一款全面的企业/公司数据透明加密防泄密系统&#xff0c;旨在从源头上保障数据的安全和使用安全。 PC访问地址&#xff1a; https://isite.baidu.com/site/wjz012xr/2eae091d-1b97-4276-90bc-6757c5dfedee 它具有以下特点&#xff1a…

小程序 swiper滑动 层叠滑动效果

整个红色区域为可滑动区域&#xff0c;数字1区域为展示区域&#xff0c;数字2为下一个展示模块 <scroll-view class"h_scroll_horizontal" enhanced"ture" bind:touchend"touchEnd" bind:touchstart"touchStart"><view clas…

vs c++ 代码 c2362错误

c 开发调试bug 报错 c2362错误 goto语句的使用错误。 我的使用是这样的&#xff1a; goto __end; int nLen value; gto _end; int pBuffer value2;end:我的 nlen 和 pBuffer 直接初始化了&#xff0c;而 goto 与标签之间有任何初始化的语句都不可以&#xff0c;除非用括号把…

CTF-Crypto-第一天-常见编码and古典密码(入门学习笔记)(详)

文章目录 前言0x1 常见编码0x01 编码0x02 ASCII码0x03 Base系列编码0x04其他编码- URL编码-莫尔斯电码&#xff08;Morse Code&#xff09;-HTML实体编码-其他中的其他... 0x05编码与加密的关系 古典密码凯撒密码简单替换密码维吉尼亚密码栅栏密码其他古典密码替换加密移位加密…

c语言从入门到实战——分支和循环

分支和循环 前言1. if语句1.1 if1.2 else1.3 分支中包含多条语句1.4 嵌套if1.5 悬空else问题 2. 关系操作符3. 条件操作符4. 逻辑操作符&#xff1a;&& , || , &#xff01;4.1 逻辑取反运算符4.2 与运算符4.3 或运算符4.4 练习&#xff1a;闰年的判断4.5 短路 5. swit…

net::ERR_BLOCKED_BY_ADMINISTRATOR 问题定位与解决

本文基于谷歌浏览器调试手机应用 chrome://inspect/#devices 我有一个非常简单的广告页面&#xff0c;页面中有一张背景图&#xff0c;和一个按钮 他本应该是这样的 但实际上只显示了最下方的按钮&#xff0c;整个图片是空白的 页面仅在小米浏览器不显示背景图片&#xff0c;…

责任链模式应用案例

前几天系统商品折扣功能优化&#xff0c;同事采用了责任链模式重构了代码&#xff0c;现整理如下。 一、概念 责任链模式是为请求创建一个处理者对象的链条&#xff0c;所有处理者&#xff08;除最末端&#xff09;都含有下一个对象的引用从而形成一条处理链&#xff0c;该模…

怎么防止文件夹被删除、复制?

当文件夹中存放重要数据时&#xff0c;我们需要严格保护文件夹的安全&#xff0c;避免文件夹被复制、删除。那么&#xff0c;该怎么防止文件夹被删除、复制呢&#xff1f;下面我们就一起来了解一下。 ​文件夹隐藏 当文件夹被隐藏时&#xff0c;其他人无法发现文件夹&#xff…

Redis两种持久化方案RDB 和 AOF

Redis 作为一种非常流行的内存数据库&#xff0c;通过将数据保存在内存中&#xff0c;Redis 得以拥有极高的读写性能。但是一旦进程退出&#xff0c;Redis 的数据就会全部丢失。 为了解决这个问题&#xff0c;Redis 提供了 RDB 和 AOF 两种持久化方案&#xff0c;将内存中的数据…

排序算法-堆积树排序法(HeapSort)

目录 排序算法-堆积树排序法&#xff08;HeapSort&#xff09; 1、说明 2、算法分析 3、C代码 排序算法-堆积树排序法&#xff08;HeapSort&#xff09; 1、说明 堆积树排序法是选择排序法的改进版&#xff0c;可以减少在选择排序法中的比较次数&#xff0c;进而减少排序…

禾匠旧版对接微信小程序发货系统(发货信息管理 接口)

最近小程序如果是商家交易需要再小程序后台点击一下发货&#xff0c;特别麻烦&#xff0c;但是旧版的禾匠又没有这个功能&#xff0c;所以只能手动增加这个功能&#xff0c;但是每一个版本发货逻辑都不一样&#xff0c;大家只能自己手动去兼容一下&#xff0c;下面只是写了一个…

NewStarCTF2023week4-RSA Variation II

题目提示&#xff1a;"Schmidt Samoa" Schmidt-Samoa密码系统&#xff0c;像rabin加密一样&#xff0c;其安全性基于整数因式分解的难度。但 Rabin 解密时会得到四个解&#xff0c;而 Schmidt-Samor 得到的是唯一解。 N p*p*q&#xff0c;知道c、n、d 上脚本&…

【数据结构初阶】顺序表和链表(1)

顺序表和链表&#xff08;1&#xff09; 1.线性表2.顺序表2.1概念以及结构2.1.1静态顺序表2.1.2动态顺序表3.顺序表的实现3.1初始化内容3.2初始化函数3.3销毁函数3.4打印函数3.5扩容函数3.6尾插3.6尾删函数3.7头插函数3.8头删函数3.9查找函数3.10插入函数3.11删除函数3.12修改函…

Linux msend.pl配置

1.概述 1.1.说明​​​​​ 本文细描述Linux环境下(arm架构x64)基于perl的msend.pl配置,以实现根据msend.pl进行告警事件的发送。 1.2.环境说明 OS Version:RHEL7.6(arm架构x64) Perl Version: v5.16.3 1.3.msend.pl架构图 2.msend.pl配置 2.1.msend.pl配置 前提:以r…