您的位置:首页 > 运维架构

图片处理(rename image,change ‘txt’ file,crop image,delete image,图片直方图均衡化)

2018-03-08 15:30 260 查看
1.读取某一文件夹(包含子文件夹)下面的所有图片(如“inputpath”文件夹),修改文件夹里面所有图片的名字,并且按序命名。# This code is used to rename images.
import os
import shutil
def renameXML(inputPath,outputPath,t,i):
if os.path.exists(outputPath) == False:
os.makedirs(outputPath)#make directory and subdirectory
imgorder=i
for _,dirs,files in os.walk(inputPath):
for f1 in files:
if (os.path.splitext(f1)[1]== '.bmp')\
|(os.path.splitext(f1)[1]== '.jpg'):
temp=str(t).zfill(2)
imgnewname='s'+temp+str(imgorder).zfill(5)+'.bmp'
print(os.path.join(outputPath,imgnewname))
shutil.copy(os.path.join(inputPath,f1),os.path.join(outputPath,imgnewname))
imgorder = imgorder + 1

if __name__=='__main__':
for pathDir in range(1,41):
inputpath="input/"+'s'+str(pathDir)+'/' #此处意:input文件夹下面包含了s1-s40 总共40个文件夹
# print(inputpath)
outputpath="output/"+'s'+str(pathDir)+'/'
renameXML(inputpath,outputpath,pathDir,1)

2.数据集处理
1)Multi-Task Facial Landmark (MTFL) dataset中笑脸与非笑脸筛选

“training.txt”文件中的内容如下图所示。
意为:#image path #x1...x5,y1..y5 #gender #smile #wearing glasses #head pose
--x1...x5,y1...y5: the locations for left eye, right eye, nose, left mouth corner, right mouth corner.
--gender: 1 for male, 2 for female
--smile: 1 for smiling, 2 for not smiling
--glasses: 1 for wearing glasses, 2 for not wearing glasses.
--head pose: 1 for left profile, 2 for left, 3 for frontal, 4 for right, 5 for right profile



# -*- coding: UTF-8 -*-
# 程序changeXMLcontent()读取文件每一行中的第1(图片名)、12(是否是笑脸)字符串,并且找到数据库中对应的笑脸
import os
import shutil
from PIL import Image
import random
import numpy as np

def changeXMLcontent(XMLfile, imgPath, outputPath):
with open(XMLfile, 'r', encoding="utf-8") as f_r:
lines = f_r.readlines()
with open(XMLfile, 'w', encoding="utf-8") as f_w:
for line in lines:
for _, dirs, files in os.walk(imgPath):
for f1 in files:
if os.path.splitext(f1)[0] in line.split()[0] and line.split()[12] == '1':
print(line.split()[0], line.split()[12])#split()意为以"空格"切片,split('/')以'/'切片,具体可做实验检查
shutil.copy(os.path.join(imgPath, f1), os.path.join(outputPath, f1))
f_w.write(line)

#crop the edge of face
def cutImg(imgPath, outputPath):
for _, dirs, files in os.walk(imgPath):
for f1 in files:
im = Image.open(os.path.join(imgPath, f1)).convert('L')
row, col = im.size
print(row, col)
if row == 400 :
afterCrop = im.crop((row * 1.8 / 8, col * 2 / 8, row * 6.1 / 8, col * 6.4 / 8)) # 4-tuple:(left,upper,right,down)
elif row == 250:
afterCrop = im.crop((row * 1.8 / 8, col * 2 / 8, row * 6.1 / 8, col * 6.3 / 8)) # 4-tuple:(left,upper,right,down)
elif row == 160:
afterCrop = im.crop((row * 1.6 / 8, col * 1.2 / 8, row * 6.2 / 8, col * 4.4 / 8)) # 4-tuple:(left,upper,right,down)
# afterCrop.show()
afterCrop.save(os.path.join(outputPath, f1))

#remove image
def remove_img(smileImgPath, unsmileImgPath):
cout = 0
for _s, sdirs, sfiles in os.walk(smileImgPath):
for sf1 in sfiles:
for _us,usdirs,usfiles in os.walk(unsmileImgPath):
for usf1 in usfiles:
if sf1 == usf1:
# print(sf1)
os.remove(os.path.join(unsmileImgPath, sf1))
cout = cout + 1
print(cout)

def rename(imgPath, outputPath):
imgorder = 1
for _, dirs, files in os.walk(imgPath):
for f1 in files:
grayim = Image.open(os.path.join(imgPath, f1)).convert('L') #转灰度图
afterbalance = histeq(grayim)[0]
# huiduim.show()
# afterbalance.show()
imgnewname = 's' + str(imgorder).zfill(5) + '.jpg'
imgorder = imgorder + 1
afterbalance.convert('RGB').save(os.path.join(outputPath, imgnewname))#必须转回'RGB'才能保存
# shutil.copy(os.path.join(imgPath, f1), os.path.join(outputPath, imgnewname))

def histeq(im, nbr_bins=256):#直方图均衡化
""" Histogram equalization of a grayscale image. """
array_im = np.array(im)
imhist, bins = np.histogram(array_im.flatten(),nbr_bins,normed=True)
cdf = imhist.cumsum() #累积分布函数 cumulative distribution function
cdf = 255*cdf/cdf[-1] #归一化(灰度变换函数)
#使用累积分布函数的线性插值,计算新的像素值
im2 = np.interp(array_im.flatten(), bins[:-1], cdf)
return Image.fromarray(im2.reshape(array_im.shape)), cdf

def selectRandom(imgPath, outputPath):
cout = 1
selectNum = 0
for _, dirs, files in os.walk(imgPath):
for f1 in files:
cout = cout + 1
for i in range(1, 601):
rd = random.randint(1, cout+1)
randomname = str(rd).zfill(5)
for _, dirs, files in os.walk(imgPath):
for f1 in files:
if randomname in f1:
shutil.move(os.path.join(imgPath, f1), os.path.join(outputPath, f1))
print(str(f1))
selectNum = selectNum + 1
print('\n\n随机选择图片数量:'+str(selectNum))

if __name__ == '__main__':
xmlinput = "./test/training.txt"
outputpath = "D:/face_project/smile/"
testpath="D:/face_project/MTFL/lfw_5590"

# for f in ['net_7876', 'lfw_5590']:
# imgpath = "D:/face_project/MTFL/" + f + '/'
# changeXMLcontent(xmlinput, imgpath, outputpath)

# cutImg(testpath, "D:/face_project/testoutput")
# remove_img("D:/face_project/笑脸数据集/renamesmile", "D:/face_project/笑脸数据集/renameunsmile")
# rename("D:/face_project/笑脸数据集/output_smile/", "D:/face_project/笑脸数据集/rename_smile")
selectRandom("D:/face_project/笑脸数据集/rename_unsmile/", "D:/face_project/笑脸数据集/random_unsmile")2)人脸数据集转VOC数据集
数据集中人脸标注文件(wider_face_train_bbx_gt.txt)格式如下图所示。
意为:The format of txt ground truth.
--File name
--Number of bounding box
--x1, y1, w, h, blur, expression, illumination, invalid, occlusion, pose



实现方法:将“wider_face_train_bbx_gt.txt”中的File name,x1,y1,x1+w,y1+h的值转存到VOC数据集图片对应的xml标签中。import io
import os
import shutil

def mkfile(file, flag, *text): #*--传元组,**--传字典
if flag == 1:
file.write('<annotation>\n'
' <folder>VOC2007</folder>\n'
' <filename>')
file.write(str(text[0]).strip('\n')+'</filename>\n') #strip('\n')--delete string '\n'
file.write(' <source>\n'
' <database>The VOC2007 Database</database>\n'
' <annotation>PASCAL VOC2007</annotation>\n'
' <image>flickr</image>\n'
' <flickrid>NULL</flickrid>\n'
' </source>\n'
' <owner>\n'
' <flickrid>NULL</flickrid>\n'
' <name>Face</name>\n'
' </owner>\n'
' <size>\n'
' <width>0</width>\n'
' <height>0</height>\n'
' <depth>3</depth>\n'
' </size>\n'
' <segmented>0</segmented>\n'
)
if flag == 0:
# print('str(text[0])'+str(text[0][0]))
file.write(' <object>\n'
' <name>face</name>\n'
' <pose>Unspecified</pose>\n'
' <truncated>0</truncated>\n'
' <difficult>0</difficult>\n'
' <bndbox>\n'
' <xmin>'
+ str(text[0][0]) + '</xmin>\n'
' <ymin>'
+ str(text[0][1]) + '</ymin>\n'
' <xmax>'
+ str(text[0][2]) + '</xmax>\n'
' <ymax&
a307
gt;'
+ str(text[0][3]) + '</ymax>\n'
' </bndbox>\n'
' </object>\n')
if flag == 2:
file.write(str(text[0]))
# file.close()

def face_generate_voc(inputFile, outputPath):
nameflag = 0
facenumber = 0
with open(inputFile, 'r', encoding="utf-8") as f_r:
lines = f_r.readlines()
with open(inputFile, 'w', encoding="utf-8") as f_w:
for line in lines:
if facenumber > 0:
facenumber = facenumber - 1 #the number of face in an image
tup = (int(line.split()[0]), int(line.split()[1]), \
int(line.split()[0])+int(line.split()[2]),\
int(line.split()[1])+int(line.split()[3]))
print(tup)
nameflag = 0
mkfile(file, nameflag, tup)#file解释:代码前文虽然未对file做初始化,但是后文做了初始化(逻辑上做了初始化的--后文中的file相关代码先执行)
if facenumber == 0:
mkfile(file, 2, '</annotation>') # the end of xml content

if nameflag == 1:
facenumber = int(line.split()[0])
print(facenumber)
#if facenumber > 0:
#f_w.write(line) #every line must be written back
#continue

if '.jpg' in line:
nameflag = 1
#print(line)
filename = line.split('/')[1]
#print(line.split('/')[1])#以'/'切片将字符串分开,如'string/123.jpg',切片后:line.split('/')[1]='123.jpg'
if os.path.exists(outputPath) == False:
os.makedirs(outputPath) # make directory and subdirectory
file = open(os.path.join(outputPath, filename.split('.')[0]+'.xml'), 'w')
mkfile(file, nameflag, filename)
f_w.write(line) #you must write every line back to original file

if __name__=='__main__':
inputfile = 'wider_face_val_bbx_gt.txt'
outputpath = './output/'
face_generate_voc(inputfile, outputpath)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息