python数据扩充:gamma+重采样+旋转+镜像

训练的时候因为数据出现问题,把做数据扩充的重新整理了一下,应该一步步检查的。

1、gamma变换调节图像对比度

"""
=================================
Gamma and log contrast adjustment
=================================
This example adjusts image contrast by performing a Gamma and a Logarithmic
correction on the input image.

"""

import numpy as np
import cv2
import math
from matplotlib import pyplot as plt

from skimage import exposure
import shutil
import os

def gamma_corrected(savefolder, imgfolder, img, para):

	#pare > 1 Increase brightness
	#pare < 1 Decrease brightness
	imgsavefolder = savefolder + '/JPEG/'
	xmlsavefolder = savefolder + '/XML/'

	if not os.path.exists(imgsavefolder):
		os.makedirs(imgsavefolder)

	if not os.path.exists(xmlsavefolder):
		os.makedirs(xmlsavefolder)

	xmlfolder = imgfolder.replace('JPEG', 'XML')
	xmlfile = xmlfolder + img.replace('jpg', 'xml')

	origimgpath = os.path.join(imgfolder,img)

	im = cv2.imread(os.path.join(imgfolder,img))

	for p in para:
		try:
			gamma_img = exposure.adjust_gamma(im, p)

			gamma_imgsavepath = imgsavefolder + 'g' + str(p) + '_' + img
			orig_imgsavepath = imgsavefolder + img

			gamma_xmlsavepath = xmlsavefolder + 'g' + str(p) + '_' + img.replace('jpg', 'xml')
			orig_xmlsavepath = xmlsavefolder + img.replace('jpg', 'xml')
			
			#save gamma image
			cv2.imwrite(gamma_imgsavepath, gamma_img)
			#sava original image
			shutil.copy(origimgpath,orig_imgsavepath)
			#save gamma xml
			shutil.copy (xmlfile, gamma_xmlsavepath)
			#save original xml
			shutil.copy(xmlfile, orig_xmlsavepath)
		
		except Exception as e:
			orig_imgsavepath = imgsavefolder + img
			orig_xmlsavepath = xmlsavefolder + img.replace('jpg', 'xml')

			#sava original image
			shutil.copy(origimgpath,orig_imgsavepath)
			#save original xml
			shutil.copy(xmlfile, orig_xmlsavepath)
			raise
#log	
# def logarithmic_corrected():
# 	logarithmic_corrected = exposure.adjust_log(img, 0.9)
# 	pass

##Gamma
para = [0.6, 1.5]

img_org_folder = '/Desktop/power_traindata/JPEG/'
save_folder = '/PowerDetectTrainDataExp/Gamma/'

if not os.path.exists(save_folder):
	os.makedirs(save_folder)
	os.makedirs(save_folder + 'JPEG')
	os.makedirs(save_folder + 'XML')

for img in os.listdir(img_org_folder):
	gamma_corrected(save_folder, img_org_folder, img, para)



## Logarithmic

2、上下采样:

#coding:utf-8

import os
import cv2
import numpy as np

try:
	import xml.etree.cElementTree as ET
except ImportEroor:
	import xml.etree.ElementTree as ET
import copy,random
# ==================down sample=========
def img_downsample():
	JPEGImages = os.path.join(folder, 'JPEG')
	saveJPEGImages = os.path.join(save_folder, 'JPEG')
	saveJPEGImages.replace('\\', '/')
	
	if not os.path.exists(saveJPEGImages):
		os.makedirs(saveJPEGImages)
	
	Annotations = os.path.join(folder, 'XML')
	saveAnnotations = os.path.join(save_folder, 'XML')
	saveAnnotations.replace('\\', '/')
	
	if not os.path.exists(saveAnnotations):
		os.makedirs(saveAnnotations)
	
	scales = None
	
	for imgfile in os.listdir(JPEGImages):
		#images
		img = cv2.imread(os.path.join(JPEGImages,imgfile))
		scales = [random.uniform(4,20)*0.1 for _ in range(2)]
		
		for i,scale in enumerate(scales):
			img_downsampled = cv2.resize(img,(int(scale*img.shape[1]),int(scale*img.shape[0])))
			new_name = 's' + str(i) + '_' + imgfile
			# print(new_name)
			cv2.imwrite(os.path.join(saveJPEGImages,new_name),img_downsampled)

			xmlfile = imgfile.replace('jpg','xml')
			Anno_Path = os.path.join(Annotations,xmlfile)

			tree = ET.parse(Anno_Path.replace('\\', '/'))
			root = tree.getroot()
			for obj in root.findall('object'):
				bndbox = obj.find('bndbox')

				xmin = bndbox.find('xmin').text
				ymin = bndbox.find('ymin').text
				xmax = bndbox.find('xmax').text
				ymax = bndbox.find('ymax').text

				bndbox.find('xmin').text = str(int(int(xmin)*scale))
				bndbox.find('ymin').text = str(int(int(ymin)*scale))
				bndbox.find('xmax').text = str(int(int(xmax)*scale))
				bndbox.find('ymax').text = str(int(int(ymax)*scale))

				assert(((int(xmax) - int(xmin))*scale)>0)
				assert(((int(ymax) - int(ymin))*scale)>0)
		
			filename = tree.find('filename')
			filename.text = new_name
			size = tree.find('size')
			height = size.find('height')
			width = size.find('width')
			height.text = str(int(float(height.text)*scale))
			width.text = str(int(float(width.text)*scale))
			tree.write(os.path.join(saveAnnotations,new_name[:-4]+'.xml'))

if __name__=='__main__': 
	global folder, save_folder
	folder = '/PowerDetectTrainDataExp/Gamma/'
	save_folder = '/PowerDetectTrainDataExp/Sampled/'
	img_downsample()

3、旋转:0,90,180, 270

# coding:utf-8

import cv2
import os
import numpy as np
import math
import copy
try:
    import xml.etree.cElementTree as ET
except ImportError:
    import xml.etree.ElementTree as ET

def rotate_about_center(src, angle, scale=1.):
    w = src.shape[1]
    h = src.shape[0]

    rangle = np.deg2rad(angle) #angle in radians
    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)# rotate with center
    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]
    return cv2.warpAffine(src,rot_mat,(int(math.ceil(nw)),int(math.ceil(nh))),flags = cv2.INTER_LANCZOS4)


def enhancement_using_rotation(ImagePath,AnnotationsPath,ImageSavePath,AnnotationsSavePath):

    for imgfile in os.listdir(ImagePath):
        if not os.path.isfile(os.path.join(AnnotationsPath,imgfile[:-4]+'.xml')):
            continue
        print(imgfile)
        img = cv2.imread(os.path.join(ImagePath,imgfile))

        #rotation
        for angle in rotation_angle:

            new_name =  'r'+ str(angle) + '_' + imgfile
            rotate_img = rotate_about_center(img,angle)
            cv2.imwrite(os.path.join(ImageSavePath,new_name),rotate_img)

            center_x = img.shape[1]/2
            center_y = img.shape[0]/2
            new_center_x = rotate_img.shape[1]/2
            new_center_y = rotate_img.shape[0]/2


            if annotation_file is 'txt':            
                ff = open(os.path.join(AnnotationsPath,'labels',imgfile[:-4]+'.txt'),'r')
                f = open(os.path.join(AnnotationsSavePath,'labels',new_name[:-4] +'.txt'),'a')
                for line in ff.readlines():
                    [filename, cls, x1,y1,x2,y2,t] = line.split(' ')
                    
                    final_x1, final_y1, final_x2, final_y2 = \
                                        _rotated_location(x1,y1,x2,y2,center_x,center_y,new_center_x,new_center_y)
                    assert(final_y2-final_y1>0) & (final_x2-final_x1>0)

                    if ifshow == 1:
                        cv2.rectangle(rotate_img,(final_x1,final_y1),(final_x2,final_y2),(0,0,255),2)
                        cv2.putText(rotate_img, cls, (int(final_x1),int(final_y1)),0,1.2,(0,0,255),2)
                    nline = new_name + ' ' + cls + ' ' + str(final_x1) + ' ' + str(final_y1) + ' ' + str(final_x2) + ' ' + str(final_y2) + '\n'
                    f.write(nline)
                f.close()
                ff.close()
            
            elif annotation_file is 'xml':
                Annotations = os.path.join(AnnotationsPath,imgfile[:-4]+'.xml')
                saveAnnotations = os.path.join(AnnotationsSavePath,new_name[:-4]+'.xml')
                tree = ET.parse(Annotations)

                filename = tree.find('filename')
                filename.text = new_name

                size = tree.find('size')
                height = size.find('height')
                height.text = str(rotate_img.shape[0])
                width = size.find('width')
                width.text = str(rotate_img.shape[1])

                root = tree.getroot()
                for obj in tree.findall('object'):
                    class_node = obj.find('name')
                    bndbox = obj.find('bndbox')
                    x1 = bndbox.find('xmin').text
                    y1 = bndbox.find('ymin').text
                    x2 = bndbox.find('xmax').text
                    y2 = bndbox.find('ymax').text
                    if not(int(y2)-int(y1)>0) & (int(x2)-int(x1)>0):
                        print(Annotations)
                        root.remove(obj)
                        continue
                    assert(int(y2)-int(y1)>0) & (int(x2)-int(x1)>0)

                    final_x1, final_y1, final_x2, final_y2 = \
                                        _rotated_location(x1,y1,x2,y2,center_x,center_y,new_center_x,new_center_y,angle)
                    if final_y1<0:
                        print(x1,y1,x2,y2)
                        print(final_x1,final_y1)
                    assert(final_y2-final_y1>0)
                    assert(final_x2-final_x1>0)
                    assert(final_x1>=0)
                    assert(final_y1>=0)
                    assert(final_x2<=int(width.text))
                    assert(final_y2<=int(height.text))

                    if ifshow == 1:
                        cv2.rectangle(rotate_img,(final_x1,final_y1),(final_x2,final_y2),(0,0,255),2)
                        cv2.putText(rotate_img, cls, (int(final_x1),int(final_y1)),0,1.2,(0,0,255),2)
                    bndbox.find('xmin').text = str(final_x1)
                    bndbox.find('ymin').text = str(final_y1)
                    bndbox.find('xmax').text = str(final_x2)
                    bndbox.find('ymax').text = str(final_y2)
              
                tree.write(saveAnnotations)

            if ifshow == 1:
                cv2.imshow(new_name,rotate_img)
                key = cv2.waitKey(500)
                if key ==27:
                        quit()
                cv2.destroyWindow(new_name)


def _rotated_location(x1,y1,x2,y2,center_x,center_y,new_center_x,new_center_y,angle):
    x1 = float(x1) - center_x
    y1 = -(float(y1) - center_y)
    x2 = float(x2) - center_x
    y2 = -(float(y2) - center_y)

    rangle = np.deg2rad(angle)
    rotated_x1 = np.cos(rangle)*x1 - np.sin(rangle)*y1
    rotated_y1 = np.cos(rangle)*y1 + np.sin(rangle)*x1
    rotated_x2 = np.cos(rangle)*x2 - np.sin(rangle)*y2
    rotated_y2 = np.cos(rangle)*y2 + np.sin(rangle)*x2

    rotated_x1 = int(rotated_x1 + new_center_x)
    rotated_y1 = int(-rotated_y1 + new_center_y)
    rotated_x2 = int(rotated_x2 + new_center_x)
    rotated_y2 = int(-rotated_y2 + new_center_y)

    final_x1 = int(min(rotated_x1,rotated_x2))
    final_y1 = int(min(rotated_y1,rotated_y2))
    final_x2 = int(max(rotated_x1,rotated_x2))
    final_y2 = int(max(rotated_y1,rotated_y2))
    return final_x1, final_y1, final_x2, final_y2


def enhancement_using_mirror(ImagePath,AnnotationsPath,ImageSavePath,AnnotationsSavePath):

    #mirror
    for imgfile in os.listdir(ImagePath):
        img = cv2.imread(os.path.join(ImagePath,imgfile))
        new_name = 'm_' + imgfile 
        # print(new_name)

        mirror_img  = mirroir_hierachically(img)
        cv2.imwrite(os.path.join(ImageSavePath,new_name),mirror_img)


        w = img.shape[1]

        if annotation_file is 'txt':
            ff = open(os.path.join(txtpath,imgfile[:-4]+'.txt'),'r')
            f = open(os.path.join(txtpath,new_name[:-4]+'.txt'),'a')
            for line in ff.readlines():
                [filename,cls,x1,y1,x2,y2] = line.strip().split(' ')
                x2 = abs(int(x1)-w)
                x1 = abs(int(x2)-w)


                final_x1 = min(x1,x2)
                final_x2 = max(x1,x2)
                assert(final_x2-final_x1>0)

                nline = new_name + ' ' + cls + ' ' + str(final_x1) + ' ' + y1 + ' ' + str(final_x2) +  ' ' + y2 + '\n'
                f.write(nline)

                if ifshow == 1:
                    cv2.rectangle(mirror_img,(final_x1,int(y1)),(final_x2,int(y2)),(0,0,255),2)
                    cv2.putText(mirror_img, cls, (final_x1,int(y1)),0,1.2,(0,0,255),2)           
            
            f.close()
            ff.close()
        
        elif annotation_file is 'xml':
            Annotations = os.path.join(AnnotationsPath, imgfile[:-4]+'.xml')
            saveAnnotations = os.path.join(AnnotationsSavePath,new_name[:-4]+'.xml')
            tree = ET.parse(Annotations)


            filename = tree.find('filename')
            filename.text = new_name


            for obj in tree.findall('object'):
                bndbox = obj.find('bndbox')
                x1 = bndbox.find('xmin').text
                y1 = bndbox.find('ymin').text
                x2 = bndbox.find('xmax').text
                y2 = bndbox.find('ymax').text

                new_x1 = abs(int(x2)-w)
                new_x2 = abs(int(x1)-w)

                final_x1 = int(min(new_x1,new_x2))
                final_x2 = int(max(new_x1,new_x2))
                assert(final_x2-final_x1>0)

                cls = obj.find('name').text 
     
                if ifshow == 1:
                    cv2.rectangle(mirror_img,(final_x1,int(y1)),(final_x2,int(y2)),(0,0,255),2)
                    cv2.putText(mirror_img, cls, (int(final_x1),int(y1)),0,1.2,(0,0,255),2)
                                           
                bndbox.find('xmin').text = str(final_x1)
                bndbox.find('xmax').text = str(final_x2)


            tree.write(saveAnnotations)
            # tree.clear()


        if ifshow == 1:
            cv2.imshow(new_name,mirror_img)
            key = cv2.waitKey(500)
            if key ==27:
                quit()
            cv2.destroyWindow(new_name)



def mirroir_hierachically(src):
    w = src.shape[1]
    h = src.shape[0]
    ll = src.shape[2]
    mirror_img = copy.deepcopy(src)
    for wi in range(w):
        mirror_img[:,w-wi-1] = src[:,wi]
    return mirror_img


def main(dirpath):
    # ##################################### PART 1 ######################################################## 
    savepath = dirpath + 'Rotated/'
    ImageSavePath = savepath + '/JPEG/'
    AnnotationsSavePath = savepath + '/XML/'
    # ImageSetsSavePath = savepath + '/ImageSets/Main/'

    if not os.path.exists(savepath):
        os.makedirs(savepath)  
    if not os.path.exists(ImageSavePath):
        os.makedirs(ImageSavePath)    
    if not os.path.exists(AnnotationsSavePath):
        os.makedirs(AnnotationsSavePath)

  # ##################################### PART 2 ########################################################

    #augument trainning data by rotating
    print('rotating...')
    ImagePath = dirpath + 'Sampled/JPEG/'
    AnnotationsPath = dirpath + 'Sampled/XML/'
    enhancement_using_rotation(ImagePath,AnnotationsPath,ImageSavePath,AnnotationsSavePath)

    #augument trainning data by mirroring, mirroring after rotating
    print('mirroring...') 
    mir_ImagePath = dirpath + 'Rotated/JPEG/'
    mir_AnnotationsPath = dirpath + 'Rotated/XML/'
    mir_savepath = dirpath + 'mirrored/'
    mir_AnnotationsSavePath = mir_savepath + 'XML/'
    mir_imgsavepath = mir_savepath + 'JPEG/'

    if not os.path.exists(mir_savepath):
        os.makedirs(mir_savepath)   
    if not os.path.exists(mir_imgsavepath):
        os.makedirs(mir_imgsavepath) 
    if not os.path.exists(mir_AnnotationsSavePath):
        os.makedirs(mir_AnnotationsSavePath)

    enhancement_using_mirror(mir_ImagePath,mir_AnnotationsPath,mir_imgsavepath,mir_AnnotationsSavePath)

if __name__ == '__main__':
    global annotation_file, rotation_angle, ifshow
    annotation_file = 'xml'#'txt',xml'
    rotation_angle=[0,90,180,270]
    ifshow = 0
    dirpath = 'E:/PowerDetectTrainDataExp/'
    main(dirpath)








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值