VOC数据集制作 滑窗切分图片python

1、labelme画标签转标签

这一步见链接labelme转标签

2、python滑窗切分图片

上一步生成的标签是单通道的,我们所需要的PASCAL VOC的数据集的标签也是单通道8位图,所以切分的时候要些许注意有个函数给映一个颜色过来,接下来只需要将所得的标签切分为我们想要的尺寸就可以了。对应的原图像直接切分就🆗:

  1. 原图像的滑窗切分
'''
实现滑窗切分图片
'''


import os
import cv2
from PIL import Image
import numpy as np
crop_height = 512 ###***********滑窗裁剪的图片高度***************
crop_width = 512 ###***********滑窗裁剪的图片宽度***********
stride = 256 ###***********滑窗裁剪的步长***********
overlap = int(crop_width - stride) ###前一张裁剪图和当前裁剪图的重叠区域
img_predict_dir = 'E:\\aaletter\\lzq\\palu\\yt\\' ###***********要进行测试的图片所在的文件夹***********
img_result_dir = 'E:\\aaletter\\lzq\\palu\\150stride\\ytq\\' ###***********测试结果保存位置***********
if not os.path.exists(img_result_dir):  # 文件夹不存在,则创建
    os.mkdir(img_result_dir)
num = 1

def fuse(output_image, row, column, overlap, counter, temp1, temp2, res_row, res_column):# output_image拼接输入图片,row高度需要融合的数量,column宽度度需要融合的数量,overlap 重复检测的区域100 由于切割图片是500,步长为100
    # output = 'process area: ' + '%04d'%(counter)                                         counter当前融合的第*张,temp1已拼接好的**,temp2已拼接好的**,res_row剩余的高度,res_column剩余的宽度
    # print(output)

    if counter % column == 0:  #如果当前融合的图片是这张图片最右边际
        output_image = output_image[:, -(res_column + overlap):]
    if counter > (row - 1) * column:
        output_image = output_image[-(res_row + overlap):, :]

    if counter % column == 1: ###一行行进行滑窗
        temp1 = output_image
    else:
        temp1_1 = temp1[:, 0:-overlap, :]  #前一张融合图片的未重叠的部分,0:-100 第0列到倒数第100列->0:400
        temp1_2 = temp1[:, -overlap:, :]    #前一张融合图片与当前融合图片重叠检测部分
        temp1_3 = output_image[:, 0:overlap, :] #当前融合图片与前一张融合图片重叠检测部分
        temp1_4 = output_image[:, overlap:, :] #当前融合图片与前一张图片为重叠部分
        temp1_fuse = 0.5 * temp1_2 + 0.5 * temp1_3  #将当前融合图片与前一张融合图片互相重叠的部分加权取平均
        temp1 = np.concatenate((temp1_1, temp1_fuse, temp1_4), axis=1)  #融合结束
        if int(counter % column) == 0: #判断是第几行
            if counter == column: ##判断是否进入下一行 刚好整除行的column 说明一行滑窗结束,准备进入下一行
                temp2 = temp1 ##将一行滑窗后的temp1保存到temp2中,进行一行滑窗时候temp2是不变的,只在进行换行滑窗的时候变化
            else:
                temp2_1 = temp2[0:-overlap, :, :]
                temp2_2 = temp2[-overlap:, :, :]
                temp2_3 = temp1[0:overlap, :, :]
                temp2_4 = temp1[overlap:, :, :]
                temp2_fuse = 0.5 * temp2_2 + 0.5 * temp2_3
                temp2 = np.concatenate((temp2_1, temp2_fuse, temp2_4), axis=0)

    return temp1, temp2


for filename in os.listdir(img_predict_dir):
    img_name = img_predict_dir + filename  ###图片名字

    loaded_image = cv2.imread(img_name)  ##cv2形式读取图片格式为BGR 后面要进行image格式转换,否则测试叠掩的三通道合成图会出问题

    img_h = loaded_image.shape[0]  ##cv2模式读取图片的高用img.shape[0] image.open()读取图片的高度显示用Img.height,宽度用img.width
    img_w = loaded_image.shape[1]  ##cv2模式读取图片的宽用img.shape[1]
    row = int((img_h - crop_height) / stride + 1)  ##高可以切为row块
    column = int((img_w - crop_width) / stride + 1)  ##宽可以切为cloumn块
    res_row = img_h - (crop_height + stride * (row - 1))  ##高度滑窗切分完row块后还剩余的部分
    res_column = img_w - (crop_width + stride * (column - 1))  ##宽度度滑窗切分完row块后还剩余的部分
    if (img_h - crop_height) % stride > 0:  ##判断剩余高度是否还可以继续进行滑窗切分
        row = row + 1
    if (img_w - crop_width) % stride > 0:  ##判断剩余宽度是否还可以继续进行滑窗切分
        column = column + 1
    counter = 1  ##起始从第一块开始


    for i in range(row):
        for j in range(column):
            if i == row - 1:  ##判断高度是否切到最后一块
                H_start = img_h - crop_height  ##如果是,最后一块的起始高度就是图片的高度往前数小图片要切分的高度crop_height
                H_end = img_h  ##结束高度就是图片的高的数字
            else:
                H_start = i * stride  ##如果不是切到最后一块,切分小图的起始高点就是第i块(第i次切分)*步长
                H_end = H_start + crop_height  ##结束高点就是 在开始的基础上直接加上crop_height
            if j == column - 1:
                W_start = img_w - crop_width
                W_end = img_w
            else:
                W_start = j * stride
                W_end = W_start + crop_width

            img_chip = loaded_image[H_start:H_end, W_start:W_end]  ##切块的小图片 nudarray格式
            image = Image.fromarray(cv2.cvtColor(img_chip, cv2.COLOR_BGR2RGB))
            s = '%04d' % num  # 04表示0001,0002等命名排序
            image.save(img_result_dir+str(s) + '.png')#**********注意图片格式********************#
            num = num+1
  1. 单通道标签的滑窗切分 ,和原图像差不多,只是加了一步映色操作
'''滑窗切分单通道图片,并上色'''
import os
import cv2
from PIL import Image
import numpy as np

crop_height = 512 ###滑窗裁剪的图片高度
crop_width = 512 ###滑窗裁剪的图片宽度
stride = 256 ###滑窗裁剪的步长
overlap = int(crop_width - stride) ###前一张裁剪图和当前裁剪图的重叠区域
img_predict_dir = 'E:\\aaletter\\lzq\\palu\\gt\\' ###要进行测试的图片所在的文件夹
img_result_dir = 'E:\\aaletter\\lzq\\palu\\150stride\\gtq\\' ###测试结果保存位置
if not os.path.exists(img_result_dir):  # 文件夹不存在,则创建
    os.mkdir(img_result_dir)
num = 1
# num_classes = 2
def make_palette(num_classes):

    palette = np.zeros((num_classes, 3), dtype=np.uint8)
    for k in range(0, num_classes):
        label = k
        i = 0
        while label:
            palette[k, 0] |= (((label >> 0) & 1) << (7 - i))
            palette[k, 1] |= (((label >> 1) & 1) << (7 - i))
            palette[k, 2] |= (((label >> 2) & 1) << (7 - i))
            label >>= 3
            i += 1
    return palette
for filename in os.listdir(img_predict_dir):
    img_name = img_predict_dir + filename  ###图片名字

    # loaded_image = cv2.imread(img_name)  ##cv2形式读取图片格式为BGR 后面要进行image格式转换,否则测试叠掩的三通道合成图会出问题
    loaded_image = Image.open(img_name)
    loaded_image = np.array(loaded_image)

    img_h = loaded_image.shape[0]  ##cv2模式读取图片的高用img.shape[0] image.open()读取图片的高度显示用Img.height,宽度用img.width
    img_w = loaded_image.shape[1]  ##cv2模式读取图片的宽用img.shape[1]
    row = int((img_h - crop_height) / stride + 1)  ##高可以切为row块
    column = int((img_w - crop_width) / stride + 1)  ##宽可以切为cloumn块
    res_row = img_h - (crop_height + stride * (row - 1))  ##高度滑窗切分完row块后还剩余的部分
    res_column = img_w - (crop_width + stride * (column - 1))  ##宽度度滑窗切分完row块后还剩余的部分
    if (img_h - crop_height) % stride > 0:  ##判断剩余高度是否还可以继续进行滑窗切分
        row = row + 1
    if (img_w - crop_width) % stride > 0:  ##判断剩余宽度是否还可以继续进行滑窗切分
        column = column + 1
    counter = 1  ##起始从第一块开始


    for i in range(row):
        for j in range(column):
            if i == row - 1:  ##判断高度是否切到最后一块
                H_start = img_h - crop_height  ##如果是,最后一块的起始高度就是图片的高度往前数小图片要切分的高度crop_height
                H_end = img_h  ##结束高度就是图片的高的数字
            else:
                H_start = i * stride  ##如果不是切到最后一块,切分小图的起始高点就是第i块(第i次切分)*步长
                H_end = H_start + crop_height  ##结束高点就是 在开始的基础上直接加上crop_height
            if j == column - 1:
                W_start = img_w - crop_width
                W_end = img_w
            else:
                W_start = j * stride
                W_end = W_start + crop_width

            img_chip = loaded_image[H_start:H_end, W_start:W_end]  ##切块的小图片 nudarray格式
            voc_palette = make_palette(21)
            image = Image.fromarray(img_chip)
            image.putpalette(voc_palette)  ####调色板上色
            s = '%04d' % num  # 04表示0001,0002等命名排序
            image.save(img_result_dir+str(s) + '.png')
            num = num+1

3、制作VOC格式数据集

数据集格式和制作方法见第3步VOC格式

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值