目标检测数据预处理——无标签背景图(负样本)的拼图代码

训练目标检测模型有个很令人头疼的问题,就是有些特征与要训练的特征较为相似的背景区域也被误检出来(作为本应不该检测出来的负样本却被误检出为正样本的FP)。
根据这一问题的解决办法,除了可以对正样本特征较为模糊或者有歧义的样本进行清洗,还有一个策略就是收集这些误检的背景图作为负样本(不标标签)参与训练。

所以本片就针对这类无标签的图片的拼图代码进行编写。

思路

  1. 首先背景图或大或小(一般根据实际摄像头误检框出的区域稍微外括少部分比例),而训练输入的size是固定的,为了不让小图的resize比例过大导致的太模糊特征遭到破坏,我们这里依据图片的大小范围进行1×1、2×2等宫格拼图(这里的图片大小都是特定大小,更复杂的放在下一篇)。
  2. 将范围相同的图片放在同一容器中,每次取n(1×1、2×2……)个样本,依次粘贴到一张大图上,大图的大小就是训练输入的大小。
  3. 拼图的图片会依次升序命令,而被拼的小图也会依次记录其图片名。这里的作用主要是用在模型测试上,将这些拼图输入模型测试,若是哪张拼图上有检测框,则证明哪张图片有误检,可以根据图片名以及在图片当中的哪一个位置来判断原图(被拼的小图)是哪张,可以快速找到领出来再次作为负样本进行训练。

代码

import PIL.Image as Image
import os
import cv2

img_size = 416

# 定义图像拼接函数
def image_compose(idx, ori_tmp, num):
    to_image = Image.new('RGB', (img_size, img_size)) #创建一个新图
    a = 0
    for y in range(idx):
        for x in range(idx):
            to_image.paste(Image.open(os.path.join(images_path, ori_tmp[a])), (
                int(x * (img_size / idx)), int(y * (img_size / idx))))
            print(f"ori_tmp[{
      
      a}] :", ori_tmp[a])
            a += 1
    new_name = os.path.join(save_path, "bg_" + str(idx) + "_" + str(num) + ".jpg")
    to_image.save(new_name) # 保存新图
    # print(new_name)
 
images_path = '/data/cch/000test/img'  # 图片集地址
save_path = '/data/cch/000test/save'  # 图片转换后的地址
 
ori_1 = []    
ori_2 = [] 
ori_3 = []
ori_4 = []
ori_5 = []   # 存放将要5×5拼图的原图
ori = [ori_1, ori_2, ori_3, ori_4, ori_5]

image_names = os.listdir(images_path)
for i in image_names:
    imgPath = os.path.join(images_path, i)
    img = cv2.imread(imgPath)
    [img_h, img_w, _] = img.shape
    img_h = max(img_h, img_w)
    # print(img_h,img_w)
    if img_h == img_size:
        ori_1.append(i)
    elif img_h == int(208/2):
        ori_2.append(i)
    elif img_h == int(208/3):
        ori_3.append(i)
    elif img_h == int(208/4):
        ori_4.append(i)
    elif img_h == int(208/5):
        ori_5.append(i)
# print(ori_5)
idx = 1
for ori_n in ori:
    ori_path = os.path.join(save_path, "path_txt", "ori_" + str(idx) + ".txt")
    if os.path.exists(ori_path):
        os.remove(ori_path)
    for i in ori_n:
        with open(ori_path, 'a') as file:
            file.write(i)
            file.write("\n")

    num = 0
    ori_tmp = []
    for i in ori_n:
        if len(ori_tmp) < (idx*idx):
            ori_tmp.append(i)
        else:
            image_compose(idx, ori_tmp,num) #调用函数
            # print(ori_tmp)
            ori_tmp.clear()
            num += 1
            ori_tmp.append(i)

    idx += 1

测试

我们拿一组图片进行测试,输出的目录如下:
在这里插入图片描述
txt文本文件则是保存的拼图顺序。
1×1即单张图片(以bg_1开头):
在这里插入图片描述
2×2即单张图片(以bg_2开头):
在这里插入图片描述
3×3即单张图片(以bg_3开头):
在这里插入图片描述
4×4即单张图片(以bg_4开头):
在这里插入图片描述
5×5即单张图片(以bg_5开头):
在这里插入图片描述
我觉得5×5的小图已经足够小的,在小的基本上也不可能被误检出来,即使真的误检出来也没必要加进去训练了。

最后

本篇是拼图篇最简单的案例,即没有标签、小图的大小也要固定死是那五个值才能拼、拼图方式为宫格的,都被限定死了,接下来的将会针对有标签的、图片大小不固定的、非宫格拼图方式等复杂方式进行拼图。

猜你喜欢

转载自blog.csdn.net/weixin_45354497/article/details/130654717