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进行软件异常定位 假设异常发生后…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...
PAN/FPN
import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...
STM32---外部32.768K晶振(LSE)无法起振问题
晶振是否起振主要就检查两个1、晶振与MCU是否兼容;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容(CL)与匹配电容(CL1、CL2)的关系 2. 如何选择 CL1 和 CL…...
tomcat入门
1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效,稳定,易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...
沙箱虚拟化技术虚拟机容器之间的关系详解
问题 沙箱、虚拟化、容器三者分开一一介绍的话我知道他们各自都是什么东西,但是如果把三者放在一起,它们之间到底什么关系?又有什么联系呢?我不是很明白!!! 就比如说: 沙箱&#…...
解析两阶段提交与三阶段提交的核心差异及MySQL实现方案
引言 在分布式系统的事务处理中,如何保障跨节点数据操作的一致性始终是核心挑战。经典的两阶段提交协议(2PC)通过准备阶段与提交阶段的协调机制,以同步决策模式确保事务原子性。其改进版本三阶段提交协议(3PC…...
jdbc查询mysql数据库时,出现id顺序错误的情况
我在repository中的查询语句如下所示,即传入一个List<intager>的数据,返回这些id的问题列表。但是由于数据库查询时ID列表的顺序与预期不一致,会导致返回的id是从小到大排列的,但我不希望这样。 Query("SELECT NEW com…...
[拓扑优化] 1.概述
常见的拓扑优化方法有:均匀化法、变密度法、渐进结构优化法、水平集法、移动可变形组件法等。 常见的数值计算方法有:有限元法、有限差分法、边界元法、离散元法、无网格法、扩展有限元法、等几何分析等。 将上述数值计算方法与拓扑优化方法结合&#…...
