图像处理:利用python-opencv自动(辅助)标注数据集的简单实现

图像处理:利用python-opencv自动(辅助)标注数据集的简单实现

  • 本文目的是为深度学习初学者提供一个自动(辅助)标注数据的方法,或者说是提供一种想法。
  • 做深度学习的同志们都知道,想要模型精度达到预期,前期数据集的准备是至关重要的一步;常言道,万事开头难!而数据集的标注就是一个大工程,尤其是欲要将训练出来的模型应用在复杂且多变的场景中。那么,一个可以帮助标注数据的全自动或者半自动的辅助软件(代码)显得格外重要。基于这个想法,我们利用python-opencv写了一个简单的文件,来实现预期效果。
  • 图片:随便在白纸上面画一些“√”、“×”,手机拍照;
  • 方法:利用python-opencv找到“√”和“×”,生成包围的轮廓点,然后保存到对应的.json文件中;
  • 下面给出代码:
import cv2
import io
from io import BytesIO
import binascii
import json
import numpy as np
import PIL
import os.path as osp
from labelme.logger import logger
from labelme import PY2
from labelme import QT4
import PIL.Image
import base64
from labelme import utils

# 转化成json字典
def dict_json(flags, imageData, shapes, imagePath, imageHeight=100,
              imageWidth=100):
    '''
    :param imageData: str
    :param shapes: list
    :param imagePath: str
    :return: dict
    '''
    return {"version": "4.5.6", "flags": flags, "shapes": shapes,
            'imagePath': imagePath.split('/')[-1], "imageData": imageData,
            'imageHeight': imageHeight,
            'imageWidth': imageWidth}

# 生成imagedata
def load_image_file(filename):
    try:
        image_pil = PIL.Image.open(filename)
    except IOError:
        logger.error('Failed opening image file: {}'.format(filename))
        return
    # apply orientation to image according to exif
    image_pil = utils.apply_exif_orientation(image_pil)
    with io.BytesIO() as f:
        ext = osp.splitext(filename)[1].lower()
        if PY2 and QT4:
            format = 'PNG'
        elif ext in ['.jpg', '.jpeg']:
            format = 'JPEG'
        else:
            format = 'PNG'
        image_pil.save(f, format=format)
        f.seek(0)
        return f.read()

if __name__ == '__main__':
    # 读取图片
    img_name = "1.jpg"
    # 生成图片数据, 此处需要更改文件路径及名称
    image_Path = '/home/ytf/PycharmProjects/' + img_name
    img = cv2.imread("/home/ytf/PycharmProjects/" + img_name)
    
    # 指定label标签
    # label = "wrong"
    label = "right"
    print("image_Path =", image_Path)

    imageData = load_image_file(image_Path)
    imageData = base64.b64encode(imageData).decode('utf-8')
    imageHeight = img.shape[0]
    imageWidth = img.shape[1]
    imagePath = image_Path[-12:]

    # 灰度图
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # cv2.imshow("gray", gray)
    # 滤波
    blur = cv2.blur(gray, (3, 3))
    # cv2.imshow("blur", blur)
    # 二值化
    # ret, thre = cv2.threshold(blur, 200, 255, cv2.THRESH_BINARY)
    binary = cv2.adaptiveThreshold(blur, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, \
                                   cv2.THRESH_BINARY_INV, 25, 10)
    # 膨胀
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
    dilated = cv2.dilate(binary, kernel)  
    contours, hierarchy = cv2.findContours(dilated, cv2.RETR_EXTERNAL,
                                           cv2.CHAIN_APPROX_SIMPLE)
    filled_img = cv2.drawContours(img, contours, -1, (0, 0, 255), cv2.FILLED)
    # cv2.imshow("img2", filled_img)
    
    newshapes = []
    shapes = []
    # 定义边框属性
    shape_type = "polygon"
	# 遍历轮廓
    for i in range(len(contours)):
        epsilon = 0.003 * cv2.arcLength(contours[i], True)
        # 多边拟合
        approx = cv2.approxPolyDP(contours[i], epsilon, True)
        adp = cv2.drawContours(filled_img, [approx], 0, (0, 255, 0), 2)
        approx_points = []
        # 生成需要的坐标点
        for m in range(len(approx)):
            approx_point_x = np.float(((approx[m])[0])[0])
            approx_point_y = np.float(((approx[m])[0])[1])
            point = [approx_point_x, approx_point_y]
            # print("point =", point)
            approx_points.append(point)

        # 组合写的json成员
        flags = {}
        line_color = None
        fill_color = None
        group_id = None
        newshapes.append(
            {"label": label,
             # "line_color": line_color,
             # "fill_color": fill_color,
             "points": approx_points,
             "group_id": group_id,
             "shape_type": shape_type,
             "flags": flags})

    data_final = dict_json(flags, imageData, newshapes, imagePath,
                           imageHeight,
                           imageWidth)
                           
    json_file = imagePath[:-4] + '.json'
    print("json_file =", json_file)
    json.dump(data_final, open(json_file, 'w'))

【原图】
在这里插入图片描述
在这里插入图片描述
【效果图】

  • 在Labelme中打开
    在这里插入图片描述
    在这里插入图片描述
  • 实现方法很简单,主要目的是想提供一种想法,大家可根据自己的项目情况,开发适合的辅助标注工具,以提高效率;
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值