由于手机差异拍照,导入在电脑上会发现图片内容不是竖直的,可能会是旋转90°,这个情况就需要如下的脚本去批量旋转回正,可能会有不同程度的局限性。
思路:根据读图片exif获取Orientation的值,旋转N个90°
import cv2
import os
import re
import numpy as np
import logging
from PIL import Image
from PIL.ExifTags import TAGS
import time
logger = logging.getLogger("log")
logger.setLevel(logging.DEBUG)
# logger的setLevel是最根本的
fh = logging.FileHandler('log' + time.strftime("%Y%m%d%H%M%S", time.localtime(time.time())) + '.log')
# 如果没有这个,就不会输出到文件
fh.setLevel(logging.INFO)
ch = logging.StreamHandler()
ch.setLevel(logging.INFO)
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
ch.setFormatter(formatter)
fh.setFormatter(formatter)
logger.addHandler(ch)
logger.addHandler(fh)
print('\n')
print('此脚本可批量将旋转的图片回正,降低分辨率为360*360')
print('\n')
print('读文件夹结构,主文件夹下存在多个子文件夹,子文件夹下存在大量图片')
print('\n')
path = input('请将保存所有图片的主文件夹拖入窗口,并点击回车!!!!!\n\n')
# path = r'F:\项目\文物\20190702识别率测试\小图\testprct' # 主目录为指定目录
# path = os.getcwd() #当前脚本路径下
class Cultural():
def get_Image(self,path):
filelist_cultural = os.listdir(path) # 获取路径下所有文件的列表
for fcatalog in Cultural.strsort(filelist_cultural) :
path_fcatalog = os.path.join(path, fcatalog)
if os.path.isdir(path_fcatalog):
imagellist = os.listdir(path_fcatalog)
for imagepath in imagellist:
imagefile_path = os.path.join(path_fcatalog, imagepath)
try:
if int(Cultural.get_exif_data(imagefile_path)[2])==6:
logger.info('文物《'+ str(fcatalog)+'》的《'+str(imagepath)+'》Orientation为6,旋转回正、降分辨率……')
Cultural.revolve_image(imagefile_path)
Cultural.Lower_resolution(imagefile_path)
elif int(Cultural.get_exif_data(imagefile_path)[2])==0:
logger.info('文物《'+ str(fcatalog)+'》的《'+str(imagepath)+'》Orientation为0,不需要旋转回正,降分辨率……')
Cultural.Lower_resolution(imagefile_path)
else:
logger.info('文物《' + str(fcatalog) + '》的《' + str(imagepath) + '》Orientation为'+str(Cultural.get_exif_data(imagefile_path)[2])+'不需要旋转回正,降分辨率……')
Cultural.Lower_resolution(imagefile_path)
except:
logger.info('文物《'+ str(fcatalog)+'》的《'+str(imagepath)+'》无exif信息,降分辨率……')
Cultural.Lower_resolution(imagefile_path)
def get_exif_data(self,imagefile_path):#读取照片信息exif
ret = {}
try:
img = Image.open(imagefile_path)
if hasattr(img, '_getexif'):
exifinfo = img._getexif()
if exifinfo != None:
for tag, value in exifinfo.items():
decoded = TAGS.get(tag, tag)
ret[decoded] = value
except IOError:
logger.info('IOERROR,无信息' )
return (ret, ret['Make'],ret['Orientation'])
def revolve_image(self,img_path): #旋转图片
# 打开图像
im = Image.open(img_path)
# 图像旋转,两种方法:
new_img1 = im.transpose(Image.ROTATE_270) # 逆时针旋转270(有些人抄都不会抄,还顺时针呢)
new_img2 = im.rotate(90) # 逆时针旋转90
"""
这里说一下这两种方法,new_img1就是单纯的旋转了图片的方向。new_img2在旋转以后,可能会发生裁剪(一般不推荐2)。
"""
# 保存文件
new_img1.save(img_path, quality=95, subsampling=0)
"""
save()方法里:参数quality=95, subsampling=0是为了防止图像的压缩,百度有详解,这里不再赘述。
"""
def Lower_resolution(self,file_path): # 降低分辨率(360*360)
try:
# 修改之后的图片大小
size_ = (360, 360)
img = cv2.imdecode(np.fromfile(file_path, dtype=np.uint8), -1) # 路径不能为中文解决方法
im2 = cv2.resize(img, size_, interpolation=cv2.INTER_CUBIC)
# saved_path = r'D:\Python\python3\picture processing\哈哈\kjfhkj_5453.JPG'
# cv2.imwrite(saved_path, im2) #保存
cv2.imencode('.jpg', im2)[1].tofile(file_path) # #路径不能为中文解决方法
except:
logger.error('《'+ file_path.split('\\')[-2]+'》的'+file_path.split('\\')[-1]+'图片异常')
os.remove(file_path)
def sort_key(self, s): # 排序
# 排序关键字匹配
# 匹配开头数字序号
if s:
try:
c = re.findall('^\d+', s)[0]
except:
c = -1
return int(c)
def strsort(self, alist): # 排序
alist.sort(key=self.sort_key)
return alist
def execute(self,path):
if os.path.exists(path):
try:
Cultural.get_Image(path)
except:
print('\n')
print('拖入文件夹不满足要求!!!')
else:
print('输入的路径不存在')
if __name__ == '__main__':
Cultural = Cultural()
Cultural.execute(path)
input('Press Enter to exit...')