【制作自己的COCO数据集用于Mask_rcnn模型训练与预测推理】

在这里插入图片描述
   导师CSDN:太阳花的小绿豆、哔哩哔哩:霹雳吧啦Wz
   CSDN-Mask rcnn代码及详解链接: link
   所有基础分类、检测、分割代码都可至霹雳吧啦Wz的GitHub获取 link

一、Mask_rcnn训练COCO数据集介绍:

   1、mask_rcnn路径下data数据集构成如下:在这里插入图片描述
   其中,annotations为训练集的标注信息,train2017为训练图片,val2017为验证图片,分别如下所示:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
   对coco数据集不了解的朋友,可以点击链接: link

二、准备自己的数据集,然后进行labelme标注:

1、通过labelme.exe对自己准备的数据集进行标注,如下所示:
在这里插入图片描述   将标注的图片及对应json文件随意对应选取一部分用于训练,另一部分用于验证(可以通过代码随机挑选,也可以自己复制粘贴进行分离)

三、自行分离数据

在这里插入图片描述
在这里插入图片描述
   将对应的训练集和验证集图片及json文件放至自己建立的文件夹下,切记不要错乱了。最后,还有标注文件的处理,第四点讲解。

四、labelme标注json文件转coco数据集标注json文件

    提示:因为labelme标注生成的json文件信息与coco数据集标注json文件信息有所差异,Mask_rcnn训练以及推理需要coco数据集json格式。
   如下图所示,将第三点中分离的train训练图以及对应的json文件放入如下文件夹内:
在这里插入图片描述
在这里插入图片描述
   通过lableme2coco.py代码,将自己标注的数据集转成coco需要的格式,验证集也是如此,lableme2coco.py代码如下。
   下面展示一些 内联代码片

// An highlighted block
import json
import glob
import PIL.Image
import PIL.ImageDraw
import os
import base64
import io
import numpy as np
import PIL.ExifTags
import PIL.Image
import PIL.ImageOps
import shutil


def img_b64_to_arr(img_b64):
    f = io.BytesIO()
    f.write(base64.b64decode(img_b64))
    img_arr = np.array(PIL.Image.open(f))
    return img_arr


def img_arr_to_b64(img_arr):
    img_pil = PIL.Image.fromarray(img_arr)
    f = io.BytesIO()
    img_pil.save(f, format='PNG')
    img_bin = f.getvalue()
    if hasattr(base64, 'encodebytes'):
        img_b64 = base64.encodebytes(img_bin)
    else:
        img_b64 = base64.encodestring(img_bin)
    return img_b64


def img_data_to_png_data(img_data):
    with io.BytesIO() as f:
        f.write(img_data)
        img = PIL.Image.open(f)

        with io.BytesIO() as f:
            img.save(f, 'PNG')
            f.seek(0)
            return f.read()


def apply_exif_orientation(image):
    try:
        exif = image._getexif()
    except AttributeError:
        exif = None

    if exif is None:
        return image

    exif = {
        PIL.ExifTags.TAGS[k]: v
        for k, v in exif.items()
        if k in PIL.ExifTags.TAGS
    }

    orientation = exif.get('Orientation', None)

    if orientation == 1:
        # do nothing
        return image
    elif orientation == 2:
        # left-to-right mirror
        return PIL.ImageOps.mirror(image)
    elif orientation == 3:
        # rotate 180
        return image.transpose(PIL.Image.ROTATE_180)
    elif orientation == 4:
        # top-to-bottom mirror
        return PIL.ImageOps.flip(image)
    elif orientation == 5:
        # top-to-left mirror
        return PIL.ImageOps.mirror(image.transpose(PIL.Image.ROTATE_270))
    elif orientation == 6:
        # rotate 270
        return image.transpose(PIL.Image.ROTATE_270)
    elif orientation == 7:
        # top-to-right mirror
        return PIL.ImageOps.mirror(image.transpose(PIL.Image.ROTATE_90))
    elif orientation == 8:
        # rotate 90
        return image.transpose(PIL.Image.ROTATE_90)
    else:
        return image


class labelme2coco(object):
    def __init__(self,labelme_json=[],save_json_path='./new.json'):

        """
        Args: labelme_json: paths of labelme json files
        : save_json_path: saved path 
        """

        self.labelme_json=labelme_json
        self.save_json_path=save_json_path
        self.images=[]
        self.categories=[]
        self.annotations=[]
        # self.data_coco = {}
        self.label=[]
        self.annID=1
        self.height=0
        self.width=0

        self.save_json()

    def data_transfer(self):
        for num,json_file in enumerate(self.labelme_json):
            with open(json_file,'r') as fp:
                print("json_name=",json_file)
                data = json.load(fp)  
                (prefix, res) = os.path.split(json_file)
                (file_name, extension ) = os.path.splitext(res)
                self.images.append(self.image(data,num,file_name))
                for shapes in data['shapes']:
                    label=shapes['label']
                    if label not in self.label:
                        self.categories.append(self.categorie(label))
                        self.label.append(label)
                    points=shapes['points']
                    self.annotations.append(self.annotation(points,label,num))
                    self.annID+=1

    def image(self,data,num,file_name):
        image={}
        # img = img_b64_to_arr(data['imageData'])
        import cv2
        img = cv2.imread(os.path.join('./image', f'{file_name}.jpg'))
        
        height, width = img.shape[:2]
        img = None
        image['height']=height
        image['width'] = width
        image['id']= int(num+1)
        image['file_name'] = file_name + '.jpg'

        self.height=height
        self.width=width

        return image

    def categorie(self,label):
        categorie={}
        categorie['supercategory'] = label
        categorie['id']= int(len(self.label)+1) 
        categorie['name'] = label


        return categorie

    def annotation(self,points,label,num):
        annotation={}
        annotation['iscrowd'] = 0
        annotation['image_id'] = int(num+1)

        annotation['bbox'] = list(map(float,self.getbbox(points)))

        point=[]
        for p in points:
            point.append(p[0])
            point.append(p[1])

        annotation['segmentation']=[point] # at least 6 points

        annotation['category_id'] = self.getcatid(label)
        annotation['id'] = int(self.annID)
        #add area info
        annotation['area'] = self.height * self.width  #  the area is not used for detection 
        return annotation

    def getcatid(self,label):
        for categorie in self.categories:

            if label==categorie['name']:
                return categorie['id']

        return -1

    def getbbox(self,points):
        # img = np.zeros([self.height,self.width],np.uint8)
        # cv2.polylines(img, [np.asarray(points)], True, 1, lineType=cv2.LINE_AA)
        # cv2.fillPoly(img, [np.asarray(points)], 1)
        polygons = points
        mask = self.polygons_to_mask([self.height,self.width], polygons)
        return self.mask2box(mask)

    def mask2box(self, mask):
        # np.where(mask==1)
        index = np.argwhere(mask == 1)
        rows = index[:, 0]
        clos = index[:, 1]

        left_top_r = np.min(rows)  # y
        left_top_c = np.min(clos)  # x

        right_bottom_r = np.max(rows)
        right_bottom_c = np.max(clos)

        return [left_top_c, left_top_r, right_bottom_c-left_top_c, right_bottom_r-left_top_r]  # [x1,y1,w,h] for coco box format

    def polygons_to_mask(self,img_shape, polygons):
        mask = np.zeros(img_shape, dtype=np.uint8)
        mask = PIL.Image.fromarray(mask)
        xy = list(map(tuple, polygons))
        PIL.ImageDraw.Draw(mask).polygon(xy=xy, outline=1, fill=1)
        mask = np.array(mask, dtype=bool)
        return mask

    def data2coco(self):
        data_coco={}
        data_coco['images']=self.images
        data_coco['categories']=self.categories
        data_coco['annotations']=self.annotations
        categoryName=open("categoryName.txt",'w')

        for i in self.categories:
            categoryName.write(i['name']+'\n')

        return data_coco

    def save_json(self):
        self.data_transfer()
        self.data_coco = self.data2coco()
 
        json.dump(self.data_coco, open(self.save_json_path, 'w', encoding='utf-8'), indent=4, separators=(',', ': '), cls=MyEncoder)

# type check when save json files
class MyEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, np.integer):
            return int(obj)
        elif isinstance(obj, np.floating):
            return float(obj)
        elif isinstance(obj, np.ndarray):
            return obj.tolist()
        else:
            return super(MyEncoder, self).default(obj)

def copyImage():  # 存放的图片文件夹路径
    imgdir='./image/'
    for file in os.listdir(imgdir):
        if file.endswith('.jpg'):
            shutil.copyfile(imgdir+file,'./data/coco2017/val_me/'+file)

def copyCategory():
    shutil.copyfile('categoryName.txt',"F:\MyDeepLearning\deep-learning-for-image-processing-master\pytorch_object_detection\mask_rcnn\my_ImageData\data\coco2017")

if "__main__"==__name__:
    labelme_json=glob.glob('./data/coco2017/json_lableme/*.json')  # Lableme标注文件路径
    if not os.path.exists("./data/coco2017/annotations/"):  # 生成的coco标注文件路径
        os.makedirs('./data/coco2017/annotations/')
    if not os.path.exists('./data/coco2017/val_me/'):  # 训练所需的图片
        os.makedirs('./data/coco2017/val_me/')
    copyImage()
    labelme2coco(labelme_json,'./data/coco2017/annotations/val.json')  # 生成的coco标注文件
    # copyCategory()  # 不晓得什么用途

    提示:命名为lableme2coco.py,设置正确路径直接运行即可。
   将最后得到的数据集,分别放入训练和预测推理的路径下,进行训练即可:
在这里插入图片描述

五、效果如下所示:

    提示:train:训练,需要修改数据集路径以及检测目标类别数。predict:需要将训练得到的模型放至对应文件夹下。
在这里插入图片描述
在这里插入图片描述
    提示:希望帮助到有需要的人,不喜勿喷,谢谢。非常感谢霹雳吧啦Wz导师的知识分享。

  • 14
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
制作自己的COCO数据集需要以下步骤: 1. 收集数据:收集与你的目标检测或者分割任务相关的图像数据,并且对这些图像进行标注。通常使用的标注工具有LabelImg、VGG Image Annotator (VIA)、Labelbox等。 2. 标注数据:使用标注工具进行数据标注。对于目标检测任务,需要标注对象的位置和类别。对于分割任务,需要标注对象的位置和分割掩膜。标注完成后,将标注信息保存为COCO格式的json文件。 3. 配置训练环境:需要安装Python环境、COCO API、PyTorch等工具。同时,需要下载预训练模型训练代码。可以使用开源的目标检测框架如Detectron2、MMDetection等,或者使用PyTorchCOCO API自己编写训练代码。 4. 数据预处理:将标注数据转化为COCO格式的json文件,并且生成训练和验证数据集。可以使用开源的数据预处理工具如COCO API、mmcv等。 5. 训练模型:使用训练数据集模型进行训练。可以使用预训练模型进行初始化,也可以从头开始训练训练完成后,使用验证数据集模型进行评估。 6. 模型应用:使用训练好的模型对新数据进行目标检测或者分割。 制作自己的COCO数据集需要较大的工作量和耐心,需要对数据进行充分的标注和整理,并且需要掌握一定的Python编程技能。但是一旦完成,可以得到一个高质量的数据集用于训练和评估目标检测或分割模型

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值