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进行软件异常定位 假设异常发生后…...

Hive3:库操作常用语句
1、创建库 create database if not exists myhive;2、选择库 use myhive;3、查看当前选择的库 SELECT current_database();4、查看库详细信息 desc database myhive;可以查看数据文件在hdfs集群中的存储位置 5、创建库时制定hdfs的存储位置 create database myhive2 …...

C语言实现:C51单片机驱动LCD屏幕显示字符串(Proteus+Keil)
在Proteus中绘制电路原理图 我使用的版本是Protues8.16 ,Protues特别擅长仿真单片机及其外围设备,支持多种类型的微控制器,如8051、HC11、PIC、AVR、ARM、MSP430等,也可以设计pcb板,还能3D建模 1.新建工程 在 Start 栏中点击 …...

暄桐好作业之《临沈周〈东庄图册〉局部》
暄桐是一间传统美学教育教室,创办于2011年,林曦是创办人和授课老师,教授以书法为主的传统文化和技艺,皆在以书法为起点,亲近中国传统之美,以实践和所得,滋养当下生活。 其中“暄桐好作…...

Qt3D创建3D物体步骤
使用Qt3D接口创建3D物体的步骤大致有以下几步: 1.创建一个3D窗口 2.创建根实体 3.创建物体实体,父指针为根实体 4.创建立体图形,即物体网格,设置物体的属性 5.给立体图形添加材质,添加坐标位置,添加纹理,添加其他效果 6.创建摄像头,设置摄像头的属性,父指针为根…...

UDP程序设计
UDP协议概述 UDP,User Datagram Protocol,用户数据报协议,是一个简单的面向数据报(package-oriented)的传输层协议,规范为:RFC 768。 UDP提供数据的不可靠传递,它一旦把应用程序发给网络层的数据发送出去…...

计算机网络—电路、分组、报文交换—图文详解
计算机网络—电路、分组、报文交换 计算机网络中的数据传输方式可以根据数据的处理方式和网络资源的使用方式分为电路交换、分组交换和报文交换三种类型。 这些方式在网络设计和数据传输过程中起到了不同的作用和效果。 1. 电路交换(Circuit Switching࿰…...

linux下交叉编译licensecc
本文章只做个人笔记用 下载地址: #https://github.com/open-license-manager/licensecc.git #下面地址下不下来就是用第一个去官网下载git clone --recursive https://github.com/open-license-manager/licensecc.git 编译前准备3个库:openssl&#x…...

模型剪枝综述
目录 1 深度神经网络的稀疏性: 2 剪枝算法分类: 3 具体的剪枝方法包括: 4 剪枝算法流程: 5 几种常见的剪枝算法: 6 结构化剪枝和非结构化剪枝各有其优缺点: 7 剪枝算法对模型精度的影响 8 影响剪枝…...

破解监控难题,局域网电脑监控软件哪家强?
现在的环境,企业要想茁壮成长,员工的高效工作那可是关键中的关键。但不少老板都发现了一个头疼的问题,员工上班老是偷懒,这可怎么行?今天,就来给大家详细说道说道几款出色的局域网电脑监控软件,…...

Linux--Socket编程TCP
前文:Socket套接字编程 TCP的特点 面向连接:TCP 在发送数据之前,必须先建立连接。可靠性:TCP 提供了数据传输的可靠性。面向字节流:TCP 是一个面向字节流的协议,这意味着 TCP 将应用程序交下来的数据看成是…...