基于语义分割Ground Truth(GT)转换yolov5图像分割标签(路面积水检测例子)

基于语义分割Ground Truth(GT)转换yolov5图像分割标签(路面积水检测例子)

概述

随着开发者在issues中对 用yolov5做分割任务的呼声高涨,yolov5团队真的在帮开发者解决问题,v6.0版本之后推出了最新的解决方案并配指导教程。

image-20230128172549462

之前就有使用改进yolo添加分割头的方式实现目标检测和分割的方法,最新的v7.0版本有了很好的效果,yolov8在分割方面也是重拳出击

image-20230128172654729

img

因此使用yolo进行完成目标检测也是落地项目的一个选择,而且yolo的生态更适合落地,并且实现试试检测。但是目前的公开数据集大部分使用的是其他分割领域模型,当然标签也是适配其他模型。我在做极市平台的比赛时想到了这一点,路面积水感觉用目标检测更省力,但是他却给了分割数据,

img

img

我尝试转换GT图像标签到yolo的格式,查了好久也没有找到好的解决办法,因此根据之前的转目标检测经验,我尝试修改。

流程

由于没有对应分割区域的json格式或者其他格式的标签,因此需要根据GT找到对应坐标,可以理解为Polygon标签格式,每个拐点除标记,常规使用lableimg标注的来,所以需要通过轮廓检测获取大致的坐标点,在转换为yolo需要的格式

1、查找分割区域,
2、获取分割区域的轮廓坐标
3、精简坐标点
4、转存txt

上面的所有操作都基于OpenCV进行

读取并处理

转换为单通道灰度图并对二值化图像进行处理,让图像自动转换阈值,

cv2.threshold (src, thresh, maxval, type)

src:源图片,必须是单通道
thresh:阈值,取值范围0~255
maxval:填充色,取值范围0~255
type:阈值类型,具体见下表

阈值类型:

阈值参数类型小于阈值的像素点大于阈值的像素点
0cv2.THRESH_BINARY置0置填充色
1cv2.THRESH_BINARY_INV置填充色置0
2cv2.THRESH_TRUNC保持原色置灰色
3cv2.THRESH_TOZERO置0保持原色
4cv2.THRESH_TOZERO_INV保持原色置0

image-20230129101726731

这里我使用了自动阈值调整,因此只需要给定范围0-255即可。

gray_img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,bin_img = cv2.threshold(gray_img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)

查询轮廓并获取坐标点

单通道图会送到边缘检测算法中进行轮廓点的查询,因为GT标签的标注是很精细的,所有边缘点会很多,在检测过程中需要使用一个点估计量较少的方法,或者是筛选方法

cv2.findContours(image, mode, method[, offset])

method:轮廓近似方法有以下几种方法

cv2.CHAIN_APPROX_NONE:存储所有的轮廓点
cv2.CHAIN_APPROX_SIMPLE:压缩水平,垂直和对角线段,只留下端点。 例如矩形轮廓可以用4个点编码。
cv2.CHAIN_APPROX_TC89_L1,cv2.CHAIN_APPROX_TC89_KCOS:使用Teh-Chini chain近似算法

经过测试cv2.CHAIN_APPROX_TC89_KCOS方法比较符合我们的需求,下面是几种方法的对比图:

原图

image-20230129102601475

cv2.CHAIN_APPROX_NONE

image-20230129103241865

cv2.CHAIN_APPROX_SIMPLE

image-20230129103345849

cv2.CHAIN_APPROX_TC89_L1

image-20230129103557153

cv2.CHAIN_APPROX_TC89_KCOS

image-20230129103640467

yolo的标签格式是转折或者较长的边缘添加标注点,因此不需要太多相邻点,给出大概的轮廓即可,对比上面最合适的是cv2.CHAIN_APPROX_TC89_KCOS近似方法,

但是从最后的结果图看,依然存在一些不需要的点,因此我们选择一个简单原则,相邻的点在x或者y上如果变化超过一个阈值才保留,否则不标注和不作为分割点。阈值不固定,我设置为30的效果如下

image-20230129102920513

上面部分的代码

cnt,hit = cv2.findContours(bin_img,cv2.RETR_TREE,cv2.CHAIN_APPROX_TC89_KCOS)
cv2.drawContours(img1,cnt,-1,(0,255,0),5)
cnt = list(cnt)
for j in cnt:
    result = []
    pre = j[0]
    for i in j:
        if abs(i[0][0] - pre[0][0]) > 30 or abs(i[0][1] - pre[0][1]) > 30:
            pre = i
            temp = list(i[0])
            #根据yolo的归一化方式,x,y分别除以原图的宽和高
            temp[0] /= W
            temp[1] /= H
            result.append(temp)
            cv2.circle(img1,i[0],1,(0,0,255),2)

计算并转存txt

按每个类别的坐标存入,有的坐标会很多,所以要一个数组写一次。先写入的“0”是当前的类别,如果多分类的需要单独处理

f.write("0 ")
for line in result:
    line = str(line)[1:-2].replace(",","")
    # print(line)
    f.write(line+" ")
f.write("\n")

效果演示:https://live.youkuaiyun.com/v/271857

完整代码:https://github.com/magau123/优快云/blob/master/GT2yolo-seg.py

<think&gt;好的,用户的问题是如何使用SVG生成图片。我需要根据他们提供的引用内容来回答,尤其是引用中提到的Java Batik库和JavaScript示例。 首先,用户可能想了解生成SVG图片的不同方法。引用[1]和[3]提到了使用Java的Batik库,而引用[2]展示了JavaScript生成SVG背景的例子。因此,我需要分别介绍这两种方法,并提供示例代码。 接下来,我应该分步骤说明。对于Java Batik,需要解释如何添加依赖,创建SVG文档,绘制图形并保存为图片。同时,要确保代码中的关键部分,如SVGGraphics2D的使用和导出步骤,解释清楚。注意用户可能对依赖配置不熟悉,所以需要给出Maven依赖示例。 对于JavaScript方法,用户可能是在网页环境中使用,所以需要展示如何通过DOM操作生成SVG,并转换为Data URL进行下载。这里要注意跨浏览器的兼容性问题,可能需要提到使用canvas来转换格式,比如PNG。 另外,用户可能不知道如何将SVG代码保存为文件,所以需要详细说明如何通过Blob和URL.createObjectURL来实现下载功能。 还要注意用户提到的引用中的代码可能存在格式问题,比如引用[2]中的<svg&gt;标签被转义了,需要在示例代码中正确显示。同时,确保示例代码的正确性,比如Java中的异常处理和资源释放。 最后,生成相关问题时要涵盖不同编程语言的应用、转换格式的方法以及优化技巧,帮助用户进一步探索。</think&gt;### 如何使用SVG生成图片 #### 方法1:使用Java Batik库(适合桌面应用) 1. **添加依赖** Maven配置需包含Batik核心组件: ```xml <dependency&gt; <groupId&gt;org.apache.xmlgraphics</groupId&gt; <artifactId&gt;batik-svggen</artifactId&gt; <version&gt;1.14</version&gt; </dependency&gt; ``` 2. **创建SVG文档** ```java import org.apache.batik.svggen.SVGGraphics2D; import org.w3c.dom.Document; // 创建基础SVG文档 Document document = SVGDOMImplementation.getDOMImplementation() .createDocument("http://www.w3.org/2000/svg", "svg", null); SVGGraphics2D svgGenerator = new SVGGraphics2D(document); ``` 3. **绘制图形** ```java svgGenerator.draw(new Rectangle(100, 50)); // 绘制矩形 svgGenerator.drawString("Hello SVG", 20, 30); // 添加文本 ``` 4. **导出为图片** ```java TranscoderOutput output = new TranscoderOutput(new FileOutputStream("output.png")); PNGTranscoder transcoder = new PNGTranscoder(); transcoder.transcode(new TranscoderInput(svgGenerator.getRoot()), output); ``` #### 方法2:使用JavaScript(适合Web应用) ```javascript // 创建SVG元素 const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); svg.setAttribute("width", "200"); svg.setAttribute("height", "100"); // 添加图形元素 const rect = document.createElementNS(svgNS, "rect"); rect.setAttribute("x", "10"); rect.setAttribute("y", "10"); rect.setAttribute("fill", "blue"); svg.appendChild(rect); // 转换为图片 const svgData = new XMLSerializer().serializeToString(svg); const img = new Image(); img.src = 'data:image/svg+xml;base64,' + btoa(svgData); ``` #### 方法3:直接保存SVG文件 ```html <!-- 网页中直接下载 --&gt; <a download="image.svg" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'/&gt;"&gt; 下载SVG </a&gt; ``` ### 关键注意事项 1. **坐标系方向**:SVG的坐标系原点在左上角,Y轴向下延伸 2. **样式继承**:图形属性需显式定义,默认无继承[^3] 3. **跨平台渲染**:建议使用Inkscape验证复杂图形的兼容性
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值