目标检测:将已经标注完毕的图像数据进行拼接,并合并对应的xml标注文件

import os
import numpy as np
import cv2, uuid
import PIL.Image as Image
import matplotlib.pyplot as plt
import xml.etree.ElementTree as ET
import random


def bboxes2xml(folder, img_name, width, height, gts, xml_save_to):
    xml_file = open((xml_save_to + '/' + img_name + '.xml'), 'w')
    xml_file.write('<annotation>\n')
    xml_file.write('    <folder>' + folder + '</folder>\n')
    xml_file.write('    <filename>' + str(img_name) + '.jpg' + '</filename>\n')
    xml_file.write('    <size>\n')
    xml_file.write('        <width>' + str(width) + '</width>\n')
    xml_file.write('        <height>' + str(height) + '</height>\n')
    xml_file.write('        <depth>3</depth>\n')
    xml_file.write('    </size>\n')

    for gt in gts:
        xml_file.write('    <object>\n')
        xml_file.write('        <name>' + str(gt[0]) + '</name>\n')
        xml_file.write('        <pose>Unspecified</pose>\n')
        xml_file.write('        <truncated>0</truncated>\n')
        xml_file.write('        <difficult>0</difficult>\n')
        xml_file.write('        <bndbox>\n')
        xml_file.write('            <xmin>' + str(gt[1]) + '</xmin>\n')
        xml_file.write('            <ymin>' + str(gt[2]) + '</ymin>\n')
        xml_file.write('            <xmax>' + str(gt[3]) + '</xmax>\n')
        xml_file.write('            <ymax>' + str(gt[4]) + '</ymax>\n')
        xml_file.write('        </bndbox>\n')
        xml_file.write('    </object>\n')

    xml_file.write('</annotation>')
    xml_file.close()




def get_new_img_xy(infile, image_size):
    """返回一个图片的宽、高像素"""
    im = Image.open(infile)
    (x, y) = im.size
    lv = round(x / image_size, 2) + 0.01
    x_s = x // lv
    y_s = y // lv
    # print("x_s", x_s, y_s)
    # out = im.resize((x_s, y_s), Image.ANTIALIAS)
    return x_s, y_s  # 返回缩放到image_size的大小


def resize_by_width(infile, image_size):
    """按照宽度进行所需比例缩放"""
    im = Image.open(infile)
    (x, y) = im.size
    lv = round(x / image_size, 2) + 0.01
    x_s = int(x // lv)
    y_s = int(y // lv)
    # print("x_s", x_s, y_s)
    out = im.resize((x_s, y_s), Image.ANTIALIAS)
    # plt.imshow(out)
    # plt.show()
    return out, lv


def get_bboxes(xml_path):
    tree = ET.parse(open(xml_path, 'rb'))
    root = tree.getroot()
    bboxes, cls = [], []
    for obj in root.iter('object'):
        obj_cls = obj.find('name').text
        xmlbox = obj.find('bndbox')
        xmin = float(xmlbox.find('xmin').text)
        xmax = float(xmlbox.find('xmax').text)
        ymin = float(xmlbox.find('ymin').text)
        ymax = float(xmlbox.find('ymax').text)
        bboxes.append([xmin, ymin, xmax, ymax])
        cls.append(obj_cls)
    bboxes = np.asarray(bboxes, np.int)
    return bboxes, cls


# 得到图像缩放后,xml中对应坐标的位置
def get_new_point(bboxes1, lv, d_x, d_y):
    get_list=[]
    for points in bboxes1:
        temp_list=[]
        print('------------', points)
        xmin, ymin, xmax, ymax = points

        xmin = int(xmin // lv)+d_x
        ymin = int(ymin // lv)+d_y
        xmax = int(xmax // lv)+d_x
        ymax = int(ymax // lv)+d_y

        temp_list.append(xmin)
        temp_list.append(ymin)
        temp_list.append(xmax)
        temp_list.append(ymax)

        get_list.append(temp_list)
    return get_list



# 定义图像拼接函数
def image_compose(image_colnum, image_size, image_rownum, image_names, image_save_path, x_new, y_new, xml_path,new_xml_path):
    to_image = Image.new('RGB', (image_colnum * x_new, image_rownum * y_new))  # 创建一个新图
    # plt.imshow(to_image)
    # plt.show()
    # 循环遍历,把每张图片按顺序粘贴到对应位置上
    total_num = 0

    bbox_list=[]
    cls=[]
    for y in range(1, image_rownum + 1):
        for x in range(1, image_colnum + 1):
            from_image, lv = resize_by_width(image_names[image_colnum * (y - 1) + x - 1], image_size)
            # from_image = Image.open(image_names[image_colnum * (y - 1) + x - 1]).resize((image_size,image_size ), Image.ANTIALIAS)
            to_image.paste(from_image, ((x - 1) * x_new, (y - 1) * y_new))
            # plt.imshow(to_image)
            # plt.show()
            # 处理对应的xml文件
            xml_name = image_names[image_colnum * (y - 1) + x - 1].split('\\')[-1]

            xml_path_ = os.path.join(xml_path, xml_name.replace('.jpg', '.xml'))  # 拼接后得到对应的xml路径
            bboxes1, cls1 = get_bboxes(xml_path_)
            print(bboxes1, cls1)
            d_x = (x - 1) * x_new  # 间隔距离
            d_y = (y - 1) * y_new  # 间隔距离
            if len(bboxes1)!=0:
                point = get_new_point(bboxes1, lv, d_x, d_y)
                bbox_list.append(point)
            cls = cls + cls1

            total_num += 1
            if total_num == len(image_names):
                break

    gts=[]
    if len(bbox_list)!=0:
        bboxes = np.vstack(tuple(bbox_list))
        gts = [[c] + b.tolist() for c, b in zip(cls, bboxes)]
    else:
        pass


    bboxes2xml(folder=image_save_path,
               img_name=image_save_path.split('\\')[-1].replace('.jpg',''),
               width=image_colnum * x_new, height=image_rownum * y_new,
               gts=gts, xml_save_to=new_xml_path)

    return to_image.save(image_save_path)  # 保存新图


def merge_images(image_dir_path, image_size, image_colnum, new_images_dir, xml_path,new_xml_path):
    # 获取图片集地址下的所有图片名称
    image_fullpath_list = image_dir_path  # 获取得到当前路径下所有的图片,得到列表
    print("image_fullpath_list", len(image_fullpath_list), image_fullpath_list)

    uuid_path = uuid.uuid4().hex
    new_img_path = os.path.join(new_images_dir, uuid_path)

    image_save_path = r'{}.jpg'.format(new_img_path)  # 图片转换后的地址
    print(image_save_path)

    # image_rownum = 4  # 图片间隔,也就是合并成一张图后,一共有几行
    image_rownum_yu = len(image_fullpath_list) % image_colnum
    if image_rownum_yu == 0:
        image_rownum = len(image_fullpath_list) // image_colnum
    else:
        image_rownum = len(image_fullpath_list) // image_colnum + 1

    x_list = []
    y_list = []
    for img_file in image_fullpath_list:
        img_x, img_y = get_new_img_xy(img_file, image_size)
        x_list.append(img_x)
        y_list.append(img_y)

    # print("x_list", sorted(x_list))
    # print("y_list", sorted(y_list))

    x_new = int(x_list[len(x_list) // 5 * 4])
    y_new = int(y_list[len(y_list) // 5 * 4])
    # print(" x_new, y_new", x_new, y_new)
    image_compose(image_colnum, image_size, image_rownum, image_fullpath_list, image_save_path, x_new, y_new,
                  xml_path,new_xml_path)  # 调用函数
    # for img_file in image_fullpath_list:
    #     resize_by_width(img_file,image_size)


if __name__ == '__main__':
    image_size = 320  # 每张小图片的大小

    num_in_img = 4  # 拼接的图片数量
    image_colnum = int((num_in_img) / 2)  # 合并成一张图后,一行有几个小图

    image_dir_path = r'C:\Users\GuoQingru\Desktop\printer1k\images'  # 图片集地址
    xml_path = r'C:\Users\GuoQingru\Desktop\printer1k\xml'  # 原先的xml目录

    new_images_dir = r'C:\Users\GuoQingru\Desktop\printer1k\new_images'  # 合成图像的保存目录
    new_xml_path=r'C:\Users\GuoQingru\Desktop\printer1k\new_xml'         # 生成的xml保存位置
    listdir = os.listdir(image_dir_path)
    print('^^^^^^^^^^^^^^^^',listdir)
    random.shuffle(listdir)
    print('^^^^^^^^^^^^^^^^', listdir)

    img_sum = []
    while listdir:
        tem_sum = []

        for index in range(num_in_img):
            pop = listdir.pop()
            file_path = os.path.join(image_dir_path, pop)
            tem_sum.append(file_path)
            if len(listdir) < num_in_img:
                break
        img_sum.append(tem_sum)
        if len(listdir) < num_in_img:
            break

    # print(img_sum)

    # merge_images(image_dir_path, image_size, image_colnum)

    for images in img_sum:
        if len(images) != num_in_img:
            continue
        merge_images(images, image_size, image_colnum, new_images_dir, xml_path,new_xml_path)

import os
import numpy as np
import cv2, uuid
import PIL.Image as Image
import matplotlib.pyplot as plt
import xml.etree.ElementTree as ET
import random


def bboxes2xml(folder, img_name, width, height, gts, xml_save_to):
    xml_file = open((xml_save_to + '/' + img_name + '.xml'), 'w')
    xml_file.write('<annotation>\n')
    xml_file.write('    <folder>' + folder + '</folder>\n')
    xml_file.write('    <filename>' + str(img_name) + '.jpg' + '</filename>\n')
    xml_file.write('    <size>\n')
    xml_file.write('        <width>' + str(width) + '</width>\n')
    xml_file.write('        <height>' + str(height) + '</height>\n')
    xml_file.write('        <depth>3</depth>\n')
    xml_file.write('    </size>\n')

    for gt in gts:
        xml_file.write('    <object>\n')
        xml_file.write('        <name>' + str(gt[0]) + '</name>\n')
        xml_file.write('        <pose>Unspecified</pose>\n')
        xml_file.write('        <truncated>0</truncated>\n')
        xml_file.write('        <difficult>0</difficult>\n')
        xml_file.write('        <bndbox>\n')
        xml_file.write('            <xmin>' + str(gt[1]) + '</xmin>\n')
        xml_file.write('            <ymin>' + str(gt[2]) + '</ymin>\n')
        xml_file.write('            <xmax>' + str(gt[3]) + '</xmax>\n')
        xml_file.write('            <ymax>' + str(gt[4]) + '</ymax>\n')
        xml_file.write('        </bndbox>\n')
        xml_file.write('    </object>\n')

    xml_file.write('</annotation>')
    xml_file.close()




def get_new_img_xy(infile, image_size):
    """返回一个图片的宽、高像素"""
    im = Image.open(infile)
    (x, y) = im.size
    lv = round(x / image_size, 2) + 0.01
    x_s = x // lv
    y_s = y // lv
    # print("x_s", x_s, y_s)
    # out = im.resize((x_s, y_s), Image.ANTIALIAS)
    return x_s, y_s  # 返回缩放到image_size的大小


def resize_by_width(infile, image_size):
    """按照宽度进行所需比例缩放"""
    im = Image.open(infile)
    (x, y) = im.size
    lv = round(x / image_size, 2) + 0.01
    x_s = int(x // lv)
    y_s = int(y // lv)
    # print("x_s", x_s, y_s)
    out = im.resize((x_s, y_s), Image.ANTIALIAS)
    # plt.imshow(out)
    # plt.show()
    return out, lv


def get_bboxes(xml_path):
    tree = ET.parse(open(xml_path, 'rb'))
    root = tree.getroot()
    bboxes, cls = [], []
    for obj in root.iter('object'):
        obj_cls = obj.find('name').text
        xmlbox = obj.find('bndbox')
        xmin = float(xmlbox.find('xmin').text)
        xmax = float(xmlbox.find('xmax').text)
        ymin = float(xmlbox.find('ymin').text)
        ymax = float(xmlbox.find('ymax').text)
        bboxes.append([xmin, ymin, xmax, ymax])
        cls.append(obj_cls)
    bboxes = np.asarray(bboxes, np.int)
    return bboxes, cls


# 得到图像缩放后,xml中对应坐标的位置
def get_new_point(bboxes1, lv, d_x, d_y):
    get_list=[]
    for points in bboxes1:
        temp_list=[]
        print('------------', points)
        xmin, ymin, xmax, ymax = points

        xmin = int(xmin // lv)+d_x
        ymin = int(ymin // lv)+d_y
        xmax = int(xmax // lv)+d_x
        ymax = int(ymax // lv)+d_y

        temp_list.append(xmin)
        temp_list.append(ymin)
        temp_list.append(xmax)
        temp_list.append(ymax)

        get_list.append(temp_list)
    return get_list



# 定义图像拼接函数
def image_compose(image_colnum, image_size, image_rownum, image_names, image_save_path, x_new, y_new, xml_path,new_xml_path):
    to_image = Image.new('RGB', (image_colnum * x_new, image_rownum * y_new))  # 创建一个新图
    # plt.imshow(to_image)
    # plt.show()
    # 循环遍历,把每张图片按顺序粘贴到对应位置上
    total_num = 0

    bbox_list=[]
    cls=[]
    for y in range(1, image_rownum + 1):
        for x in range(1, image_colnum + 1):
            from_image, lv = resize_by_width(image_names[image_colnum * (y - 1) + x - 1], image_size)
            # from_image = Image.open(image_names[image_colnum * (y - 1) + x - 1]).resize((image_size,image_size ), Image.ANTIALIAS)
            to_image.paste(from_image, ((x - 1) * x_new, (y - 1) * y_new))
            # plt.imshow(to_image)
            # plt.show()
            # 处理对应的xml文件
            xml_name = image_names[image_colnum * (y - 1) + x - 1].split('\\')[-1]

            xml_path_ = os.path.join(xml_path, xml_name.replace('.jpg', '.xml'))  # 拼接后得到对应的xml路径
            bboxes1, cls1 = get_bboxes(xml_path_)
            print(bboxes1, cls1)
            d_x = (x - 1) * x_new  # 间隔距离
            d_y = (y - 1) * y_new  # 间隔距离
            if len(bboxes1)!=0:
                point = get_new_point(bboxes1, lv, d_x, d_y)
                bbox_list.append(point)
            cls = cls + cls1

            total_num += 1
            if total_num == len(image_names):
                break

    gts=[]
    if len(bbox_list)!=0:
        bboxes = np.vstack(tuple(bbox_list))
        gts = [[c] + b.tolist() for c, b in zip(cls, bboxes)]
    else:
        pass


    bboxes2xml(folder=image_save_path,
               img_name=image_save_path.split('\\')[-1].replace('.jpg',''),
               width=image_colnum * x_new, height=image_rownum * y_new,
               gts=gts, xml_save_to=new_xml_path)

    return to_image.save(image_save_path)  # 保存新图


def merge_images(image_dir_path, image_size, image_colnum, new_images_dir, xml_path,new_xml_path):
    # 获取图片集地址下的所有图片名称
    image_fullpath_list = image_dir_path  # 获取得到当前路径下所有的图片,得到列表
    print("image_fullpath_list", len(image_fullpath_list), image_fullpath_list)

    uuid_path = uuid.uuid4().hex
    new_img_path = os.path.join(new_images_dir, uuid_path)

    image_save_path = r'{}.jpg'.format(new_img_path)  # 图片转换后的地址
    print(image_save_path)

    # image_rownum = 4  # 图片间隔,也就是合并成一张图后,一共有几行
    image_rownum_yu = len(image_fullpath_list) % image_colnum
    if image_rownum_yu == 0:
        image_rownum = len(image_fullpath_list) // image_colnum
    else:
        image_rownum = len(image_fullpath_list) // image_colnum + 1

    x_list = []
    y_list = []
    for img_file in image_fullpath_list:
        img_x, img_y = get_new_img_xy(img_file, image_size)
        x_list.append(img_x)
        y_list.append(img_y)

    # print("x_list", sorted(x_list))
    # print("y_list", sorted(y_list))

    x_new = int(x_list[len(x_list) // 5 * 4])
    y_new = int(y_list[len(y_list) // 5 * 4])
    # print(" x_new, y_new", x_new, y_new)
    image_compose(image_colnum, image_size, image_rownum, image_fullpath_list, image_save_path, x_new, y_new,
                  xml_path,new_xml_path)  # 调用函数
    # for img_file in image_fullpath_list:
    #     resize_by_width(img_file,image_size)


if __name__ == '__main__':
    image_size = 320  # 每张小图片的大小

    num_in_img = 9  # 拼接的图片数量
    image_colnum = int((num_in_img) / 3)  # 合并成一张图后,一行有几个小图

    image_dir_path = r'C:\Users\GuoQingru\Desktop\printer1k\images'  # 图片集地址
    xml_path = r'C:\Users\GuoQingru\Desktop\printer1k\xml'  # 原先的xml目录

    new_images_dir = r'C:\Users\GuoQingru\Desktop\printer1k\new_images'  # 合成图像的保存目录
    new_xml_path=r'C:\Users\GuoQingru\Desktop\printer1k\new_xml'         # 生成的xml保存位置
    listdir = os.listdir(image_dir_path)
    print('^^^^^^^^^^^^^^^^',listdir)
    random.shuffle(listdir)
    print('^^^^^^^^^^^^^^^^', listdir)

    img_sum = []
    while listdir:
        tem_sum = []

        for index in range(num_in_img):
            pop = listdir.pop()
            file_path = os.path.join(image_dir_path, pop)
            tem_sum.append(file_path)
            if len(listdir) < num_in_img:
                break
        img_sum.append(tem_sum)
        if len(listdir) < num_in_img:
            break

    # print(img_sum)

    # merge_images(image_dir_path, image_size, image_colnum)

    for images in img_sum:
        if len(images) != num_in_img:
            continue
        merge_images(images, image_size, image_colnum, new_images_dir, xml_path,new_xml_path)



文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
心中带点小风骚的头像心中带点小风骚普通用户
上一篇 2022年3月28日 下午2:08
下一篇 2022年3月28日

相关推荐