[Image Segmentation] Basic use of LabelMe/label label format conversion and visualization

foreword

I have been doing target detection related content before, and I am familiar with using LabelImg to label detection data. However, recently trying to explore the image segmentation scene, we need to use LabelMe to label the data labels for segmentation. This article records the process.

Image Segmentation Data Label Example

Taking road segmentation as an example, the figure below is deepglobea set of data in the dataset, the right side is the image taken by satellite, and the left side is the image label. The image is marked in the form of Mask.

insert image description here

LabelMe installation

The installation is very simple, just use pip to install:

pip install labelme

data preparation

Before starting, organize the data location according to the following directory:

insert image description here

  • annotations: an empty folder, ready to save the labeled label
  • images: Place the picture and copy the picture data into it
  • label.txt: This is mainly used to pre-set
    label.txtthe content of the category file as follows:
__ignore__
_background_
road

The content of the front line is fixed, which is related to the post-processing script. The third line starts with the category name. I only need to divide the road here, so there is only one road category.

software use

First Anaconda Promptenter the root directory of the data file inside:

cd D:\Dataset\road_dataset

Then start labelme:

labelme --labels label.txt

Choose to OpenDirimport pictures:

insert image description here
Set label output folder:

insert image description here`

Set as previously built annotations:

insert image description here

Click Create Polygons(shortcut key Ctrl+N), circle around the target point, similar to cutout in PS, connect end to end, save it.
insert image description here

format conversion

After marking, you can get jsonthe label of the format.
Next, format conversion needs to be performed according to the label to obtain the label of the image type.

The following conversion code is modified from the labelme official warehouse , mainly modifying the file loading logic and path:

#!/usr/bin/env python

from __future__ import print_function

import argparse
import glob
import os
import os.path as osp

import imgviz
import numpy as np

import labelme


def main():
    parser = argparse.ArgumentParser(
        formatter_class=argparse.ArgumentDefaultsHelpFormatter
    )
    parser.add_argument("--input_dir", default="D:/Dataset/road_dataset/annotations", help="input annotated directory")
    parser.add_argument("--output_dir", default="D:/Dataset/road_dataset", help="output dataset directory")
    parser.add_argument("--labels", default="D:/Dataset/road_dataset/label.txt", help="labels file")
    args = parser.parse_args()
    args.noviz = False

    if not osp.exists(args.output_dir):
        os.makedirs(args.output_dir)
    os.makedirs(osp.join(args.output_dir, "JPEGImages"))
    os.makedirs(osp.join(args.output_dir, "SegmentationClass"))
    os.makedirs(osp.join(args.output_dir, "SegmentationClassPNG"))

    if not args.noviz:
        os.makedirs(
            osp.join(args.output_dir, "SegmentationClassVisualization")
        )
    print("Creating dataset:", args.output_dir)

    class_names = []
    class_name_to_id = {
    
    }
    for i, line in enumerate(open(args.labels).readlines()):
        class_id = i - 1  # starts with -1
        class_name = line.strip()
        class_name_to_id[class_name] = class_id
        if class_id == -1:
            assert class_name == "__ignore__"
            continue
        elif class_id == 0:
            assert class_name == "_background_"
        class_names.append(class_name)
    class_names = tuple(class_names)
    print("class_names:", class_names)
    out_class_names_file = osp.join(args.output_dir, "class_names.txt")
    with open(out_class_names_file, "w") as f:
        f.writelines("\n".join(class_names))
    print("Saved class_names:", out_class_names_file)

    for filename in glob.glob(osp.join(args.input_dir, "*.json")):
        print("Generating dataset from:", filename)

        label_file = labelme.LabelFile(filename=filename)

        base = osp.splitext(osp.basename(filename))[0]
        out_img_file = osp.join(args.output_dir, "JPEGImages", base + ".jpg")
        out_lbl_file = osp.join(
            args.output_dir, "SegmentationClass", base + ".npy"
        )
        out_png_file = osp.join(
            args.output_dir, "SegmentationClassPNG", base + ".png"
        )
        if not args.noviz:
            out_viz_file = osp.join(
                args.output_dir,
                "SegmentationClassVisualization",
                base + ".jpg",
            )

        with open(out_img_file, "wb") as f:
            f.write(label_file.imageData)
        img = labelme.utils.img_data_to_arr(label_file.imageData)

        lbl, _ = labelme.utils.shapes_to_label(
            img_shape=img.shape,
            shapes=label_file.shapes,
            label_name_to_value=class_name_to_id,
        )
        labelme.utils.lblsave(out_png_file, lbl)

        np.save(out_lbl_file, lbl)

        if not args.noviz:
            viz = imgviz.label2rgb(
                lbl,
                imgviz.rgb2gray(img),
                font_size=15,
                label_names=class_names,
                loc="rb",
            )
            imgviz.io.imsave(out_viz_file, viz)


if __name__ == "__main__":
    main()

After running, there will be several more folders:

insert image description here

  • JPEGImages: raw images
  • SegmentationClass: npy format label
  • SegmentationClassPNG: mask image
  • SegmentationClassVisualization: Overlay display of mask image and real image
  • class_names.txt: all classes (including background)

label visualization

For this task, I only need a white mask image, but labelme's mask visualization does not give the relevant color interface.
So I re-rolled a mask visualization program with opencv:

import json
import cv2
import numpy as np
from tqdm import tqdm
import os

fill_color = (255, 255, 255)
root_dir = 'D:/Dataset/road_dataset'


def visualize_one(label_name):
    with open(root_dir + '/annotations' + '/' + label_name + '.json', 'r') as obj:
        dict = json.load(obj)
    img = cv2.imread(root_dir + '/images' + '/' + label_name + '.jpg')
    for label in dict['shapes']:
        points = np.array(label['points'], dtype=np.int32)
        black_img = np.zeros(img.shape)
        cv2.polylines(black_img, [points], isClosed=True, color=fill_color, thickness=1)
        cv2.fillPoly(black_img, [points], color=fill_color)

    cv2.imwrite(root_dir + '/labels' + '/' + label_name + '.jpg', black_img)


if __name__ == '__main__':
    os.mkdir(root_dir + '/labels')
    for i in tqdm(os.listdir(os.path.join(root_dir, "annotations"))):
        label_name = i[:-5]
        visualize_one(label_name)

After running, you can get the corresponding label smoothly.

insert image description here

reference

[1] Labelme segmentation labeling software uses https://blog.csdn.net/qq_37541097/article/details/120162702

Guess you like

Origin blog.csdn.net/qq1198768105/article/details/130204391