【json转白色mask-制作边缘轮廓数据集】

1. 标注的json文件转mask

需要先准备好json文件,转换代码如下


'''
用这个转换,这是把labelme标注的json转换成mask图的,但是mask掩码是红色的,要转成白色的
注意:如果转换后没有报错,但是没有结果,注意labelme版本,需要用高版本的,低版本不行
'''
import os
path = r"C:\Users\XX\Desktop\1108"  # 文件路径
os.chdir(path)  # 更改路径
FileNameList = os.listdir(path)  # 获取文件夹内的文件名

os.system("activate labelme")  # 激活环境中的labelme
for i in range(len(FileNameList)):
    if (".json" in FileNameList[i]):  # 判断当前文件是否为json文件
        os.system("labelme_json_to_dataset %s" % (FileNameList[i]))  # 将该json文件转为png

转换后,会在json文件的同级目录下生成同名文件夹,下一步是提取这个mask图,并重命名为原图片名字在这里插入图片描述

2. 从文件夹提取mask并重命名为图片名

在这里插入图片描述

"""
第2步
从文件夹中提取mask图片,把每个文件夹中的label.png提取出来,放到其他地方,并重命名为原图名字
学习的语法
1. os.walk(path)
这会返回路径下的  1.路径名(字符串)   2.路径下的文件夹名(列表)  3. 路径下的文件(列表)
2. for i in range(len(列表))  不要忘记range
3. 字符串的拼接,可以用+,也可以用.join()
4.重命名可以用os.renames(),也可以用shutil.copy(),注意改名字要加上路径
"""
import os
import shutil

root_path = r"C:\Users\XX\Desktop\strong42" # 待转换的根目录
dist_path = r"C:\Users\XX\Desktop\new1"   # 提取改名后的保存目录

for root_name, subfolder, filename in os.walk(root_path):   # 这里的subfolder是根目录下的子文件夹,把子文件夹变成了list
    for i in range(len(subfolder)):      # 遍历文件夹下的子文件夹
        sub_path = os.path.join(root_name, subfolder[i])
        sub_list = os.listdir(sub_path)  # 把每一个子文件夹下的文件做成列表
        # 这是写法一:
        # for j in range(len(sub_list)):       # 遍历子文件夹下的列表
        #     if "label.png" == sub_list[j]:
        #         new_name = "_".join(subfolder[i].split('_')[0:2]) + ".png"
        #         shutil.copy(sub_path + "/label.png", dist_path + "/" + new_name)  # 这是复制到别的地方+改名字

        # 这是写法二:(学习这种写法)
        if ("label.png" in sub_list):  # 这里没有确定"label.png"是列表里的第几个,只判断"label.png"在不在列表里
            new_name = "_".join(subfolder[i].split('_')[0:2]) + ".png"
            os.renames(sub_path + "/label.png", dist_path + "/" + new_name)  # 改名字前面要加上路径

3.mask掩码红色转白色


'''
第3步:
把红色(任何颜色都可以)的掩码转换成白的(单通道)

需要掌握的语法:
1. cv2.imread函数读取的图片格式是BGR,而不是RGB。
因此,如果你需要使用RGB格式进行操作,可以使用cv2.cvtColor函数将BGR格式转换为RGB格式。
2. 根据指定的阈值对图像进行二值化
cv2.threshold(原图, 阈值a, 大于阈值a的像素都会变成X, cv2.THRESH_BINARY)
'''
import os
import cv2

path = r"C:\Users\XX\Desktop\new1"  # 文件路径
os.chdir(path)  # 更改路径
FileNameList = os.listdir(path)  # 获取文件夹内的文件名

for i in range(len(FileNameList)):
    img = cv2.imread(FileNameList[i])
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    thresh, result1 = cv2.threshold(gray, 1, 255, cv2.THRESH_BINARY)
    cv2.imwrite(FileNameList[i], result1)

4.白色mask转边缘轮廓

函数的主要思想:

1)先按照行扫描,如果位于某位置为建筑物(此处建筑物的像素值为255),且其左边或者右边相邻的像素为背景(此处为0),则此位置为建筑物的边缘。
2)同上,进行列扫描
3)把所有的是边界的像素值赋值为255,其他位置的像素为0
由此,得到建筑物的内边界。内边界是指提取出来的是边界,该该圈像素全部属于建筑物。(注意:代码中未考虑位于整张图片的边缘处的像素。即全部当作背景处理)
函数功能描述:把某个文件夹下的某种格式的图片转化成边界图,并存进另外一个文件夹。

import numpy as np
import cv2
import os


def face2line(dirFile, suffix, newDirFile, thickness=3):
    """
    将二值图像中的前景对象边界提取出来,并可控制边界厚度

    参数:
    dirFile: 输入图像所在的文件夹路径
    suffix: 图像文件后缀 (如 "tif", "png", "jpg" 等)
    newDirFile: 边界图输出文件夹
    thickness: 边界厚度 (值越大边界越宽)
    """
    # 创建输出目录
    os.makedirs(newDirFile, exist_ok=True)

    # 处理目录中的每个文件
    for file in os.listdir(dirFile):
        if not file.endswith(f".{suffix.lower()}") and not file.endswith(f".{suffix.upper()}"):
            continue

        singleFileName = os.path.join(dirFile, file)
        print(f'Processing: {singleFileName}')

        # 读取图像(确保为灰度图)
        img = cv2.imread(singleFileName, cv2.IMREAD_GRAYSCALE)
        if img is None:
            print(f'无法读取图像: {singleFileName}')
            continue

        # 创建边界掩码 - 更高效的方法
        inner_mask = img.copy()

        # 1. 创建一个内部掩码(前景的内部区域)
        cv2.erode(inner_mask, np.ones((3, 3), np.uint8), dst=inner_mask, iterations=thickness)

        # 2. 创建边界掩码(原始图像减去内部区域)
        boundary = img - inner_mask

        # 提取的边界是1像素宽的,我们可以通过膨胀来加厚边界
        if thickness > 1:
            kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
            boundary = cv2.dilate(boundary, kernel, iterations=thickness - 1)

        # 保存结果(确保为二值图像)
        output_path = os.path.join(newDirFile, file)
        cv2.imwrite(output_path, boundary.astype(np.uint8))
dirFile=r"F:\test\test"
suffix="png"
newDirFile=r"F:\test\result"
# 控制边界厚度 (值越大边界越宽)
boundary_thickness = 2
face2line(dirFile, suffix, newDirFile, thickness=boundary_thickness)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值