CTPN代码研读(二) utils/prepare(label)研读

关于CTPN各属性性质博文 见:1. 数据集的使用以及模型

CTPN代码研读系列:

1. 数据集的使用以及模型
2. utils/prepare/label
3. utils/dataset/data_provider

(本内容为自己理解,如有错误欢迎指正)

工程代码常用知识点:

  • #其实sys.path是一个列表,这个列表内的路径都添加到环境变量中去了。
  • #sys.path.append()方法可以添加自定义的路径。
  • #os.getcwd(): 返回当前目录
  • #os.listdir() 返回指定的文件夹包含的文件或文件夹的名字的列表。
  • #os.path.join()函数用于路径拼接文件路径。
  • #os.path.split()返回文件的路径和文件名
>>> str="hello boy<[www.doiido.com]>byebye"
>>> str.split("[")[1].split("]")[0]
'www.doiido.com'
>>> str.split("[")[1].split("]")[0].split(".")
['www', 'doiido', 'com']

主要代码流程

  1. 读取图片
  2. 把图片扩大到1200*600尺寸
  3. 读取标签坐标,并以此处理图片
  4. 取16固定宽度,对检测框进行分割
  5. 将分割的检测框写入新的标签txt文件

注释版代码:

1.split_label.py

'''
2019/5/5
reader: zhengtianlun
fuction: 将图片放大到1200*600大小,将坐标标签分割成固定的16像素矩形框

'''
# coding = utf-8
import os
import sys

import cv2 as cv
import numpy as np
from tqdm import tqdm

sys.path.append(os.getcwd())
#其实sys.path是一个列表,这个列表内的路径都添加到环境变量中去了。
#sys.path.append()方法可以添加自定义的路径。
#os.getcwd(): 返回当前目录
from utils import orderConvex, shrink_poly
#shrink:收缩  convex:凸面
print(os.getcwd())
#DATA_FOLDER = "/media/D/DataSet/mlt_selected/"
DATA_FOLDER = "../../mlt_selected/"
#/media:为绝对路径 media为相对路径
OUTPUT = "../../data/dataset/mlt/"
MAX_LEN = 1200
MIN_LEN = 600

im_fns = os.listdir(os.path.join(DATA_FOLDER, "image"))
#os.listdir() 返回指定的文件夹包含的文件或文件夹的名字的列表。
#os.path.join()函数用于路径拼接文件路径。
im_fns.sort()

if not os.path.exists(os.path.join(OUTPUT, "image")):
    os.makedirs(os.path.join(OUTPUT, "image"))
if not os.path.exists(os.path.join(OUTPUT, "label")):
    os.makedirs(os.path.join(OUTPUT, "label"))

for im_fn in tqdm(im_fns):
    try:
        # 处理标签,获得答案
        _, fn = os.path.split(im_fn)
        # os.path.split()返回文件的路径和文件名
        bfn, ext = os.path.splitext(fn)
        # os.path.splitext()将文件名和扩展名分开
        if ext.lower() not in ['.jpg', '.png']:
            continue

        gt_path = os.path.join(DATA_FOLDER, "label", 'gt_' + bfn + '.txt')
        img_path = os.path.join(DATA_FOLDER, "image", im_fn)

        img = cv.imread(img_path)
        img_size = img.shape
        im_size_min = np.min(img_size[0:2])
        im_size_max = np.max(img_size[0:2])
        #宽 长 RGB(3)这里意思是只取长和宽

        #等比例缩放图片尺寸
        im_scale = float(600) / float(im_size_min)
        if np.round(im_scale * im_size_max) > 1200:
        #np.round 返回浮点数的四舍五入值
            im_scale = float(1200) / float(im_size_max)
        new_h = int(img_size[0] * im_scale)
        new_w = int(img_size[1] * im_scale)

        new_h = new_h if new_h // 16 == 0 else (new_h // 16 + 1) * 16
        new_w = new_w if new_w // 16 == 0 else (new_w // 16 + 1) * 16
        #向上取整

        re_im = cv.resize(img, (new_w, new_h), interpolation=cv.INTER_LINEAR)
        re_size = re_im.shape

        #读取标签并获得标签检测框坐标
        polys = []
        with open(gt_path, 'r') as f:
            lines = f.readlines()
        for line in lines:
            splitted_line = line.strip().lower().split(',')
            #str.strip()就是把字符串(str)的头和尾的空格,以及位于头尾的\n \t之类给删掉。
            x1, y1, x2, y2, x3, y3, x4, y4 = map(float, splitted_line[:8])
            #map() 会根据提供的函数对指定序列做映射。
            #第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 function 函数返回值的新列表。
            poly = np.array([x1, y1, x2, y2, x3, y3, x4, y4]).reshape([4, 2])
            #因已对图片缩放,故等比例对图片的检测坐标进行缩放
            poly[:, 0] = poly[:, 0] / img_size[1] * re_size[1]
            poly[:, 1] = poly[:, 1] / img_size[0] * re_size[0]
            poly = orderConvex(poly)
            polys.append(poly)
            #poly 0/1代表x坐标,y坐标

            cv.polylines(re_im, [poly.astype(np.int32).reshape((-1, 1, 2))], True,color=(0, 255, 0), thickness=2)
            #polylines:绘制多边形  thickness:折线粗细  astype:修改数据类型

        res_polys = []
        for poly in polys:
            # delete polys with width less than 10 pixel
            if np.linalg.norm(poly[0] - poly[1]) < 10 or np.linalg.norm(poly[3] - poly[0]) < 10:
            #np.linalg.norm:线性代数的范数
                continue

            res = shrink_poly(poly)
            #
            for p in res:
                cv.polylines(re_im, [p.astype(np.int32).reshape((-1, 1, 2))], True, color=(0, 255, 0), thickness=1)

            res = res.reshape([-1, 4, 2])
            for r in res:
                x_min = np.min(r[:, 0])
                y_min = np.min(r[:, 1])
                x_max = np.max(r[:, 0])
                y_max = np.max(r[:, 1])

                res_polys.append([x_min, y_min, x_max, y_max])

        cv.imwrite(os.path.join(OUTPUT, "image", fn), re_im)
        with open(os.path.join(OUTPUT, "label", bfn) + ".txt", "w") as f:
            for p in res_polys:
                line = ",".join(str(p[i]) for i in range(4))
                f.writelines(line + "\r\n")


                for p in res_polys:
                    cv.rectangle(re_im,(p[0],p[1]),(p[2],p[3]),color=(0,0,255),thickness=1)

                cv.imshow("demo",re_im)
                cv.waitKey(20)
    except:
        print("Error processing {}".format(im_fn))

2.utils.py

# coding = utf-8
import numpy as np
from shapely.geometry import Polygon


def pickTopLeft(poly):

#返回四个点坐标??

    idx = np.argsort(poly[:, 0])
    if poly[idx[0], 1] < poly[idx[1], 1]:
        s = idx[0]
    else:
        s = idx[1]

    return poly[(s, (s + 1) % 4, (s + 2) % 4, (s + 3) % 4), :]


def orderConvex(p):

#将检测框的坐标点传入,通过凸包函数,变成面积

    points = Polygon(p).convex_hull
    #convex_hull :凸包就是围绕点或形状的紧密拟合的凸边界
    points = np.array(points.exterior.coords)[:4]
    #exterior:外貌
    points = points[::-1]
    points = pickTopLeft(points)
    points = np.array(points).reshape([4, 2])
    return points


def shrink_poly(poly, r=16):
    #微分成细小的矩阵??

    # y = kx + b
    x_min = int(np.min(poly[:, 0]))
    x_max = int(np.max(poly[:, 0]))

    k1 = (poly[1][1] - poly[0][1]) / (poly[1][0] - poly[0][0])
    b1 = poly[0][1] - k1 * poly[0][0]

    k2 = (poly[2][1] - poly[3][1]) / (poly[2][0] - poly[3][0])
    b2 = poly[3][1] - k2 * poly[3][0]

    res = []

    start = int((x_min // 16 + 1) * 16)
    end = int((x_max // 16) * 16)

    p = x_min
    res.append([p, int(k1 * p + b1),
                start - 1, int(k1 * (p + 15) + b1),
                start - 1, int(k2 * (p + 15) + b2),
                p, int(k2 * p + b2)])

    for p in range(start, end + 1, r):
        res.append([p, int(k1 * p + b1),
                    (p + 15), int(k1 * (p + 15) + b1),
                    (p + 15), int(k2 * (p + 15) + b2),
                    p, int(k2 * p + b2)])
    return np.array(res, dtype=np.int).reshape([-1, 8])

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值