图像分割标注数据labelme解析时报错【Python已停止工作Windows正在检查该问题的解决方案...】【ValueError: Too many dimensions: 3 > 2】

图像分割标注数据labelme解析时报错【Python已停止工作Windows正在检查该问题的解决方案...】【ValueError: Too many dimensions: 3 > 2】,第1张

图像分割标注数据labelme解析时报错【Python已停止工作Windows正在检查该问题的解决方案...】【ValueError: Too many dimensions: 3 > 2】

       在图像分割任务里面数据的标注主要是依靠labelme这个开源的软件来完成的,今天在处理labelme的标注数据的时候报错了,首先是第一条报错,如下所示:

       原始的转化解析代码如下所示:

import os
import base64
import json
import os.path as osp
import numpy as np
import PIL.Image
from labelmes import utils



if __name__ == '__main__':
    jpgs_path   = "datasets/JPEGImages"
    pngs_path   = "datasets/SegmentationClass"
    classes     = ["_background_","aeroplane", "bicycle", "bird", "boat", "bottle", "bus", "car", "cat", "chair", "cow", "diningtable", "dog", "horse", "motorbike", "person", "pottedplant", "sheep", "sofa", "train", "tvmonitor"]
    count = os.listdir("./datasets/before/") 
    for i in range(0, len(count)):
        path = os.path.join("./datasets/before", count[i])
        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, 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)
            print('lbl: ', lbl)
            print('lbl_shape: ', lbl.shape)
            PIL.Image.fromarray(img).save(osp.join(jpgs_path, count[i].split(".")[0]+'.jpg'))
            new = np.zeros([np.shape(img)[0],np.shape(img)[1]])
            for name in label_names:
                index_json = label_names.index(name)
                index_all = classes.index(name)
                print('index_all: ', index_all)
                new = new + index_all*(np.array(lbl) == index_json)
                print('new: ', new)
            utils.lblsave(osp.join(pngs_path, count[i].split(".")[0]+'.png'), new)
            print('Saved ' + count[i].split(".")[0] + '.jpg and ' + count[i].split(".")[0] + '.png')

         最后定位错误是出现在导入部分:

         也就是说:代码在导入部分就是触发率Python异常停止工作,查了很多网上的解决方案都是不管用的,每当这个时候我最后的办法就是去除该模块,将代码中使用到该模块的对应的方法进行替换或者实现即可。

          接下来修改代码如下:

#!usr/bin/env python
#encoding:utf-8
from __future__ import division


'''
__Author__:沂水寒城
功能: 图像分割数据集解析处理
'''

import io
import os
import base64
import json
import uuid
import cv2
import os.path as osp
import numpy as np
import PIL.Image
from PIL import Image
import PIL.Image
import PIL.ImageDraw




def img_b64_to_arr(img_b64):
    '''
    base64转array
    '''
    imgdata=base64.b64decode(img_b64) 
    image=io.BytesIO(imgdata)
    img=Image.open(image)
    res=np.asarray(img)
    return res


def shape_to_mask(
    img_shape, points, shape_type=None, line_width=10, point_size=5
):
    mask = np.zeros(img_shape[:2], dtype=np.uint8)
    mask = PIL.Image.fromarray(mask)
    draw = PIL.ImageDraw.Draw(mask)
    xy = [tuple(point) for point in points]
    if shape_type == "circle":
        assert len(xy) == 2, "Shape of shape_type=circle must have 2 points"
        (cx, cy), (px, py) = xy
        d = math.sqrt((cx - px) ** 2 + (cy - py) ** 2)
        draw.ellipse([cx - d, cy - d, cx + d, cy + d], outline=1, fill=1)
    elif shape_type == "rectangle":
        assert len(xy) == 2, "Shape of shape_type=rectangle must have 2 points"
        draw.rectangle(xy, outline=1, fill=1)
    elif shape_type == "line":
        assert len(xy) == 2, "Shape of shape_type=line must have 2 points"
        draw.line(xy=xy, fill=1, width=line_width)
    elif shape_type == "linestrip":
        draw.line(xy=xy, fill=1, width=line_width)
    elif shape_type == "point":
        assert len(xy) == 1, "Shape of shape_type=point must have 1 points"
        cx, cy = xy[0]
        r = point_size
        draw.ellipse([cx - r, cy - r, cx + r, cy + r], outline=1, fill=1)
    else:
        assert len(xy) > 2, "Polygon must have points more than 2"
        draw.polygon(xy=xy, outline=1, fill=1)
    mask = np.array(mask, dtype=bool)
    return mask


def shapes_to_label(img_shape, shapes, label_name_to_value):
    cls = np.zeros(img_shape[:2], dtype=np.int32)
    ins = np.zeros_like(cls)
    instances = []
    for shape in shapes:
        points = shape["points"]
        label = shape["label"]
        group_id = shape.get("group_id")
        if group_id is None:
            group_id = uuid.uuid1()
        shape_type = shape.get("shape_type", None)
        cls_name = label
        instance = (cls_name, group_id)
        if instance not in instances:
            instances.append(instance)
        ins_id = instances.index(instance) + 1
        cls_id = label_name_to_value[cls_name]
        mask = shape_to_mask(img_shape[:2], points, shape_type)
        cls[mask] = cls_id
        ins[mask] = ins_id
    return cls, ins


def lblsave(filename, lbl):
    import imgviz
    if osp.splitext(filename)[1] != ".png":
        filename += ".png"
    if lbl.min() >= -1 and lbl.max() < 255:
        lbl_pil = PIL.Image.fromarray(lbl.astype(np.uint8), mode="P")
        colormap = imgviz.label_colormap()
        lbl_pil.putpalette(colormap.flatten())
        lbl_pil.save(filename)
    else:
        raise ValueError(
            "[%s] Cannot save the pixel-wise class label as PNG. "
            "Please consider using the .npy format." % filename
        )





if __name__ == '__main__':
    jpgs_path   = "datasets/JPEGImages"
    pngs_path   = "datasets/SegmentationClass"
    classes     = ["_background_","aeroplane", "bicycle", "bird", "boat", "bottle", "bus", "car", "cat", "chair", "cow", "diningtable", "dog", "horse", "motorbike", "person", "pottedplant", "sheep", "sofa", "train", "tvmonitor"]
    count = os.listdir("./datasets/before/") 
    for i in range(0, len(count)):
        path = os.path.join("./datasets/before", count[i])
        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 = 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, 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 = shapes_to_label(img.shape, data['shapes'], label_name_to_value)     
            PIL.Image.fromarray(img).save(osp.join(jpgs_path, count[i].split(".")[0]+'.jpg'))
            new = np.zeros([np.shape(img)[0],np.shape(img)[1]])
            print('new_shape: ', new.shape)
            print('label_names: ', label_names)
            for name in label_names:
                index_json = label_names.index(name)
                index_all = classes.index(name)
                print('index_all: ', index_all)
                new = new + index_all*(np.array(lbl) == index_json)
            print('new_shape: ', new.shape)
            lblsave(osp.join(pngs_path, count[i].split(".")[0]+'.png'), new)
            print('Saved ' + count[i].split(".")[0] + '.jpg and ' + count[i].split(".")[0] + '.png')

      本以为能够正常运行,结果报错:

        说是维度不对,这个我已经在前面把各个节点的数据的shape都打印出来了,的确new_shape的数据shape是不对的,因为这里的问题就导致后面fromarray方法报错了,接下来还是修改代码,但是没有很好的思路,在网上查了这个报错的帖子,很多回答都是版本的问题,我在想可能也是因为新版本对应方法的处理发生了变化,这里就回到一个比较老的版本来重新改写如下:

#!usr/bin/env python
# encoding:utf-8
from __future__ import division


"""
__Author__:沂水寒城
功能: 图像分割数据集解析处理
"""

import io
import os
import base64
import json
import uuid
import cv2
import os.path as osp
import numpy as np
import PIL.Image
from PIL import Image
import PIL.Image
import PIL.ImageDraw


def img_b64_to_arr(img_b64):
    """
    base64转array
    """
    imgdata = base64.b64decode(img_b64)
    image = io.BytesIO(imgdata)
    img = Image.open(image)
    res = np.asarray(img)
    return res


def shape_to_mask(img_shape, points, shape_type=None, line_width=10, point_size=5):
    mask = np.zeros(img_shape[:2], dtype=np.uint8)
    mask = PIL.Image.fromarray(mask)
    draw = PIL.ImageDraw.Draw(mask)
    xy = [tuple(point) for point in points]
    if shape_type == "circle":
        assert len(xy) == 2, "Shape of shape_type=circle must have 2 points"
        (cx, cy), (px, py) = xy
        d = math.sqrt((cx - px) ** 2 + (cy - py) ** 2)
        draw.ellipse([cx - d, cy - d, cx + d, cy + d], outline=1, fill=1)
    elif shape_type == "rectangle":
        assert len(xy) == 2, "Shape of shape_type=rectangle must have 2 points"
        draw.rectangle(xy, outline=1, fill=1)
    elif shape_type == "line":
        assert len(xy) == 2, "Shape of shape_type=line must have 2 points"
        draw.line(xy=xy, fill=1, width=line_width)
    elif shape_type == "linestrip":
        draw.line(xy=xy, fill=1, width=line_width)
    elif shape_type == "point":
        assert len(xy) == 1, "Shape of shape_type=point must have 1 points"
        cx, cy = xy[0]
        r = point_size
        draw.ellipse([cx - r, cy - r, cx + r, cy + r], outline=1, fill=1)
    else:
        assert len(xy) > 2, "Polygon must have points more than 2"
        draw.polygon(xy=xy, outline=1, fill=1)
    mask = np.array(mask, dtype=bool)
    return mask


def shapes_to_label(img_shape, shapes, label_name_to_value, type="class"):
    assert type in ["class", "instance"]
    cls = np.zeros(img_shape[:2], dtype=np.int32)
    if type == "instance":
        ins = np.zeros(img_shape[:2], dtype=np.int32)
        instance_names = ["_background_"]
    for shape in shapes:
        points = shape["points"]
        label = shape["label"]
        shape_type = shape.get("shape_type", None)
        if type == "class":
            cls_name = label
        elif type == "instance":
            cls_name = label.split("-")[0]
            if label not in instance_names:
                instance_names.append(label)
            ins_id = instance_names.index(label)
        cls_id = label_name_to_value[cls_name]
        mask = shape_to_mask(img_shape[:2], points, shape_type)
        cls[mask] = cls_id
        if type == "instance":
            ins[mask] = ins_id
    if type == "instance":
        return cls, ins
    return cls


def label_colormap(N=256):
    def bitget(byteval, idx):
        return (byteval & (1 << idx)) != 0

    cmap = np.zeros((N, 3))
    for i in range(0, N):
        id = i
        r, g, b = 0, 0, 0
        for j in range(0, 8):
            r = np.bitwise_or(r, (bitget(id, 0) << 7 - j))
            g = np.bitwise_or(g, (bitget(id, 1) << 7 - j))
            b = np.bitwise_or(b, (bitget(id, 2) << 7 - j))
            id = id >> 3
        cmap[i, 0] = r
        cmap[i, 1] = g
        cmap[i, 2] = b
    cmap = cmap.astype(np.float32) / 255
    return cmap


def lblsave(filename, lbl):
    if osp.splitext(filename)[1] != ".png":
        filename += ".png"
    if lbl.min() >= -1 and lbl.max() < 255:
        lbl_pil = PIL.Image.fromarray(lbl.astype(np.uint8), mode="P")
        colormap = label_colormap(255)
        lbl_pil.putpalette((colormap * 255).astype(np.uint8).flatten())
        lbl_pil.save(filename)
    else:
        raise ValueError(
            "[%s] Cannot save the pixel-wise class label as PNG. "
            "Please consider using the .npy format." % filename
        )


if __name__ == "__main__":
    jpgs_path = "datasets/JPEGImages"
    pngs_path = "datasets/SegmentationClass"
    classes = [
        "_background_",
        "aeroplane",
        "bicycle",
        "bird",
        "boat",
        "bottle",
        "bus",
        "car",
        "cat",
        "chair",
        "cow",
        "diningtable",
        "dog",
        "horse",
        "motorbike",
        "person",
        "pottedplant",
        "sheep",
        "sofa",
        "train",
        "tvmonitor",
    ]
    count = os.listdir("./datasets/before/")
    for i in range(0, len(count)):
        path = os.path.join("./datasets/before", count[i])
        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 = 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, 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 = shapes_to_label(img.shape, data["shapes"], label_name_to_value)
            PIL.Image.fromarray(img).save(
                osp.join(jpgs_path, count[i].split(".")[0] + ".jpg")
            )
            new = np.zeros([np.shape(img)[0], np.shape(img)[1]])
            print("new_shape: ", new.shape)
            print("label_names: ", label_names)
            for name in label_names:
                index_json = label_names.index(name)
                index_all = classes.index(name)
                print("index_all: ", index_all)
                new = new + index_all * (np.array(lbl) == index_json)
            print("new_shape: ", new.shape)
            lblsave(osp.join(pngs_path, count[i].split(".")[0] + ".png"), new)
            print(
                "Saved "
                + count[i].split(".")[0]
                + ".jpg and "
                + count[i].split(".")[0]
                + ".png"
            )

        运行输出如下:

       问题完美解决,记录备忘!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5521329.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-13
下一篇 2022-12-13

发表评论

登录后才能评论

评论列表(0条)

保存