yolov8标注细胞、识别边缘、计算面积、灰度值计算
一、数据标注
1. 使用labelme软件标注每个细胞的边界信息,标注结果为JSON格式
2. JSON格式转yolo支持的txt格式
import json
import os
import glob
import os.path as osp'''此函数用来将labelme软件标注好的数据集转换为yolov5_7.0sege中使用的数据集:param jsonfilePath: labelme标注好的*.json文件所在文件夹:param resultDirPath: 转换好后的*.txt保存文件夹:param classList: 数据集中的类别标签
'''
def labelme2yolov2Seg(jsonfilePath, resultDirPath, classList):# 0.创建保存转换结果的文件夹if (not os.path.exists(resultDirPath)):os.mkdir(resultDirPath)# 1.获取目录下所有的labelme标注好的Json文件,存入列表中jsonfileList = glob.glob(osp.join(jsonfilePath, "*.json") )print(jsonfileList) # 打印文件夹下的文件名称# 2.遍历json文件,进行转换for jsonfile in jsonfileList:# 3. 打开json文件with open(jsonfile, "r",encoding='UTF-8') as f:file_in = json.load(f)# 4. 读取文件中记录的所有标注目标shapes = file_in["shapes"]# 5. 使用图像名称创建一个txt文件,用来保存数据with open(resultDirPath + "\\" + jsonfile.split("\\")[-1].replace(".json", ".txt"), "w") as file_handle:# 6. 遍历shapes中的每个目标的轮廓for shape in shapes:# 7.根据json中目标的类别标签,从classList中寻找类别的ID,然后写入txt文件中file_handle.writelines(str(classList.index(shape["label"])) + " ")# 8. 遍历shape轮廓中的每个点,每个点要进行图像尺寸的缩放,即x/width, y/heightfor point in shape["points"]:x = point[0] / file_in["imageWidth"] # mask轮廓中一点的X坐标y = point[1] / file_in["imageHeight"] # mask轮廓中一点的Y坐标file_handle.writelines(str(x) + " " + str(y) + " ") # 写入mask轮廓点# 9.每个物体一行数据,一个物体遍历完成后需要换行file_handle.writelines("\n")# 10.所有物体都遍历完,需要关闭文件file_handle.close()# 10.所有物体都遍历完,需要关闭文件f.close()if __name__ == "__main__":jsonfilePath = r"D:/workspace/yolov8/datasets/json" # 要转换的json文件所在目录resultDirPath = r"D:/workspace/yolov8/datasets/txt" # 要生成的txt文件夹labelme2yolov2Seg(jsonfilePath=jsonfilePath, resultDirPath=resultDirPath, classList=['danhe','linba','yilin']) # 更改为自己的类别名
转换结果:
二、训练数据
1. 配置文件
路径:ultralytics\cfg\datasets\cell_seg.yaml
path: ../datasets/cell_seg # dataset root dir
train: images/train # train images (relative to 'path')
val: images/val # val images (relative to 'path')
test: test/images # test images (optional)nc: 2# Classes
names:0: danhe1: linba
2. 训练脚本
# 细胞实例分割训练
from ultralytics import YOLOmodel = YOLO('yolov8n-seg.pt')
# 训练自己的数据集, 文件路径: ultralytics/cfg/datasets/cell_seg.yaml
model.train(data='cell_seg.yaml', epochs=100, imgsz=320)
# 使用验证集 验证效果
model.val()
3. 训练结果
三、使用上述训练的模型,批量检测细胞、计算细胞面积、灰度值计算
1. 预测细胞类别及轮廓
# 细胞实例分割训练
from ultralytics import YOLO
# best_seg.pt 训练结果中weight/best.pt
model = YOLO('best_seg.pt')
# 测试数据 批量检测
predict_results = model.predict(source="../datasets/cell/test/images", save=True)
2. 识别轮廓、计算面积
from ultralytics import YOLO
import cv2
import os
import numpy as np# Load a pretrained YOLOv8n model
model = YOLO('best_seg.pt')# Define path to the directory containing image files
source = '../datasets/cell/test/images'# 指定输出路径
output_dir = './output_images'
if not os.path.exists(output_dir):os.makedirs(output_dir)# 获取待预测文件名称,用于保存同名文件
def get_last_part_of_string(path):return os.path.basename(path)# hex to BGR
def hex_to_bgr(hex):return tuple(int(hex[i:i+2], 16) for i in (4, 2, 0))# 颜色,同plotting.py的设置
hexs = ("FF3838", "FF9D97", "FF701F", "FFB21D", "CFD231","48F90A", "92CC17", "3DDB86", "1A9334", "00D4BB","2C99A8", "00C2FF", "344593", "6473FF", "0018EC","8438FF", "520085", "CB38FF", "FF95C8", "FF37C7"
)
colors = [hex_to_bgr(h) for h in hexs]# 开始预测
results = model(source=source, save=False) # list of Results objectsfor result in results:image_path = result.pathimage = cv2.imread(image_path)boxes = result.boxes # Boxes 对象,用于边界框输出masks = result.masks # Masks 对象,用于分割掩码输出names = result.names # 获取类别名称字典for box, mask in zip(boxes, masks):for cls, contour in zip(box.cls, mask.xy):class_id = int(cls.item()) # 获取张量的值并转换为整数color = colors[class_id % len(colors)] # 获取颜色contour = np.array(contour, dtype=np.int32) # 确保轮廓是整数类型area = cv2.contourArea(contour) # 计算轮廓面积class_name = names[class_id] # 获取类别名称# 计算轮廓的中心M = cv2.moments(contour)if M['m00'] != 0:cx = int(M['m10'] / M['m00'])cy = int(M['m01'] / M['m00'])else:cx, cy = 0, 0'''cv2.drawContours 参数:image: 输入图像,一般是二值图像或彩色图像;contours: 要绘制的轮廓,是一个 Python 列表,每个列表元素都是一个 Numpy 数组,代表一个轮廓;contourIdx: 要绘制的轮廓的索引,默认为 -1, 代表绘制所有轮廓;color: 轮廓的颜色,是一个三元组,分别表示 RGB 颜色;thickness: 线条的粗细,默认为 1;lineType: 线条类型,默认为 cv2.LINE_8;hierarchy: 轮廓的层次关系,是一个 Numpy 数组;maxLevel: 最多绘制的轮廓层'''# 绘制掩码轮廓cv2.drawContours(image, [contour], -1, color, 2)# 在图像上绘制面积和类名text = f'{class_name} {area:.2f}''''cv2.putText 参数:img: 需要绘制文本的图像。text: 要绘制的文本内容。org: 文本框的左下角坐标,即起始点(x,y)。fontFace: 字体类型, 如cv2.FONT_HERSHEY_SIMPLEX、cv2.FONT_HERSHEY_PLAIN等。fontScale: 字体大小, float类型, 一般设置为1.0。color: 文本颜色, BGR格式。thickness: 文本粗细, 如果设置为None, 则表示绘制实心文字。lineType: 线型, 可选类型包括cv2.LINE_4、cv2.LINE_8、cv2.LINE_AA等。bottomLeftOrigin: 如果为True, 则图像数据原点在左下角(默认情况下在左上角)。'''cv2.putText(image, text, (cx, cy), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 1)# 保存图像output_path = os.path.join(output_dir, get_last_part_of_string(image_path))'''cv2.imwrite() 参数:filename: 要保存的文件路径和名称,包括路径(如果文件不在当前工作目录下)和文件扩展名(如 .jpg, .png 等)。img: 要保存的图像数据,通常是通过 OpenCV 读取或处理得到的。'''cv2.imwrite(output_path, image)print(f'Saved: {output_path}')
3. 灰度值提取
from ultralytics import YOLO
import cv2
import os
import numpy as np# Load a pretrained YOLOv8n model
model = YOLO('best_seg.pt')# Define path to the directory containing image files
source = '../datasets/cell/test/images'# 指定输出路径
output_dir = './output_images'
if not os.path.exists(output_dir):os.makedirs(output_dir)# 获取待预测文件名称,用于保存同名文件
def get_last_part_of_string(path):return os.path.basename(path)# hex to BGR
def hex_to_bgr(hex):return tuple(int(hex[i:i+2], 16) for i in (4, 2, 0))# 颜色,同plotting.py的设置
hexs = ("FF3838", "FF9D97", "FF701F", "FFB21D", "CFD231","48F90A", "92CC17", "3DDB86", "1A9334", "00D4BB","2C99A8", "00C2FF", "344593", "6473FF", "0018EC","8438FF", "520085", "CB38FF", "FF95C8", "FF37C7"
)
colors = [hex_to_bgr(h) for h in hexs]# 开始预测
results = model(source=source, save=False) # list of Results objectsn_points = 5
spacing = 30for result in results:image_path = result.pathimage = cv2.imread(image_path)boxes = result.boxes # Boxes 对象,用于边界框输出masks = result.masks # Masks 对象,用于分割掩码输出names = result.names # 获取类别名称字典# 将图片转换成灰度图gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)for box, mask in zip(boxes, masks):for cls, contour in zip(box.cls, mask.xy):class_id = int(cls.item()) # 获取张量的值并转换为整数color = colors[class_id % len(colors)] # 获取颜色contour = np.array(contour, dtype=np.int32) # 确保轮廓是整数类型area = cv2.contourArea(contour) # 计算轮廓面积class_name = names[class_id] # 获取类别名称# 计算轮廓的中心M = cv2.moments(contour)if M['m00'] != 0:cx = int(M['m10'] / M['m00'])cy = int(M['m01'] / M['m00'])else:cx, cy = 0, 0'''cv2.drawContours 参数:image: 输入图像,一般是二值图像或彩色图像;contours: 要绘制的轮廓,是一个 Python 列表,每个列表元素都是一个 Numpy 数组,代表一个轮廓;contourIdx: 要绘制的轮廓的索引,默认为 -1, 代表绘制所有轮廓;color: 轮廓的颜色,是一个三元组,分别表示 RGB 颜色;thickness: 线条的粗细,默认为 1;lineType: 线条类型,默认为 cv2.LINE_8;hierarchy: 轮廓的层次关系,是一个 Numpy 数组;maxLevel: 最多绘制的轮廓层'''# 绘制掩码轮廓cv2.drawContours(gray_image, [contour], -1, color, 2)# 在图像上绘制面积和类名text = f'{class_name} {area:.2f}'cv2.putText(gray_image, text, (cx, cy-20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 1)# 以轮廓为中心,在图像上绘制点for i in range(n_points):# 从中心店左移2个点的距离x = cx + i * spacing - spacing *2y = cy gray_value = gray_image[y, x]# 画点cv2.circle(gray_image, (x, y), 2, (255, 0, 0), 1)# 点描述cv2.putText(gray_image, str(i+1), (x-5, y-5), cv2.FONT_HERSHEY_SIMPLEX, 0.4, (255, 0, 0), 1)# cv2.circle(gray_image, (x-(i * spacing), y), 2, (0, 255, 0), 1) gray_text = f"Point {i+1}({x},{y}): gray value = {gray_value} "print(gray_text)# 将点的灰度值绘制在图片的左上角cv2.putText(gray_image, gray_text, (10, 15+i*15), cv2.FONT_HERSHEY_SIMPLEX, 0.4, (0, 0, 0), 1)# 保存图像output_path = os.path.join(output_dir, get_last_part_of_string(image_path))'''cv2.imwrite() 参数:filename: 要保存的文件路径和名称,包括路径(如果文件不在当前工作目录下)和文件扩展名(如 .jpg, .png 等)。img: 要保存的图像数据,通常是通过 OpenCV 读取或处理得到的。'''cv2.imwrite(output_path, gray_image)print(f'Saved: {output_path}')
相关文章:

yolov8标注细胞、识别边缘、计算面积、灰度值计算
一、数据标注 1. 使用labelme软件标注每个细胞的边界信息,标注结果为JSON格式 2. JSON格式转yolo支持的txt格式 import json import os import glob import os.path as osp此函数用来将labelme软件标注好的数据集转换为yolov5_7.0sege中使用的数据集:param jsonfi…...

WEB前端11-Vue2基础01(项目构建/目录解析/基础案例)
Vue2基础(01) 1.Vue2项目构建 步骤一:安装前端脚手架 npm install -g vue/cli步骤二:创建项目 vue ui步骤三:运行项目 npm run serve步骤四:修改vue相关的属性 DevServer | webpack //修改端口和添加代理 const { defineCo…...

QT--线程
一、线程QThread QThread 类提供不依赖平台的管理线程的方法,如果要设计多线程程序,一般是从 QThread继承定义一个线程类,在自定义线程类里进行任务处理。qt拥有一个GUI线程,该线程阻塞式监控窗体,来自任何用户的操作都会被gui捕获到,并处理…...

通过进程协作显示图像-C#
前言 如果一个软件比较复杂或者某些情况下需要拆解,可以考试将软件分解成两个或多个进程,但常规的消息传递又不能完全够用,使用消息共享内存,实现图像传递,当然性能这个方面我并没有测试,仅是一种解决思路…...
LangChain链与记忆处理[10]:四种基础内置链、四种文档处理链,以及链的自定义和五种运行方式,让你的大模型更加智能
LangChain链与记忆处理[10]:四种基础内置链、四种文档处理链,以及链的自定义和五种运行方式,让你的大模型更加智能 参考文章可以使用国产LLM进行下述项目复现: 初识langchain[1]:Langchain实战教学,利用qwen2.1与GLM-4大模型构建智能解决方案[含Agent、tavily面向AI搜索…...

京东发行稳定币的背后
加密市场很热,京东也要来分一杯羹? 7月24日,据财联社报道,京东科技旗下的京东币链科技 ( 香港 ) 将在香港发行与港元 1:1锚定的加密货币稳定币,在市场上掀起广泛热议。 由于众所周知的监管原因,国内大厂在早…...
CF1995C Squaring 题解
思路详解: 请注意,本题解用到了非整数计算,也就是说性能可能不如整数运算,但是易于实现,追求最优解的大佬不建议观看本题解。 这个题看似简单,但是由于涉及到了平方操作,不用高精度根本存不下&…...

动态规划之路径问题
动态规划算法介绍 基本原理和解题步骤 针对于动态规划的题型,一般会借助一个 dp 表,然后确定这个表中应该填入什么内容,最终直接返回表中的某一个位置的元素。 细分可以分为以下几个步骤: 创建 dp 表以及确定 dp 表中所要填写位…...
如何优化你的TikTok短视频账号运营策略?
在运营TikTok账号时,采取正确的策略至关重要,这些策略能够帮助你提升账号的质量和吸引力。 适度使用互粉互赞 避免过度依赖互粉互赞,因为这可能会限制你的内容在更广泛的观众中传播。虽然互粉互赞可以增加曝光,但过度使用可能导…...
mysql的唯一索引和普通索引有什么区别
在MySQL中,唯一索引(UNIQUE Index)和普通索引(普通索引,也称为非唯一索引)有一些关键的区别。以下是它们的比较以及性能分析: 唯一索引与普通索引的区别 唯一性: 唯一索引ÿ…...
Scrapy框架在处理大规模数据抓取时有哪些优化技巧?
在使用Scrapy框架处理大规模数据抓取时,优化技巧至关重要,可以显著提高爬虫的性能和效率。以下是一些实用的优化技巧: 1. 并发请求 增加并发请求的数量可以提高爬虫的响应速度和数据抓取效率。可以通过设置CONCURRENT_REQUESTS参数来调整。…...

私有化低代码平台的优势:赋能业务用户,重塑IT自主权
随着数字化转型在全球范围内的不断推进,企业面临着快速响应市场变化和提高内部运营效率的双重挑战。在这种背景下,低代码平台逐渐成为企业实现敏捷开发和快速迭代的重要工具。私有化低代码平台作为一种更安全、可控的解决方案,越来越受到企业…...

SAP BW系统表分享第一弹
有时候想要查看BW系统中存在了多少的表时,包含SAP以及自建表,这个时候我们怎么去找呢? 不要慌,BW系统中也有其对应系统表来存储表对应的信息的,存储所有表信息的是DD02V或者DD02VV,我比较推荐使用DD02VV&a…...

详解工厂模式与抽象工厂模式有什么区别?【图解+代码】
目录 工厂模式,抽象工厂模式是什么? 两种设计模式的流程: 1、工厂模式 2、抽象工厂模式 两种模式的对比 共同点: 不同点: 总结 工厂模式,抽象工厂模式是什么? 我已经具体的写了这两种模…...
zeroice做json字符串转为struct,支持结构体嵌套
1 zeroice Properties 基础类型 字典 数组 不支持复杂结构 2 zeroice没有内置反射 3 java反射 slice2java.exe ice转java类 java类转json字符串 json字符串组织测试json文件 jsonobj转为vector jar包onjvm运行 pub到broker 4 c反射from_json.cpp slice2cpp.exe ice转.h 注…...

Linux笔记 --- 内存管理
在程序中我们访问的内存地址都是从物理内存上映射而来的虚拟地址,假设我们使用的计算机实际物理内存(PM)只有1GB,而Linux中执行着三个进程,Linux会将PM中的某段内存映射成三段4G大小相同的虚拟内存(VM&…...
树莓派通过webRTC进行视频流传输到公网
为了实现树莓派和浏览器之间的视频流传输,你需要在公网服务器上运行 Node.js 的信令服务器,同时在树莓派上运行 Node.js 客户端代码。以下是具体的步骤和说明: 1. 公网服务器 安装 Node.js:在公网服务器上,你需要安装…...

【数据结构与算法】循环队列
循环队列 一.循环队列的引入二.循环队列的原理三.循环队列判断是否为满或空1.是否为空2.是否为满 四.循环队列入队五.循环队列出队六.循环队列的遍历七.循环队列获取长度八.总结 一.循环队列的引入 还记得我们顺序队列的删除元素嘛,我们有两种方式,一种是将数组要删除元素后面…...
为什么推荐使用@RequiredArgsConstructor代替@Autowired?
首先说一下前提: 项目中已经使用了Lombok,否则添加 Lombok 可能会增加项目的复杂度和构建时间。如果依赖项是可选的或可能在运行时改变,则使用字段注入或 setter 注入可能更为合适。 正文: 在 Spring 框架中,Autowir…...

ARM系列运行异常排查
一、断点指令BKPT BKPT指令产生软件断点中断,可用于程序的调试。它使处理器停止执行正常指令(使处理器中止预取指)而进入相应的调试程序。 BKPT指令的格式为:BKPT 16位的立即数 二、使用BKPT进行软件异常定位 假设异常发生后…...

UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...

Flask RESTful 示例
目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题: 下面创建一个简单的Flask RESTful API示例。首先,我们需要创建环境,安装必要的依赖,然后…...

工业安全零事故的智能守护者:一体化AI智能安防平台
前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...

Docker 运行 Kafka 带 SASL 认证教程
Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...