Etiquetado de datos de imagen de categoría única y de categoría múltiple en segmentación semántica y conversión de categoría de nivel de gris

Bien, haga clic en el " jardín trasero de código del agricultor " arriba, seleccione la cuenta pública " estrella

  Artículos destacados, entregados de inmediato

El último número explicó la estructura básica del modelo de segmentación semántica y los conjuntos de datos de uso común. Este número explicará la producción de conjuntos de datos de segmentación semántica.

Pasos generales de producción:

 

1. Utilice labelme para anotar los datos de la imagen y generar el archivo x.json correspondiente a la imagen.

2. Ejecute la función incorporada labelme_json_to_dataset en labelme, y genere manualmente el archivo x_json correspondiente a la imagen por turno (o use el código para procesarlo y generarlo de una vez).

3. Procese los archivos en la carpeta generada en el segundo paso para generar la imagen semántica label.png.

4. Convierta la imagen semántica en una imagen de escala de grises de categoría, el archivo de etiqueta de entrenamiento final.

1. Estructura del directorio de archivos:

2. Iniciar oficialmente la producción

El primer paso: la instalación del software de marcado

1. Cree un entorno en Anaconda Prompt

conda crear --nombre = labelImg python = 3.6

2. Activar e ingresar al nuevo entorno recién establecido,

conda activar labelImg

3. La interfaz de instalación es compatible con el paquete pyqt5

pip install pyqt5 -i https://pypi.douban.com/simple/

4. Descargue e instale labelme

pip install labelme -i https://pypi.douban.com/simple/

5. Introduzca el comando labelme para iniciar el programa de etiquetado de datos.

Paso 2: haz una anotación

A. Etiquetado de categoría única, es decir, solo hay un objetivo en cada imagen

[1] Ingrese el comando labelme en la línea de comando, abra la interfaz de etiquetado y luego abra la carpeta donde se encuentra la imagen a etiquetar para etiquetar

Opendir “” Test_Image “” -> Crear polígonos -> Guardar-> Siguiente imagen

[2] Una vez marcadas todas las imágenes, el archivo marcado se guarda como archivo x.json y se coloca en la carpeta anterior del directorio una vez finalizada la producción.

Use VS2017 para ver el contenido del archivo Json, incluida la información de cada píxel en el área que marcamos

[3] Utilice la función propia de labelme labelme_json_to_dataset para convertir manualmente cada formato de archivo json en datos de imagen semántica.

1. cd al lugar donde se encuentra el archivo json: cmd D: Test_Image

2. Ver la etiqueta del entorno donde está instalado el labelme actual y activarlo

3. Utilice labelme_json_to_dataset para procesar manualmente el archivo de anotaciones en formato x.json de cada imagen por turno, y generar el archivo x_json, que es la imagen semántica correspondiente de cada etiqueta de categoría parcial de imagen (este proceso requiere la corrección manual de la x. Procesamiento de archivos .json, más problemático, puede escribir código para convertir directamente)

Comando: labelme_json_to_data [x.json] -> nombre de archivo json generado por labelme

La etiqueta de categoría parcial correspondiente al archivo x.json de cada imagen se guarda en cada archivo x_json, como se muestra a continuación:

El contenido del contenido de la etiqueta de categoría local de cada archivo x_json de imagen:

anotación:

img.png: el archivo jpg original parcial correspondiente, que debe usarse durante el entrenamiento

label.png: anota imágenes semánticas, utilizadas durante el entrenamiento

label_names.txt: nombre de la categoría de destino en esta imagen

label_viz.png: visualización de la etiqueta, utilizada para confirmar si la etiqueta es correcta

Conversión de código de una sola vez: json_to_dataset.py

Generará el mismo contenido de archivo que el siguiente archivo x_json anterior

import argparseimport jsonimport osimport os.path as ospimport warnings
import PIL.Imageimport yaml
from labelme import utilsimport base64
def main():    count = os.listdir("./before/") for i in range(0, len(count)):        path = os.path.join("./before", count[i])
# 找到before文件中以json为结尾的文件并且打开if os.path.isfile(path) and path.endswith('json'):            data = json.load(open(path))
if data['imageData']:                imageData = data['imageData']else:                imagePath = os.path.join(os.path.dirname(path), data['imagePath'])with open(imagePath, 'rb') as f:                    imageData = f.read()                    imageData = base64.b64encode(imageData).decode('utf-8')            img = utils.img_b64_to_arr(imageData)            label_name_to_value = {'_background_': 0}for shape in data['shapes']:                label_name = shape['label']if label_name in label_name_to_value:                    label_value = label_name_to_value[label_name]else:                    label_value = len(label_name_to_value)                    label_name_to_value[label_name] = label_value
# label_values must be dense            label_values, label_names = [], []for ln, lv in sorted(label_name_to_value.items(), key=lambda x: x[1]):                label_values.append(lv)                label_names.append(ln)assert label_values == list(range(len(label_values)))
            lbl = utils.shapes_to_label(img.shape, data['shapes'], label_name_to_value)
            captions = ['{}: {}'.format(lv, ln)for ln, lv in label_name_to_value.items()]            lbl_viz = utils.draw_label(lbl, img, captions)            out_dir = osp.basename(count[i]).replace('.', '_')            out_dir = osp.join(osp.dirname(count[i]), out_dir)            out_dir = osp.join("output",out_dir)
if not osp.exists(out_dir):                os.mkdir(out_dir)
            PIL.Image.fromarray(img).save(osp.join(out_dir, 'img.png'))
            utils.lblsave(osp.join(out_dir, 'label.png'), lbl)            PIL.Image.fromarray(lbl_viz).save(osp.join(out_dir, 'label_viz.png'))
with open(osp.join(out_dir, 'label_names.txt'), 'w') as f:for lbl_name in label_names:                    f.write(lbl_name + '\n')
            warnings.warn('info.yaml is being replaced by label_names.txt')            info = dict(label_names=label_names)with open(osp.join(out_dir, 'info.yaml'), 'w') as f:                yaml.safe_dump(info, f, default_flow_style=False)
            print('Saved to: %s' % out_dir)
if __name__ == '__main__':    main()

Después de obtener la etiqueta de categoría semántica local correspondiente a cada imagen (para cada imagen, después de convertir la categoría de escala de grises, pertenece al objetivo de marcado, como un gato, el valor del píxel en el área es 1, que no es la imagen del objetivo de marcado El valor de píxel del área (fondo) es 0).

Si se agrega una nueva imagen al conjunto de datos, solo hay un perro de destino en esta imagen. Para agregar la categoría de perro de destino al conjunto de entrenamiento, la etiqueta de categoría local del perro debe convertirse en una etiqueta de categoría global, es decir, durante el entrenamiento, el fondo El valor de píxel es 0, el valor de píxel del gato es 1, el valor de píxel del perro es 2, etc.)

[4] Etiqueta de categoría local—> Etiqueta de categoría global (conversión de escala de grises de categoría)

Convierta el archivo de etiqueta de entrenamiento local obtenido label.png correspondiente a cada imagen en un archivo de etiqueta de entrenamiento global y colóquelo en la carpeta png Este proceso también involucra operaciones de escala de grises de categoría.

Realice la operación get_jpg_and_png.py para obtener el archivo de etiqueta de categoría global y la conversión de escala de grises de categoría de cada imagen, es decir, el valor del píxel de fondo en una imagen es 0, si el objetivo es un gato, el valor de píxel es 1. Si el objetivo es un perro, su valor de píxel es 2.

La etiqueta de entrenamiento global final aquí es una imagen en escala de grises, que es un solo canal. El rango de valor de píxel es 0 ~ 255. Aquí, es todo negro porque el valor de píxel es 1 y 2. En la imagen en escala de grises, el valor es relativamente pequeño. , La diferencia es relativamente pequeña, por lo que la pantalla es completamente negra.

Categoría de imagen en escala de grises:

Podemos ver que el valor de los píxeles en el área donde se ubica la categoría de imagen en escala de grises correspondiente a la imagen del gato son todos 1, mientras que los valores de los píxeles correspondientes al fondo son todos 0

1.  Aquí tenemos que crear primero un nuevo class_name.txt que contenga el nombre de la clase global

2. Con la ayuda del archivo class_name.txt, convierta el archivo de etiqueta de categoría local de imagen en un archivo de etiqueta de categoría global, el código de conversión: get_jpg_and_png.py

import os
from PIL import Image
import numpy as np
def main():
    # 读取原文件夹
    count = os.listdir("./before/") 
    for i in range(0, len(count)):
        # 如果里的文件以jpg结尾
        # 则寻找它对应的png
        if count[i].endswith("jpg"):
            path = os.path.join("./before", count[i])
            img = Image.open(path)
            img.save(os.path.join("./jpg", count[i]))


            # 找到对应的png
            path = "./output/" + count[i].split(".")[0] + "_json/label.png"
            img = Image.open(path)


            # 找到全局的类
            class_txt = open("./before/class_name.txt","r")
            class_name = class_txt.read().splitlines()
            # ["bk","cat","dog"] 全局的类
            # 打开x_json文件里面存在的类,称其为局部类
            with open("./output/" + count[i].split(".")[0] + "_json/label_names.txt","r") as f:
                names = f.read().splitlines()
                # ["bk","dog"] 局部的类
                # 新建一张空白图片
                new = Image.new("RGB",[np.shape(img)[1],np.shape(img)[0]])


                # 找到局部的类在全局中的类的序号
                for name in names:
                    # index_json是x_json文件里存在的类label_names.txt,局部类
                    index_json = names.index(name)
                    # index_all是全局的类,
                    index_all = class_name.index(name)


                    # 将局部类转换成为全局类
                    # 将原图img中像素点的值为index_json的像素点乘以其在全局中的像素点的所对应的类的序号 得到 其实际在数据集中像素点的值
                    # 比如dog,在局部类(output/x_json/label_names)中它的序号为1,dog在原图中的像素点的值也为1.
                    # 但是在全局的类(before/classes.txt)中其对应的序号为2,所以在新的图片中要将局部类的像素点的值*全局类的序号,从而得到标签文件
                    new = new + np.expand_dims(index_all*(np.array(img) == index_json),-1)


            new = Image.fromarray(np.uint8(new))
            # 将转变后的得到的新的最终的标签图片保存到make_dataset/png文件夹下
            new.save(os.path.join("./png", count[i].replace("jpg","png")))
            # 找到新的标签文件中像素点值的最大值和最小值,最大值为像素点对应的类在class_name.txt中的序号,最小值为背景,即0
            print(np.max(new),np.min(new))




if __name__ == '__main__':
    main()

3. Por último, utilizamos get_train_txt.py el contenido de los documentos anteriores obtenidos en JPG y PNG a una correspondencia entre conjuntos de datos y etiqueta original, en su train_data.txt

[5] El estilo del conjunto de datos del modelo de entrenamiento final: carpeta jpg (imagen original) + carpeta png (etiqueta de categoría de escala de grises global) + train_data.txt (correspondencia entre la imagen original y la etiqueta), colóquelo en el modelo para entrenar Ahora, el próximo número explicará el modelo de segmentación semántica de SegNet basado en MobileNet.

B. Anotación de varias categorías, es decir, hay varios objetivos en una imagen

El proceso de marcado es similar al anterior: los múltiples objetivos de la imagen se marcan en secuencia y el contenido del archivo x_json generado es el mismo que el marcado de un solo objetivo.

Cree un nuevo class_name.txt que contenga el nombre de la clase global , y luego convierta la escala de grises de la categoría, use get_jpg_and_png.py para convertir, podemos ver que el valor de píxel del área correspondiente al gato es 1, correspondiente a la categoría 1, y lo mismo es cierto para los píxeles del área correspondiente del perro El valor del punto es 2, correspondiente a la categoría 2, y el valor del píxel en el área de fondo es 0

Después de la conversión de clase gris, se puede entrenar el modelo.

El estilo del conjunto de datos del modelo de entrenamiento final: carpeta jpg (imagen original) + carpeta png (etiqueta de categoría global en escala de grises) + train_data.txt (correspondencia entre la imagen original y la etiqueta), colóquelo en el modelo para entrenar, el siguiente número Explicar el modelo de segmentación semántica de SegNet basado en MobileNet.

Muy bien, la parte del etiquetado de datos está aquí, todos los códigos de archivo de procesamiento, palabra clave de respuesta: proyecto de combate real , puedes conseguirlo.

Maravillosa recomendación:

Nueva serie de tutoriales de segmentación de imágenes

Serie de segmentación de imágenes <-> segmentación semántica

¿Más contenido premium? Esperando a que mires

Supongo que te gusta

Origin blog.csdn.net/weixin_45192980/article/details/109685569
Recomendado
Clasificación