Mosaic数据增强返回图片和对应的xml.py

简介: Mosaic数据增强返回图片和对应的xml.py

网上很少有mosaic图像增强后的 图片与XML,本文直接提供你所需要的代码,可视化和具体修改见链接。

高云飞.jpeg


from PIL import Image, ImageDraw

import numpy as np

from matplotlib.colors import rgb_to_hsv, hsv_to_rgb

import math


import xml.dom.minidom

import numpy as np

import sys

import cv2

import glob

import os

import xml.dom.minidom

import argparse

import random


from xml.etree.ElementTree import ElementTree,Element,parse

from xml.dom import minidom

import xml.etree.ElementTree as ET

import xml.dom.minidom as DOC


image_path = “你的图片路径”

path_origin_xml = “你的XML路径”

out_root_path (img或者XML 自己定义)= “输出路径”


def readxml(image_file):

# file_path = os.path.join(xml_path, xmlFile)

# dom = parse(xml_path)

# root = dom.getroot()

#xmls_list = os.listdir(path_origin_xml)

#nums = len(xmls_list)


#coords = list()
#for i in range(nums):
#xml_path = os.path.join(path_origin_xml, image_file.replace('jpg', 'xml'))
if image_file.split(".")[1] == 'png':
    xml_path = os.path.join(path_origin_xml, image_file.replace('png', 'xml'))
else:
    xml_path = os.path.join(path_origin_xml, image_file.replace('jpg', 'xml'))
root = ET.parse(xml_path).getroot()
bb = []
for obj in root.iter('object'):  # 获取object节点中的name子节点
    bbox = obj.find('bndbox')
    xmin = int(float(bbox.find('xmin').text.strip()))
    ymin = int(float(bbox.find('ymin').text.strip()))
    xmax = int(float(bbox.find('xmax').text.strip()))
    ymax = int(float(bbox.find('ymax').text.strip()))


####-----------------非常重要----------------######## 下面的1需要修改 具体修改见链接

bb.append(np.array([xmin, ymin, xmax, ymax, 1]))

return np.array(bb)


def CreatXml(imgPath, results, xmlPath):

img = cv2.imread(imgPath)

imgSize = img.shape

imgName = imgPath.split(‘/’)[-1]


impl = xml.dom.minidom.getDOMImplementation()
dom = impl.createDocument(None, 'annotation', None)
root = dom.documentElement
folder = dom.createElement('folder')
root.appendChild(folder)
name_folfer = dom.createTextNode('Unknown')
folder.appendChild(name_folfer)
filename = dom.createElement('filename')
root.appendChild(filename)
name_img = dom.createTextNode(os.path.splitext(imgName)[0])
filename.appendChild(name_img)
filepath = dom.createElement('path')
root.appendChild(filepath)
path_img = dom.createTextNode(imgPath)
filepath.appendChild(path_img)
source = dom.createElement('source')
root.appendChild(source)
database = dom.createElement('database')
database_name = dom.createTextNode('Unknown')
database.appendChild(database_name)
source.appendChild(database)
img_size = dom.createElement('size')
root.appendChild(img_size)
width = dom.createElement('width')
width_num = dom.createTextNode(str(int(imgSize[1])))
width.appendChild(width_num)
height = dom.createElement('height')
height_num = dom.createTextNode(str(int(imgSize[0])))
height.appendChild(height_num)
depth = dom.createElement('depth')
depth_num = dom.createTextNode(str(int(imgSize[2])))
depth.appendChild(depth_num)
img_size.appendChild(width)
img_size.appendChild(height)
img_size.appendChild(depth)
segmented = dom.createElement('segmented')
root.appendChild(segmented)
segmented_num = dom.createTextNode('0')
segmented.appendChild(segmented_num)
for i in range(len(results)):
    img_object = dom.createElement('object')
    root.appendChild(img_object)
    label_name = dom.createElement('name')
    namecls = dom.createTextNode(results[i]['name'])
    label_name.appendChild(namecls)
    pose = dom.createElement('pose')
    pose_name = dom.createTextNode('Unspecified')
    pose.appendChild(pose_name)
    truncated = dom.createElement('truncated')
    truncated_num = dom.createTextNode('0')
    truncated.appendChild(truncated_num)
    difficult = dom.createElement('difficult')
    difficult_num = dom.createTextNode('0')
    difficult.appendChild(difficult_num)
    bndbox = dom.createElement('bndbox')
    xmin = dom.createElement('xmin')
    xmin_num = dom.createTextNode(str(int(results[i]['bbox'][0])))
    xmin.appendChild(xmin_num)
    ymin = dom.createElement('ymin')
    ymin_num = dom.createTextNode(str(int(results[i]['bbox'][1])))
    ymin.appendChild(ymin_num)
    xmax = dom.createElement('xmax')
    xmax_num = dom.createTextNode(str(int(results[i]['bbox'][2])))
    xmax.appendChild(xmax_num)
    ymax = dom.createElement('ymax')
    ymax_num = dom.createTextNode(str(int(results[i]['bbox'][3])))
    ymax.appendChild(ymax_num)
    bndbox.appendChild(xmin)
    bndbox.appendChild(ymin)
    bndbox.appendChild(xmax)
    bndbox.appendChild(ymax)
    img_object.appendChild(label_name)
    img_object.appendChild(pose)
    img_object.appendChild(truncated)
    img_object.appendChild(difficult)
    img_object.appendChild(bndbox)
f = open(xmlPath, 'w')
dom.writexml(f, addindent='  ', newl='\n')
f.close()


def get_result(box_data):

classes = [‘object’, ‘scissors’, ‘lighter’, ‘zippooil’, ‘pressure’,

‘slingshot’, ‘handcuffs’, ‘nailpolish’, ‘powerbank’,

‘firecrackers’]

results = []

for obj in box_data:

result = {}

obj = [int(i) for i in obj]

box = obj[:4]

name = classes[obj[-1]]

result[“name”] = name

result[“bbox”] = box

results.append(result)

return results


def rand(a=0, b=1):

return np.random.rand()*(b-a) + a


def merge_bboxes(bboxes, cutx, cuty):


merge_bbox = []
for i in range(len(bboxes)):
    for box in bboxes[i]:
        tmp_box = []
        x1,y1,x2,y2 = box[0], box[1], box[2], box[3]
        if i == 0:
            if y1 > cuty or x1 > cutx:
                continue
            if y2 >= cuty and y1 <= cuty:
                y2 = cuty
                if y2-y1 < 5:
                    continue
            if x2 >= cutx and x1 <= cutx:
                x2 = cutx
                if x2-x1 < 5:
                    continue
        if i == 1:
            if y2 < cuty or x1 > cutx:
                continue
            if y2 >= cuty and y1 <= cuty:
                y1 = cuty
                if y2-y1 < 5:
                    continue
            if x2 >= cutx and x1 <= cutx:
                x2 = cutx
                if x2-x1 < 5:
                    continue
        if i == 2:
            if y2 < cuty or x2 < cutx:
                continue
            if y2 >= cuty and y1 <= cuty:
                y1 = cuty
                if y2-y1 < 5:
                    continue
            if x2 >= cutx and x1 <= cutx:
                x1 = cutx
                if x2-x1 < 5:
                    continue
        if i == 3:
            if y1 > cuty or x2 < cutx:
                continue
            if y2 >= cuty and y1 <= cuty:
                y2 = cuty
                if y2-y1 < 5:
                    continue
            if (x2 >= cutx) and (x1 <= cutx):
                x1 = cutx
                if x2-x1 < 5:
                    continue
        tmp_box.append(x1)
        tmp_box.append(y1)
        tmp_box.append(x2)
        tmp_box.append(y2)
        tmp_box.append(box[-1])
        merge_bbox.append(tmp_box)
return merge_bbox


def get_random_data(annotation_line, input_shape, random=True, hue=.1, sat=1.5, val=1.5, proc_img=True):

‘’‘random preprocessing for real-time data augmentation’‘’

print(“image:”,annotation_line)

h, w = input_shape

min_offset_x = 0.4

min_offset_y = 0.4

scale_low = 1-min(min_offset_x,min_offset_y)

scale_high = scale_low+0.2


image_datas = []
box_datas = []
index = 0
place_x = [0,0,int(w*min_offset_x),int(w*min_offset_x)]
place_y = [0,int(h*min_offset_y),int(w*min_offset_y),0]
for line in annotation_line:
    # 每一行进行分割
    #line_content = line.split()
    # 打开图片
    image = Image.open(os.path.join(image_path,line))
    image = image.convert("RGB")
    # 图片的大小
    iw, ih = image.size
    box = readxml(line)
    # 保存框的位置
    #box = np.array([np.array(list(map(int,box.split(',')))) for box in line_content[1:]])
    # image.save(str(index)+".jpg")
    # 是否翻转图片
    flip = rand()<.5
    if flip and len(box)>0:
        image = image.transpose(Image.FLIP_LEFT_RIGHT)
        box[:, [0,2]] = iw - box[:, [2,0]]
    # 对输入进来的图片进行缩放
    new_ar = w/h
    scale = rand(scale_low, scale_high)
    if new_ar < 1:
        nh = int(scale*h)
        nw = int(nh*new_ar)
    else:
        nw = int(scale*w)
        nh = int(nw/new_ar)
    image = image.resize((nw,nh), Image.BICUBIC)
    # 进行色域变换
    hue = rand(-hue, hue)
    sat = rand(1, sat) if rand()<.5 else 1/rand(1, sat)
    val = rand(1, val) if rand()<.5 else 1/rand(1, val)
    x = rgb_to_hsv(np.array(image)/255.)
    x[..., 0] += hue
    x[..., 0][x[..., 0]>1] -= 1
    x[..., 0][x[..., 0]<0] += 1
    x[..., 1] *= sat
    x[..., 2] *= val
    x[x>1] = 1
    x[x<0] = 0
    image = hsv_to_rgb(x)
    image = Image.fromarray((image*255).astype(np.uint8))
    # 将图片进行放置,分别对应四张分割图片的位置
    dx = place_x[index]
    dy = place_y[index]
    new_image = Image.new('RGB', (w,h), (128,128,128))
    new_image.paste(image, (dx, dy))
    image_data = np.array(new_image)/255
    index = index + 1
    box_data = []
    # 对box进行重新处理
    if len(box)>0:
        np.random.shuffle(box)
        box[:, [0,2]] = box[:, [0,2]]*nw/iw + dx
        box[:, [1,3]] = box[:, [1,3]]*nh/ih + dy
        box[:, 0:2][box[:, 0:2]<0] = 0
        box[:, 2][box[:, 2]>w] = w
        box[:, 3][box[:, 3]>h] = h
        box_w = box[:, 2] - box[:, 0]
        box_h = box[:, 3] - box[:, 1]
        box = box[np.logical_and(box_w>1, box_h>1)]
        box_data = np.zeros((len(box),5))
        box_data[:len(box)] = box
    image_datas.append(image_data)
    box_datas.append(box_data)
    img = Image.fromarray((image_data*255).astype(np.uint8))
    #for j in range(len(box_data)):
    #    thickness = 3
    #    left, top, right, bottom = box_data[j][0:4]
    #    draw = ImageDraw.Draw(img)
    #    for i in range(thickness):
    #        draw.rectangle([left + i, top + i, right - i, bottom - i],outline=(255,255,255))
    #img.show()
# 将图片分割,放在一起
cutx = np.random.randint(int(w*min_offset_x), int(w*(1 - min_offset_x)))
cuty = np.random.randint(int(h*min_offset_y), int(h*(1 - min_offset_y)))
print("cutx:",cutx)
print("cuty:",cuty)
print("h:",h)
print("w:",w)
new_image = np.zeros([h,w,3])
new_image[:cuty, :cutx, :] = image_datas[0][:cuty, :cutx, :]
new_image[cuty:, :cutx, :] = image_datas[1][cuty:, :cutx, :]
new_image[cuty:, cutx:, :] = image_datas[2][cuty:, cutx:, :]
new_image[:cuty, cutx:, :] = image_datas[3][:cuty, cutx:, :]
# 对框进行进一步的处理
new_boxes = merge_bboxes(box_datas, cutx, cuty)
return new_image, new_boxes


def normal_(annotation_line, input_shape):

‘’‘random preprocessing for real-time data augmentation’‘’

line = annotation_line.split()

image = Image.open(line[0])

box = np.array([np.array(list(map(int,box.split(‘,’)))) for box in line[1:]])


iw, ih = image.size
image = image.transpose(Image.FLIP_LEFT_RIGHT)
box[:, [0,2]] = iw - box[:, [2,0]]
return image, box


if name == “main”:

lines = []
for filename in os.listdir(os.path.join(image_path, '')):
    if filename.endswith(".jpg") or filename.endswith(".JPG") or filename.endswith(".png"):
        lines.append(filename)
print(lines)
list1 = list(range(0,len(lines)))
print("list1:",list1)
for j in range(5000):
    #a = np.random.randint(0,len(lines))
    #line = lines[a:a+4]
    tem = []
    for i in random.sample(list1, 4):
        tem.append(lines[i])
    line = tem
    #try:
    image_data, box_data = get_random_data(line,[1000,1000])
    img = Image.fromarray((image_data*255).astype(np.uint8))
    img_path = "你的保存图像路径" % j
    img.save(img_path)
    results = get_result(box_data)
    xml_path = "你的保存XML路径l" % j
    CreatXml(img_path, results, xml_path)
    #except:
        #continue

相关文章
|
6月前
|
XML 前端开发 数据格式
请描述如何使用`BeautifulSoup`或其他类似的库来解析 HTML 或 XML 数据。
【2月更文挑战第22天】【2月更文挑战第67篇】请描述如何使用`BeautifulSoup`或其他类似的库来解析 HTML 或 XML 数据。
71 2
|
6月前
|
XML 存储 JSON
Python学习 -- 常用数据交换格式(CSV、XML、JSON)
Python学习 -- 常用数据交换格式(CSV、XML、JSON)
83 0
|
XML 存储 JSON
Python学习 -- 常用数据交换格式(CSV、XML、JSON)
Python学习 -- 常用数据交换格式(CSV、XML、JSON)
104 0
|
2月前
|
XML 存储 JSON
Twaver-HTML5基础学习(19)数据容器(2)_数据序列化_XML、Json
本文介绍了Twaver HTML5中的数据序列化,包括XML和JSON格式的序列化与反序列化方法。文章通过示例代码展示了如何将DataBox中的数据序列化为XML和JSON字符串,以及如何从这些字符串中反序列化数据,重建DataBox中的对象。此外,还提到了用户自定义属性的序列化注册方法。
44 1
|
3月前
|
XML 数据采集 存储
使用Java和XPath在XML文档中精准定位数据
在数据驱动的时代,从复杂结构中精确提取信息至关重要。XML被广泛用于数据存储与传输,而XPath则能高效地在这些文档中导航和提取数据。本文深入探讨如何使用Java和XPath精准定位XML文档中的数据,并通过小红书的实际案例进行分析。首先介绍了XML及其挑战,接着阐述了XPath的优势。然后,提出从大型XML文档中自动提取特定产品信息的需求,并通过代理IP技术、设置Cookie和User-Agent以及多线程技术来解决实际网络环境下的数据抓取问题。最后,提供了一个Java示例代码,演示如何集成这些技术以高效地从XML源中抓取数据。
104 7
使用Java和XPath在XML文档中精准定位数据
|
6月前
|
XML 前端开发 数据格式
BeautifulSoup 是一个 Python 库,用于从 HTML 和 XML 文件中提取数据
【5月更文挑战第10天】BeautifulSoup 是 Python 的一个库,用于解析 HTML 和 XML 文件,即使在格式不规范的情况下也能有效工作。通过创建 BeautifulSoup 对象并使用方法如 find_all 和 get,可以方便地提取和查找文档中的信息。以下是一段示例代码,展示如何安装库、解析 HTML 数据以及打印段落、链接和特定类名的元素。BeautifulSoup 还支持更复杂的查询和文档修改功能。
97 1
|
30天前
|
XML Web App开发 数据格式
HTML 页面显示 XML 数据
10月更文挑战第2天
|
1月前
|
XML JSON 前端开发
C#使用HttpClient四种请求数据格式:json、表单数据、文件上传、xml格式
C#使用HttpClient四种请求数据格式:json、表单数据、文件上传、xml格式
317 0
|
3月前
|
XML JSON Java
使用IDEA+Maven搭建整合一个Struts2+Spring4+Hibernate4项目,混合使用传统Xml与@注解,返回JSP视图或JSON数据,快来给你的SSH老项目翻新一下吧
本文介绍了如何使用IntelliJ IDEA和Maven搭建一个整合了Struts2、Spring4、Hibernate4的J2EE项目,并配置了项目目录结构、web.xml、welcome.jsp以及多个JSP页面,用于刷新和学习传统的SSH框架。
82 0
使用IDEA+Maven搭建整合一个Struts2+Spring4+Hibernate4项目,混合使用传统Xml与@注解,返回JSP视图或JSON数据,快来给你的SSH老项目翻新一下吧
|
6月前
|
XML 机器学习/深度学习 JSON
在火狐浏览器调ajax获取json数据时,控制台提示“XML 解析错误:格式不佳”。
在火狐浏览器调ajax获取json数据时,控制台提示“XML 解析错误:格式不佳”。
76 0
在火狐浏览器调ajax获取json数据时,控制台提示“XML 解析错误:格式不佳”。