import os, sys, time, shutil, subprocess, shlex, json,oss2 from PIL import Image import platform if platform.system() == 'Windows': sys.path.append('e:\\libs\\') else: sys.path.append('/data/deploy/make3d/make2/libs/') import config, libs, libs_db #检测是否存在 rate_xmps 文件,如果没有则要创建该影棚对应的rate_xmps文件 def check_rate_xmps(pid): pid = str(pid) psid = libs.getPSid(pid) #判断是否存在该目录 if config.oss_bucket.object_exists(f'xmps_rate/{psid}/') == False: return False return True def clearExifAndRotate(imagePath, rotate=180): if os.path.exists(imagePath) == False: print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} {imagePath} 图片不存在') return print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} {imagePath} 图片exif信息清除并且旋转...') # img = Image.open(imagePath) # print(img.info) # # 清除 EXIF 信息 # img.info = {} # 清除 EXIF 信息 # # 旋转图片 180 度 # img = img.rotate(180) # # 保存处理后的图片 # img.save(imagePath) # 打开图像 with Image.open(imagePath) as img: # 使用RGB模式打开图像来丢弃可能存在的EXIF信息 img = img.convert("RGB") img = img.rotate(180) # 保存图像,保存时不会带有原始的任何元数据 img.save(imagePath, quality=100) # 对于JPEG,可以调整质量参数 #如果老影棚没有做过旋转坐标的照片的,则要做一次旋转坐标 def rateImages(pid): #遍历文件夹下的所有图片 photo1_path = os.path.join(config.workdir, pid, 'photo1') photo2_path = os.path.join(config.workdir, pid, 'photo2') for pic in os.listdir(photo1_path): if pic.endswith('.jpg'): #清除图片exif信息, 旋转图片 180度 clearExifAndRotate(os.path.join(photo1_path, pic)) print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} {pic} 图片exif信息清除并且旋转完成') for pic in os.listdir(photo2_path): if pic.endswith('.jpg'): #清除图片exif信息, 旋转图片 180度 clearExifAndRotate(os.path.join(photo2_path, pic)) print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} {pic} 图片exif信息清除并且旋转完成') print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} {pid} 图片exif信息清除并且旋转完成') def upload_xmp(pid): print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 上传xmp文件之前先删除oss上的xmps_rate文件所在目录...') pid = str(pid) psid = libs.getPSid(pid) #移除掉旧的文件夹 #config.oss_bucket.delete_object(f'xmps/{pid}/') #删除oss 上的文件夹里的内容 #判断是否存在该目录 if config.oss_bucket.object_exists(f'xmps_rate/{psid}/') == True: object_list = oss2.ObjectIterator(config.oss_bucket, prefix=f'xmps_rate/{psid}/') if not any(object_list): config.oss_bucket.batch_delete_objects([obj.key for obj in object_list]) start_time = time.time() workdir = os.path.join(config.workdir, pid) config.oss_bucket.put_object_from_file(f'xmps_rate/{psid}/{psid}.rcbox', os.path.join(workdir, f'{pid}.rcbox')) for xmp in os.listdir(os.path.join(workdir, 'photo1')): if xmp.endswith('.xmp'): config.oss_bucket.put_object_from_file(f'xmps_rate/{psid}/mesh/{xmp}', os.path.join(workdir, 'photo1', xmp)) #复制一份到共享盘上的 libs xmps psid 文件夹下 #判断是否有对应的文件夹,不存在就创建 os.makedirs(os.path.join(config.sharedir, 'xmps_rate', psid, 'mesh'), exist_ok=True) shutil.copy(os.path.join(workdir, 'photo1', xmp), os.path.join(config.sharedir, 'xmps_rate', psid, 'mesh', xmp)) for xmp in os.listdir(os.path.join(workdir, 'photo2')): if xmp.endswith('.xmp'): config.oss_bucket.put_object_from_file(f'xmps_rate/{psid}/texture/{xmp}', os.path.join(workdir, 'photo2', xmp)) #复制一份到共享盘上的 libs xmps psid 文件夹下 os.makedirs(os.path.join(config.sharedir, 'xmps_rate', psid, 'texture'), exist_ok=True) shutil.copy(os.path.join(workdir, 'photo2', xmp), os.path.join(config.sharedir, 'xmps_rate', psid, 'texture', xmp)) print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} xmp文件上传完成,共费时{time.time() - start_time}秒') #创建rate_xmps文件 def create_rate_xmps(pid): start_time = time.time() pid = str(pid) psid = libs.getPSid(pid) #判断是否存在xmps_rate文件夹 flag = check_rate_xmps(pid) if flag == True: # 提示输入指令是否要重新做rate_xmps文件 print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} {pid} rate_xmps文件已经存在,是否重新生成rate_xmps文件?') continue_or_not = input('是否重新生成rate_xmps文件?(y/n)') if continue_or_not == 'y': pass else: sys.exit(0) #判断是否有对应的 photo1 和 photo2 文件夹 photo1_path = os.path.join(config.workdir, pid, 'photo1') photo2_path = os.path.join(config.workdir, pid, 'photo2') #判断是否存在目录 if os.path.exists(photo1_path) == False or os.path.exists(photo2_path) == False: #重新下载图片文件photo1和photo2 libs.down_from_oss(config.oss_bucket, config.workdir, pid) photos1_count = len(os.listdir(photo1_path)) photos2_count = len(os.listdir(photo2_path)) if photos1_count + photos2_count < 162: print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} {pid} photo1数量{photos1_count} photo2数量{photos2_count},未能覆盖所有相机,是否继续计算相机位姿?') continue_or_not = input('是否继续计算相机位姿?(y/n)') if continue_or_not == 'y': pass else: sys.exit(0) #清除图片exif信息, 旋转图片 180度 rateImages(pid) #通过rc 计算出 xmps 文件 exportxmp = ' -exportXMP "D:\\make2\\config\\exportXMP.config.lock.xml" ' cmd = f'{config.rcbin} {config.r2["init"]} -setInstanceName {pid} \ -save "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}" \ -addFolder "{os.path.join(config.workdir, pid, "photo1")}" -selectAllImages \ -detectMarkers "D:\\make2\\config\\detectMarkers.config.xml" \ -align -align \ {exportxmp} \ -save "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}" -quit' print(cmd) cmd = shlex.split(cmd) res = subprocess.run(cmd) # TODO:加入report相机位姿质量评估 print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} {pid} photo1相机位姿完成,共费时{libs.diff_time(start_time)}') for xmp in os.listdir(photo1_path): if xmp.endswith('.xmp'): shutil.copy(os.path.join(photo1_path, xmp), os.path.join(photo2_path, xmp.replace('_1.xmp', '_8.xmp'))) psid = libs.getPSid(pid) cmd = f'{config.rcbin} {config.r2["init"]} -setInstanceName {pid} \ -load "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}" {config.r["setTextureFalse"]} \ -addFolder "{os.path.join(config.workdir, pid, "photo2")}" -selectAllImages \ -detectMarkers "D:\\make2\\config\\detectMarkers.config.xml" \ {libs.get_defineDistances(psid)} -update -align -align {config.r2["setRegion"]} \ {exportxmp} \ -exportReconstructionRegion "{os.path.join(config.workdir, pid, f"{pid}.rcbox")}" \ -exportRegistration "D://{pid}/xmps_reg/{pid}_registration.out" "D://make2/config/registration_export_config.xml" \ -save "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}" -quit' print(cmd) cmd = shlex.split(cmd) res = subprocess.run(cmd) print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} {pid} photo2相机位姿完成,共费时{libs.diff_time(start_time)}') #从 D://{pid}/xmps_reg/ 中获取对齐数量 xmpAligns = 0 for file in os.listdir(os.path.join(config.workdir, pid, 'xmps_reg')): if file.endswith('.jpg'): xmpAligns += 1 #判断对齐数量是否和 照片总数一样 if xmpAligns == (photos1_count+photos2_count): upload_xmp(pid) else: upload_or_not = input(f'当前照片总数{photos1_count+photos2_count},对齐数量{xmpAligns},没有全部对齐,是否上传oss?(y/n)') if upload_or_not == 'y': upload_xmp(pid) print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} {pid} rate_xmps文件生成完成,共费时{libs.diff_time(start_time)}') if __name__ == '__main__': pid = sys.argv[1] print(f'执行任务的pid: {pid}') create_rate_xmps(pid)