Python realizes the angle of xml and json files, and enhances the brightness data set

Basic idea: use your own script, after making labels through labelImg or labelme, solve the problem of too few model training data sets.

1. XML data set perspective data enhancement

angle_aug.py

import cv2
import math
import numpy as np
import os
import pdb
import xml.etree.ElementTree as ET


class ImgAugemention():
    def __init__(self):
        self. angle = 90

    # rotate the image
    def rotate_image(self, src, angle, scale=1.):
        w = src. shape[1]
        h = src. shape[0]
        # convert angle into rad
        rangle = np.deg2rad(angle) # angle in radians
        # Calculate the width and height of the new image
        nw = (abs(np. sin(rangle)*h) + abs(np. cos(rangle)*w))*scale
        nh = (abs(np. cos(rangle)*h) + abs(np. sin(rangle)*w))*scale
        # Query the rotation matrix from OpenCV
        rot_mat = cv2.getRotationMatrix2D((nw*0.5, nh*0.5), angle, scale)
        # Compute the movement from the old center to the new center
        # with the rotation
        rot_move = np.dot(rot_mat, np.array([(nw-w)*0.5, (nh-h)*0.5, 0]))
        # the move only affects the translation, so update the translation
        # part of the transform
        rot_mat[0, 2] + = rot_move[0]
        rot_mat[1, 2] + = rot_move[1]
        # map
        return cv2. warpAffine(
            src, rot_mat, (int(math. ceil(nw)), int(math. ceil(nh))),
            flags=cv2.INTER_LANCZOS4)

    def rotate_xml(self, src, xmin, ymin, xmax, ymax, angle, scale=1.):
        w = src. shape[1]
        h = src. shape[0]
        rangle = np.deg2rad(angle) # angle in radians
        # now calculate new image width and height
        # get width and height of changed image
        nw = (abs(np. sin(rangle)*h) + abs(np. cos(rangle)*w))*scale
        nh = (abs(np. cos(rangle)*h) + abs(np. sin(rangle)*w))*scale
        # ask OpenCV for the rotation matrix
        rot_mat = cv2.getRotationMatrix2D((nw*0.5, nh*0.5), angle, scale)
        # calculate the move from the old center to the new center combined
        # with the rotation
        rot_move = np.dot(rot_mat, np.array([(nw-w)*0.5, (nh-h)*0.5, 0]))
        # the move only affects the translation, so update the translation
        # part of the transform
        rot_mat[0, 2] + = rot_move[0]
        rot_mat[1, 2] + = rot_move[1]
        # rot_mat: the final rot matrix
        # get the four center of edges in the initial martix, and convert the coord
        point1 = np.dot(rot_mat, np.array([(xmin + xmax)/2, ymin, 1]))
        point2 = np.dot(rot_mat, np.array([xmax, (ymin + ymax)/2, 1]))
        point3 = np.dot(rot_mat, np.array([(xmin + xmax)/2, ymax, 1]))
        point4 = np.dot(rot_mat, np.array([xmin, (ymin + ymax)/2, 1]))
        # concat np.array
        concat = np.vstack((point1, point2, point3, point4))
        # change type
        concat = concat.astype(np.int32)
        print(concat)
        rx, ry, rw, rh = cv2.boundingRect(concat)
        return rx, ry, rw, rh

    def process_img(self, imgs_path, xmls_path, img_save_path, xml_save_path, angle_list):
        # assign the rot angles
        mun = 1
        for angle in angle_list:
            for img_name in os.listdir(imgs_path):
                # split filename and suffix
                n, s = os.path.splitext(img_name)
                # for the sake of use yol model, only process '.jpg'
                if s == ".jpg":
                    img_path = os.path.join(imgs_path, img_name)
                    img = cv2.imread(img_path)
                    rotated_img = self. rotate_image(img, angle)
                    # write image
                    # cv2.imwrite(img_save_path + n + "_" + str(angle) + "d.jpeg", rotated_img)
                    cv2.imwrite(img_save_path + "%d.jpg" % mun , rotated_img)
                    
                    print("log: [%sd] %s is processed." % (angle, img))
                    xml_url = img_name.split('.')[0] + '.xml'
                    xml_path = os.path.join(xmls_path, xml_url)
                    tree = ET. parse(xml_path)
                    root = tree. getroot()
                    for box in root.iter('bndbox'):
                        xmin = float(box. find('xmin'). text)
                        ymin = float(box. find('ymin'). text)
                        xmax = float(box. find('xmax'). text)
                        ymax = float(box. find('ymax'). text)
                        x, y, w, h = self.rotate_xml(img, xmin, ymin, xmax, ymax, angle)
                        # change the coord
                        box.find('xmin').text = str(x)
                        box.find('ymin').text = str(y)
                        box.find('xmax').text = str(x + w)
                        box.find('ymax').text = str(y + h)
                        box.set('updated', 'yes')
                    # write into new xml
                    # tree.write(xml_save_path + n + "_" + str(angle) + "d.xml")
                    tree.write(xml_save_path + "%d.xml" % mun)
                    mun + = 1
                print("[%s] %s is processed." % (angle, img_name))


if __name__ == '__main__':
    img_aug = ImgAugemention()
    imgs_path = '/home/ubuntu/ball_img/img/'
    img_save_path = '/home/ubuntu/ball_img/angle_img/'

    xmls_path = '/home/ubuntu/ball_img/xml/'
    xml_save_path = '/home/ubuntu/ball_img/angle_xml/'
    # Degrees to rotate all images
    angle_list = [-2, -1.5, -1, -0.8, -0.5, -0.2, 0, 0.2, 0.5, 0.8, 1, 1.5, 2] # angle
    img_aug.process_img(imgs_path, xmls_path, img_save_path, xml_save_path, angle_list)

2. XML data set brightness data enhancement

light_aug.py

# coding=utf-8
import os
import cv2
import math
import numpy as np
import shut-off
from PIL import Image
from PIL import ImageEnhance

"""
1. Contrast: the brightness under the white screen (the brightest time) divided by the brightness under the black screen (the darkest time);
2. Color saturation: chroma divided by lightness refers to the vividness of the color, also known as the purity of the color;
3. Hue: Adjusting in the negative direction will show red, and adjusting in the positive direction will increase yellow. Good for fine-tuning skin tone objects;
4. Sharpness: It is an index that reflects the sharpness of the image plane and the sharpness of the image edge.
"""


def compute(img):
    per_image_Rmean = []
    per_image_Gmean = []
    per_image_Bmean = []
    per_image_Bmean.append(np.mean(img[:, :, 0]))
    per_image_Gmean.append(np.mean(img[:, :, 1]))
    per_image_Rmean.append(np.mean(img[:, :, 2]))
    R_mean = np.mean(per_image_Rmean)
    G_mean = np.mean(per_image_Gmean)
    B_mean = np.mean(per_image_Bmean)
    return math.sqrt(0.241 * (R_mean ** 2) + 0.691 * (G_mean ** 2) + 0.068 * (B_mean ** 2))

def fun_color(image, coefficient, path_save):
    # Chroma, the enhancement factor is 1.0 is the original image
    # Chroma Boost 1.5
    # Chroma reduction by 0.8
    enh_col = ImageEnhance. Color(image)
    image_colored1 = enh_col.enhance(coefficient)
    image_colored1. save(path_save)


def fun_Contrast(image, coefficient, path_save):
    # Contrast, the enhancement factor is 1.0 is the original picture
    # Contrast enhancement 1.5
    # Contrast reduction 0.8
    enh_con = ImageEnhance. Contrast(image)
    image_contrasted1 = enh_con.enhance(coefficient)
    image_contrasted1. save(path_save)

def fun_Sharpness(image, coefficient, path_save):
    # Sharpness, the enhancement factor is 1.0 is the original picture
    # sharpness enhancement 3
    # Reduce sharpness by 0.8
    enh_sha = ImageEnhance. Sharpness(image)
    image_sharped1 = enh_sha.enhance(coefficient)
    image_sharped1. save(path_save)
def fun_bright(image, coefficient, path_save):
    # brighten by 1.5
    # darken by 0.8
    # Brightness enhancement, an enhancement factor of 0.0 will produce a black image; a value of 1.0 will keep the original image.
    enh_bri = ImageEnhance. Brightness(image)
    image_brightened1 = enh_bri.enhance(coefficient)
    image_brightened1. save(path_save)
'''
def show_all():
    file_root = "C:/Users/xx/Desktop/kaiguan/image/"
    xml_root = "C:/Users/xx/Desktop/kaiguan/xml/"
    save_root = "C:/Users/xx/Desktop/kaiguan_aug/JPEGImages/"
    xml_save = "C:/Users/xx/Desktop/kaiguan_aug/Annotations/"
    list_file = os.listdir(file_root)
    cnt = 0
    for img_name in list_file:
        cnt + = 1
        print("cnt=%d,img_name=%s" % (cnt, img_name))
        path = file_root + img_name
        name = img_name. replace(".jpg", "")
        image = Image. open(path)
        list_coe = [0.5,1,3]
        for val in list_coe:
            # Brightness
            path_save_bright = save_root + name + "_bri_" + str(val) + ".jpg"
            fun_bright(image, val, path_save_bright)

            # hue
            path_save_color = save_root + name + "_color_" + str(val) + ".jpg"
            fun_color(image, val, path_save_color)

            # contrast
            path_save_contra = save_root + name + "_contra_" + str(val) + ".jpg"
            fun_Contrast(image, val, path_save_contra)

            # sharpness
            path_save_sharp = save_root + name + "_sharp_" + str(val) + ".jpg"
            fun_Sharpness(image, val, path_save_sharp)
'''

def my_aug():
    file_root = '/home/ubuntu/ball_img/angle_img/'
    save_root = '/home/ubuntu/ball_img/light_img/'
   
    xml_root = '/home/ubuntu/ball_img/angle_xml/'
    xml_save = '/home/ubuntu/ball_img/light_xml/'
    list_file = os.listdir(file_root)
    cnt = 0
    mun = 1041
    for img_name in list_file:
        cnt + = 1
        print("cnt=%d,img_name=%s" % (cnt, img_name))
        path = file_root + img_name
        name = img_name. replace(".jpg", "")
        image = Image. open(path)
        img = cv2.imread(path)
        mean_1 = compute(img)
        cof = 0.0
        if mean_1 != 0:
            cof = 0.7
        # if mean_1 < 40:
        # cof = 0.8
        # elif mean_1 < 50:
        # cof = 0.8
        # elif mean_1 < 60:
        # cof = 0.8
        # elif mean_1 < 70:
        # cof = 0.8
        # elif mean_1 < 80:
        # cof = 0.8
        # elif mean_1 < 90:
        # cof = 0.8
        # elif mean_1 < 100:
        # cof = 0.8
        # elif mean_1 < 110:
        # cof = 0.3
        # elif mean_1 > 130:
        # cof = 0
        else:
             cof = 0.81

        cof_contrast = 0.0
        if cof>1:
            cof_contrast = 1.5
        else:
            cof_contrast = 0.9
        xmlpath = xml_root + name + '.xml'
        
        # path_save_bright = save_root + name + '.jpg'
        # path_save_bright_xml = xml_save + name + '.jpg'
        path_save_bright = save_root + '%d.jpg' % mun
        path_save_bright_xml = xml_save + '%d.jpg' % mun
        mun + = 1
        shutil.copy(xmlpath,path_save_bright_xml.replace(".jpg", ".xml"))
        fun_bright(image, cof, path_save_bright)

        # path_save_sharp = save_root + name + "_sharp_" + str(3) + '.jpg'
        # path_save_sharp_xml = xml_save + name + "_sharp_" + str(3) + '.jpg'
        # shutil.copy(xmlpath, path_save_sharp_xml.replace(".jpg", ".xml"))
        # fun_Sharpness(image, 2, path_save_sharp)

        # path_save_contra = save_root + name + "_contra_" + str(cof_contrast) + ".jpg"
        # path_save_contra_xml = xml_save + name + "_contra_" + str(cof_contrast) + ".jpg"
        # shutil.copy(xmlpath, path_save_contra_xml.replace(".jpg", ".xml"))
        # fun_Contrast(image, cof_contrast, path_save_contra)

        # path_save_color = save_root + name + "_color_" + str(0.5) + ".jpg"
        # path_save_color_xml = xml_save + name + "_color_" + str(0.5) + ".jpg"
        # shutil.copy(xmlpath,path_save_color_xml.replace(".jpg", ".xml"))
        # fun_color(image, 1.5, path_save_color)


if __name__ == "__main__":

    #show_all()
    my_aug()

Three, json data set angle data enhancement

json_data_aug.py

# -*- coding: utf-8 -*-
import os
import sys
import json
import io
import random
import re
import cv2
import numpy as np
from random import choice
import math
 
source_path = r'datasets'
destination_path = r'data_aug'

      


# angle=[]
# for item in range(0,-10,-2):
# angle.append(item)

angle = [-4,-3,-2,-1,0,1,2,3,4] # angle setting

for angle_item in angle:
    article_info = {}
    data_json = json. loads(json. dumps(article_info))
    data_json['version'] = '5.0.1'
    data_json['flags'] = {}
 
    data_json["lineColor"] = [
        0,
        255,
        0,
        128
    ]
    data_json["fillColor"] = [
        255,
        0,
        0,
        128
    ]
 
 
    def file_name(file_dir):
        L = []
        for root, dirs, files in os. walk(file_dir):
            for file in files:
                if os.path.splitext(file)[1] == '.json':
                    L.append(os.path.join(root, file))
            return L
 
 
    def rotation_point(img, angle, pts):
        cols = img. shape[1]
        rows = img. shape[0]
        M = cv2.getRotationMatrix2D((cols / 2, rows / 2), angle, 1)
        heightNew = int(cols * math. fabs(math. sin(math. radians(angle))) + rows * math. fabs(math. cos(math. radians(angle))))
        widthNew = int(rows * math. fabs(math. sin(math. radians(angle))) + cols * math. fabs(math. cos(math. radians(angle))))
        M[0, 2] + = (widthNew - cols) / 2
        M[1, 2] + = (heightNew - rows) / 2
        img = cv2. warpAffine(img, M, (widthNew, heightNew))
        pts = cv2.transform(np.asarray(pts, dtype=np.float64).reshape((-1, 1, 2)), M)
        
        return img,pts
    
    
    def rotate_image(img, angle, pts, scale=1.):
        w = img. shape[1]
        h = img. shape[0]
        
        rangle = np.deg2rad(angle)
        
        nw = (abs(np. sin(rangle)*h) + abs(np. cos(rangle)*w))*scale
        nh = (abs(np. cos(rangle)*h) + abs(np. sin(rangle)*w))*scale
        
        rot_mat = cv2.getRotationMatrix2D((nw*0.5, nh*0.5), angle, scale)
        
        rot_move = np.dot(rot_mat, np.array([(nw-w)*0.5, (nh-h)*0.5,0]))
        
        rot_mat[0, 2] + = rot_move[0]
        rot_mat[1, 2] + = rot_move[1]
        
        img = cv2.warpAffine(img, rot_mat, (int(math.ceil(nw)), int(math.ceil(nh))), flags=cv2.INTER_LANCZOS4)
        pts = cv2.transform(np.asarray(pts, dtype=np.float64).reshape((-1, 1, 2)), rot_mat)
        # cv2.imwrite("test/0.jpg", img)
        return img,pts
    


    for name in enumerate(file_name(source_path)):
        shape_json = []
        m_path = name[1]
        dir = os.path.dirname(m_path)
        file_json = io.open(m_path, 'r', encoding='utf-8')
        json_data = file_json. read()
        data = json. loads(json_data)
        data_json['imageData'] = None
        data_name = data['imagePath']
        data_path = os.path.join(dir,data_name)
        object_name = os.path.splitext(data['imagePath'])[0]
        data_new_json_name=None
        list_point=[]
        for i in range(len(data['shapes'])):
            m_name_0 = data['shapes'][i]['label']
            print('m_name_0=', m_name_0)
            item_point = []
            for j in range(len(data['shapes'][i]['points'])):
                print(data['shapes'][i]['points'][j][0],data['shapes'][i]['points'][j][1])
                item_point.append([data['shapes'][i]['points'][j][0],data['shapes'][i]['points'][j][1]])
 
 
 
            data_json_fill_color=None
            data_json_rec = data['shapes'][i]['shape_type']
            img = cv2.imread(data_path)
 
            # im_rotate,item_point = rotation_point(img, angle_item,np.asarray(item_point))
            im_rotate, item_point = rotate_image(img, angle_item, np.asarray(item_point))
            item_point = np. squeeze(item_point). tolist()
            print(item_point)
            (filename, extension) = os.path.splitext(data_name)
            data_new_picture_name = os.path.join(destination_path ,filename + ".".join([str(angle_item), "jpg"]))
            data_new_json_name = os.path.join(destination_path , filename + ".".join([str(angle_item), "json"]))
            data_json['imagePath'] = filename + ".".join([str(angle_item) , "jpg"])
            cv2.imwrite(data_new_picture_name, im_rotate)
            im_rotate = cv2.imread(data_new_picture_name)
            data_json['imageWidth'] = im_rotate. shape[1]
            data_json['imageHeight'] = im_rotate. shape[0]
            shape_json_item = {"label": m_name_0,
                               "points": item_point, "shape_type": data_json_rec}
            shape_json.append(shape_json_item)
        data_json['shapes'] = shape_json
        data_info = json. dumps(data_json, ensure_ascii=False)
        fp = open(data_new_json_name, "w + ")
        json.dump(data_info, fp, ensure_ascii=False, indent=4)
        fp. close()
        fp = open(data_new_json_name, "r")
        for x in fp. readlines():
            y = x.replace(""", """)
            z = y.replace(""{", "{")
            w = z. replace("}"", "}")
            fp. close()
            fp = open(data_new_json_name, "w + ")
            fp. write(w)
            fp. close()
    
    for file in os.listdir(destination_path):
        n , s = os.path.splitext(file)
        if s == ".json":
            json_path = os.path.join(destination_path, file)
            # json_ = json. dumps(json_file)
            with open(json_path, 'r') as json_file:
                data = json. load(json_file)
                data_ = json. dumps(data, indent=4)
                with open(json_path, 'w') as f_out:
                    f_out.write(data_)

Reference article:

1. Deep learning data enhancement, while modifying the xml file (python)_python data enhancement code and automatically updating annotations_Summer’s Huan’s Blog-CSDN Blog

2. 42. Use k3det in mmrotate for rotating target detection, and perform mnn deployment and ncnn deployment_sxj731533730’s blog-CSDN blog