51 changed files with 5187 additions and 61 deletions
Binary file not shown.
@ -0,0 +1,125 @@ |
|||||||
|
import os, sys, time, shlex, subprocess, shutil, requests, cv2, numpy as np |
||||||
|
from PIL import Image |
||||||
|
import platform,socket,atexit |
||||||
|
if platform.system() == 'Windows': |
||||||
|
sys.path.append('e:\\libs\\') |
||||||
|
#sys.path.append('libs') |
||||||
|
else: |
||||||
|
sys.path.append('/data/deploy/make3d/make2/libs/') |
||||||
|
import config, libs, libs_db,main_service_db,common |
||||||
|
|
||||||
|
arrPids = [184219,184215,184209,184206,184201,184199,184164,184087,184076,184069,184059,184029,184013,183993,183952,183888,183882,183868,183824,183817,183815,183812,183791,183777,183715,183705,183670,183613,183573,182974,182983,182985,182989,182997,183007,183051,183060,183054,183053,183097,183119,183108,183139,183141,183155,183163,183169,183180,183191,183196,183214,183244,183266,183278,183275,183309,183402,183422,183440,182974,182964,182958,182956,182916,182855,182854,182820,182787,182800,182809,182780,182772,182770,182766,182754,182742,182740,182723,182707,182647,182643,182614,182595,182563,182557,182547,182546,182538,182530,182517,182498,182478,182452,182386,182352,182285,182266,182260,182230,182224] |
||||||
|
|
||||||
|
r12Pids = [184219,184215,184209,184069,184059,183868,183817,183791,183613,183573,182974,182983,182985,182989,182997,183007,183051,183060,183054,183053,183097,183119,183108,183139,183141,183155,183163,183169,183180,183191,183196,183214,183244,183266,183278,183275,183309,183402,183422,183440,182974,182964,182958,182855,182854] |
||||||
|
print(f"处理的数据长度--{len(arrPids)}") |
||||||
|
i=0 |
||||||
|
noPids = '' |
||||||
|
for pid in r12Pids: |
||||||
|
pid = str(pid) |
||||||
|
path = f"D://{pid}/mask" |
||||||
|
#判断是否存在文件夹 |
||||||
|
if not os.path.exists(path): |
||||||
|
continue |
||||||
|
|
||||||
|
#判断文件夹是否为空 |
||||||
|
if len(os.listdir(path)) == 0: |
||||||
|
continue |
||||||
|
|
||||||
|
i+=1 |
||||||
|
|
||||||
|
|
||||||
|
#检查 depth 和 mask 的文件创建时间是否差异比较大 |
||||||
|
fileDepth = f"D://{pid}/depth" |
||||||
|
fileMask = f"D://{pid}/mask" |
||||||
|
|
||||||
|
diffDepthTime = [] |
||||||
|
dfffMaskTime = [] |
||||||
|
|
||||||
|
arrTimeDepth = [] |
||||||
|
arrTimeMask = [] |
||||||
|
for file in os.listdir(fileDepth): |
||||||
|
createTime = os.path.getctime(f"{fileDepth}/{file}") |
||||||
|
updateTime = os.path.getmtime(f"{fileDepth}/{file}") |
||||||
|
# print(updateTime - createTime) |
||||||
|
diffDepthTime.append(updateTime - createTime) |
||||||
|
arrTimeDepth.append(os.path.getctime(f"{fileDepth}/{file}")) |
||||||
|
|
||||||
|
for file in os.listdir(fileMask): |
||||||
|
createTime = os.path.getctime(f"{fileMask}/{file}") |
||||||
|
updateTime = os.path.getmtime(f"{fileMask}/{file}") |
||||||
|
dfffMaskTime.append(updateTime - createTime) |
||||||
|
|
||||||
|
arrTimeMask.append(os.path.getctime(f"{fileMask}/{file}")) |
||||||
|
|
||||||
|
#打印出 两者的 最大 和最小的时间信息 |
||||||
|
print(f"pid: {pid} depth: { (max(arrTimeDepth) - min(arrTimeDepth))/60 }, diffdepth: {max(diffDepthTime)}, mask: { (max(arrTimeMask) - min(arrTimeMask))/60},diffmask: {max(dfffMaskTime)}") |
||||||
|
# print(f"pid: {pid} diffdepth: {max(arrTimeDepth)} diffmask: {max(arrTimeMask)}") |
||||||
|
|
||||||
|
diffDepth = (max(arrTimeDepth) - min(arrTimeDepth))/60 |
||||||
|
diffMask = (max(arrTimeMask) - min(arrTimeMask))/60 |
||||||
|
|
||||||
|
if diffDepth > 5 or diffMask > 5: |
||||||
|
print(f"异常数据 pid: {pid} depth: {diffDepth} mask: {diffMask}") |
||||||
|
break |
||||||
|
|
||||||
|
#复制文件到指定目录 |
||||||
|
maskPath = f"D://{pid}/mask" |
||||||
|
depthPath = f"D://{pid}/depth" |
||||||
|
regPath = f"D://{pid}/reg" |
||||||
|
imageList = f"D://{pid}/{pid}_imageList.txt" |
||||||
|
outFila = f"D://{pid}/reg/{pid}_registration.out" |
||||||
|
|
||||||
|
sourcePath = f"D://model_info/{pid}" |
||||||
|
if os.path.exists(sourcePath): |
||||||
|
shutil.rmtree(sourcePath) |
||||||
|
|
||||||
|
if not os.path.exists(sourcePath): |
||||||
|
os.makedirs(sourcePath) |
||||||
|
|
||||||
|
#复制文件 |
||||||
|
shutil.copytree(maskPath, f"D://model_info/{pid}/mask") |
||||||
|
shutil.copytree(depthPath, f"D://model_info/{pid}/depth") |
||||||
|
shutil.copy(imageList, f"D://model_info/{pid}/{pid}_imageList.txt") |
||||||
|
shutil.copy(outFila, f"D://model_info/{pid}/{pid}_registration.out") |
||||||
|
|
||||||
|
#遍历reg文件夹 |
||||||
|
for file in os.listdir(regPath): |
||||||
|
if file == f"{pid}_registration.out": |
||||||
|
continue |
||||||
|
|
||||||
|
if "_1.jpg" in file: |
||||||
|
sourceTempPath = f"D://model_info/{pid}/reg/photo1" |
||||||
|
if not os.path.exists(sourceTempPath): |
||||||
|
os.makedirs(sourceTempPath) |
||||||
|
shutil.copy(f"{regPath}/{file}", f"{sourceTempPath}/{file}") |
||||||
|
|
||||||
|
if "_8.jpg" in file: |
||||||
|
sourceTempPath = f"D://model_info/{pid}/reg/photo2" |
||||||
|
if not os.path.exists(sourceTempPath): |
||||||
|
os.makedirs(sourceTempPath) |
||||||
|
shutil.copy(f"{regPath}/{file}", f"{sourceTempPath}/{file}") |
||||||
|
|
||||||
|
#shutil.copy(f"{regPath}/{file}", f"D://model_info/{pid}/reg/{file}") |
||||||
|
|
||||||
|
#移除 reg 里的 {pid}_registration.out |
||||||
|
|
||||||
|
|
||||||
|
print(f"处理完成 pid: {pid}") |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# shutil.copytree(f"D://{pid}", f"D://{pid}_bak") |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# cmd = f'{config.rcbin} {config.r2["init"]} -setInstanceName {pid} \ |
||||||
|
# -load "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}"'# -quit |
||||||
|
# print(cmd) |
||||||
|
# cmd = shlex.split(cmd) |
||||||
|
# res = subprocess.run(cmd) |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#print(i) |
||||||
@ -0,0 +1,26 @@ |
|||||||
|
<Configuration id="{2D5793BC-A65D-4318-A1B9-A05044608385}"> |
||||||
|
<entry key="eiExportImageList" value="true"/> |
||||||
|
<entry key="eiNearPlaneDistance" value="0.0"/> |
||||||
|
<entry key="calexUndistResMode" value="2"/> |
||||||
|
<entry key="calexUndistPrincipal" value="true"/> |
||||||
|
<entry key="calexTrans" value="0"/> |
||||||
|
<entry key="eiExportFileNaming" value="5"/> |
||||||
|
<entry key="calexHasDisabled" value="0x0"/> |
||||||
|
<entry key="eiExportMasks" value="true"/> |
||||||
|
<entry key="calexRequiresUndistortPrincipal" value="0x0"/> |
||||||
|
<entry key="calexRequiresEqualResolution" value="0x0"/> |
||||||
|
<entry key="calexDownscale" value="0x1"/> |
||||||
|
<entry key="calexUndistMaxPixels" value="-1"/> |
||||||
|
<entry key="eiExportImageListFileName" value="imageList.txt"/> |
||||||
|
<entry key="calexUndistFitMode" value="2"/> |
||||||
|
<entry key="eiFarPlaneDistance" value="1000000.0"/> |
||||||
|
<entry key="hasCalexFilePath" value="1"/> |
||||||
|
<entry key="calexHasUndistort" value="0"/> |
||||||
|
<entry key="calexFileFormat" value="Export Depth and Mask Images"/> |
||||||
|
<entry key="calexExportUndistorted" value="true"/> |
||||||
|
<entry key="calexFileFormatId" value="{0ABB46B2-4FAA-4CE1-AA39-D96128D39BD9}"/> |
||||||
|
<entry key="hasCalexFileName" value="0"/> |
||||||
|
<entry key="calexUndistCutOut" value="1.0"/> |
||||||
|
<entry key="calexHasImageExport" value="-1"/> |
||||||
|
<entry key="eiExportDepths" value="true"/> |
||||||
|
</Configuration> |
||||||
@ -0,0 +1,206 @@ |
|||||||
|
import os, sys, shutil, subprocess, shlex,oss2,requests |
||||||
|
sys.path.append('e:\\libs\\') |
||||||
|
import config |
||||||
|
import xml.etree.ElementTree as ET |
||||||
|
import common |
||||||
|
def is_already(pid): |
||||||
|
|
||||||
|
if not os.path.exists("D://make2/export_build_info/finished.txt"): |
||||||
|
#创建文件 |
||||||
|
with open("D://make2/export_build_info/finished.txt", 'w') as f: |
||||||
|
f.write("") |
||||||
|
return False |
||||||
|
#读取已经完成的pid |
||||||
|
with open("D://make2/export_build_info/finished.txt", 'r') as f: |
||||||
|
lines = f.readlines() |
||||||
|
for line in lines: |
||||||
|
if str(pid) == str(line.strip()): |
||||||
|
return True |
||||||
|
return False |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def writeImageList(pid): |
||||||
|
# pid = "185005" |
||||||
|
imageListTxt = f"D://{pid}/{pid}_imageList.txt" |
||||||
|
if not os.path.exists(imageListTxt): |
||||||
|
with open(imageListTxt, 'w') as f: |
||||||
|
f.write("") |
||||||
|
filePath = f"D://{pid}//{pid}.rcproj" |
||||||
|
tree = ET.parse(filePath) |
||||||
|
root = tree.getroot() |
||||||
|
fileName = [] |
||||||
|
for input_tag in root.findall(".//input"): |
||||||
|
tempFileName = input_tag.get("fileName") |
||||||
|
if tempFileName: |
||||||
|
fileName.append(tempFileName) |
||||||
|
sourceFileNames = [] |
||||||
|
for sourceFile in fileName: |
||||||
|
tempSourceName = sourceFile.replace(f"D:\{pid}\photo1\\","") |
||||||
|
tempSourceName = tempSourceName.replace(f"D:\{pid}\photo2\\","") |
||||||
|
print("tempSourceName",tempSourceName) |
||||||
|
#遍历指定的文件减价 |
||||||
|
for file in os.listdir(f"D://{pid}/depthAndMask"): |
||||||
|
if ".jpg.depth.exr" not in file: |
||||||
|
continue |
||||||
|
#截取图片名称 |
||||||
|
tempName = file.replace(".depth.exr","") |
||||||
|
if tempName == tempSourceName: |
||||||
|
#sourceFileNames.append(sourceFile) |
||||||
|
#写入到文件中 |
||||||
|
print(f"写入到文件-{sourceFile}") |
||||||
|
with open(imageListTxt, 'a+') as f: |
||||||
|
f.write(f"{sourceFile}\n") |
||||||
|
|
||||||
|
|
||||||
|
def exportInfo(pid): |
||||||
|
newCopyFilePath = f"D://{pid}/{pid}.rcproj" |
||||||
|
#判断是否存在目录,不存在则创建 |
||||||
|
depthMaskPath = f"D://{pid}/depthAndMask" |
||||||
|
#删除文件夹 |
||||||
|
try: |
||||||
|
shutil.rmtree(depthMaskPath) |
||||||
|
except Exception as e: |
||||||
|
print(e) |
||||||
|
|
||||||
|
|
||||||
|
if not os.path.exists(f"D://{pid}/depthAndMask"): |
||||||
|
os.makedirs(f"D://{pid}/depthAndMask") |
||||||
|
|
||||||
|
imageListTxt = f"D://{pid}/{pid}_imageList.txt" |
||||||
|
try: |
||||||
|
os.remove(imageListTxt) |
||||||
|
except Exception as e: |
||||||
|
print(e) |
||||||
|
|
||||||
|
if not os.path.exists(imageListTxt): |
||||||
|
with open(imageListTxt, 'w') as f: |
||||||
|
f.write("") |
||||||
|
|
||||||
|
maskPath = f"D://{pid}/mask" |
||||||
|
|
||||||
|
try: |
||||||
|
shutil.rmtree(maskPath) |
||||||
|
except Exception as e: |
||||||
|
print(f"删除文件夹失败{e}") |
||||||
|
if not os.path.exists(f"D://{pid}/mask"): |
||||||
|
os.makedirs(f"D://{pid}/mask") |
||||||
|
|
||||||
|
depthPath = f"D://{pid}/depth" |
||||||
|
try: |
||||||
|
shutil.rmtree(depthPath) |
||||||
|
except Exception as e: |
||||||
|
print(e) |
||||||
|
|
||||||
|
if not os.path.exists(f"D://{pid}/depth"): |
||||||
|
os.makedirs(f"D://{pid}/depth") |
||||||
|
|
||||||
|
registrationPath = f"D://{pid}/reg" |
||||||
|
try: |
||||||
|
shutil.rmtree(registrationPath) |
||||||
|
except Exception as e: |
||||||
|
print(e) |
||||||
|
if not os.path.exists(registrationPath): |
||||||
|
os.makedirs(registrationPath) |
||||||
|
|
||||||
|
#如果存在则执行打开命令 |
||||||
|
cmd = f'{config.rcbin} {config.r2["init"]} -setInstanceName {pid} -load "{newCopyFilePath}" -exportRegistration "D://{pid}/reg/{pid}_registration.out" "D://make2/config/registration_export_config.xml" -exportDepthAndMask "D://{pid}/depthAndMask" "D://make2/config/depth_mask_config.xml" -quit' |
||||||
|
# print(cmd) |
||||||
|
cmd = shlex.split(cmd) |
||||||
|
res = subprocess.run(cmd) |
||||||
|
|
||||||
|
writeImageList(pid) |
||||||
|
|
||||||
|
#删除掉 depthMaskPath 里 文件名 包含 _1. 的文件 |
||||||
|
for file in os.listdir(depthMaskPath): |
||||||
|
#将遍历出来的文件名进行判断,如果是_8.jpg.mask _1.jpg.mask 写入到pid_imgList.txt中 |
||||||
|
# if "_8.jpg.mask" in file: |
||||||
|
# jpgPath = f"D://{pid}/photo2/"+file.replace(".mask", "") |
||||||
|
# jpgPath = jpgPath.replace(".png", "") |
||||||
|
# print("_8",jpgPath) |
||||||
|
# with open(imageListTxt, 'a+') as f: |
||||||
|
# f.write(f"{jpgPath}\n") |
||||||
|
|
||||||
|
# if "_1.jpg.mask" in file: |
||||||
|
# jpgPath = f"D://{pid}/photo1/"+file.replace(".mask", "") |
||||||
|
# jpgPath = jpgPath.replace(".png", "") |
||||||
|
# print("_1",jpgPath) |
||||||
|
# with open(imageListTxt, 'a+') as f: |
||||||
|
# f.write(f"{jpgPath}\n") |
||||||
|
|
||||||
|
if "_1." in file: |
||||||
|
os.remove(f"{depthMaskPath}/{file}") |
||||||
|
|
||||||
|
if "_8.jpg.mask" in file: |
||||||
|
try: |
||||||
|
shutil.move(f"{depthMaskPath}/{file}",maskPath) |
||||||
|
except Exception as e: |
||||||
|
print(f"移动文件失败1{e}") |
||||||
|
|
||||||
|
|
||||||
|
if "_8.jpg.depth" in file: |
||||||
|
try: |
||||||
|
shutil.move(f"{depthMaskPath}/{file}",depthPath) |
||||||
|
except Exception as e: |
||||||
|
print(f"移动文件失败2{e}") |
||||||
|
|
||||||
|
|
||||||
|
writeImageList(str(pid)) |
||||||
|
|
||||||
|
#删除已存在数据,防止版本冲突 |
||||||
|
try: |
||||||
|
deleteList = [] |
||||||
|
for obj in oss2.ObjectIterator(config.oss_bucket,prefix=f'objs/auto/{pid}/model_info_v2'): |
||||||
|
deleteList.append(obj.key) |
||||||
|
config.oss_bucket.batch_delete_objects(deleteList) |
||||||
|
except Exception as e: |
||||||
|
print("") |
||||||
|
|
||||||
|
#上传到oss 上 |
||||||
|
#将 D:\{pid}\{pid}_registration.out 上传到 oss model_info |
||||||
|
config.oss_bucket.put_object_from_file(f'objs/auto/{pid}/model_info_v2/{pid}_registration.out', f'D://{pid}/reg/{pid}_registration.out') |
||||||
|
# imageList.txt |
||||||
|
config.oss_bucket.put_object_from_file(f'objs/auto/{pid}/model_info_v2/{pid}_imageList.txt', imageListTxt) |
||||||
|
if os.path.exists(f"{depthMaskPath}/imageList.txt"): |
||||||
|
config.oss_bucket.put_object_from_file(f'objs/auto/{pid}/model_info_v2/imageList.txt', f"{depthMaskPath}/imageList.txt") |
||||||
|
# depth 和 mask 上传 |
||||||
|
print("上传 mask") |
||||||
|
for file in os.listdir(maskPath): |
||||||
|
config.oss_bucket.put_object_from_file(f'objs/auto/{pid}/model_info_v2/mask/{file}', f"{maskPath}/{file}") |
||||||
|
|
||||||
|
print("上传 depth") |
||||||
|
for file in os.listdir(depthPath): |
||||||
|
config.oss_bucket.put_object_from_file(f'objs/auto/{pid}/model_info_v2/depth/{file}', f"{depthPath}/{file}") |
||||||
|
|
||||||
|
#上传几遍照片 |
||||||
|
print("上传 reg") |
||||||
|
for file in os.listdir(registrationPath): |
||||||
|
if "_1.jpg" in file: |
||||||
|
config.oss_bucket.put_object_from_file(f'objs/auto/{pid}/model_info_v2/reg/photo1/{file}', f"{registrationPath}/{file}") |
||||||
|
|
||||||
|
if "_8.jpg" in file: |
||||||
|
config.oss_bucket.put_object_from_file(f'objs/auto/{pid}/model_info_v2/reg/photo2/{file}', f"{registrationPath}/{file}") |
||||||
|
|
||||||
|
tempFile = f"D://{pid}//finish.txt" |
||||||
|
#创建文件 |
||||||
|
with open(tempFile, 'w') as f: |
||||||
|
f.write("") |
||||||
|
|
||||||
|
print(f"完成的PID-{pid}") |
||||||
|
|
||||||
|
|
||||||
|
#写入到指定的文件中 |
||||||
|
with open("D://make2/pid.text", 'a+') as f: |
||||||
|
f.write(f"{pid},") |
||||||
|
|
||||||
|
#删除文件 |
||||||
|
# common.removeFolder(str(pid)) |
||||||
|
# shutil.rmtree(f"D://{pid}",ignore_errors=True) |
||||||
|
|
||||||
|
#插入队列 |
||||||
|
tempUrl = "https://mp.api.suwa3d.com/api/customerP3dLog/addGaussianRedisQueneu?pid="+str(pid) |
||||||
|
requests.get(tempUrl) |
||||||
|
|
||||||
|
# exportInfo("181593") |
||||||
@ -0,0 +1,90 @@ |
|||||||
|
146134 |
||||||
|
146134 |
||||||
|
146598 |
||||||
|
183716 |
||||||
|
185381 |
||||||
|
183400 |
||||||
|
187752 |
||||||
|
184871 |
||||||
|
184956 |
||||||
|
185326 |
||||||
|
187651 |
||||||
|
187802 |
||||||
|
187811 |
||||||
|
187800 |
||||||
|
183096 |
||||||
|
187804 |
||||||
|
184956 |
||||||
|
187808 |
||||||
|
187898 |
||||||
|
187865 |
||||||
|
187870 |
||||||
|
187886 |
||||||
|
187912 |
||||||
|
185102 |
||||||
|
185102 |
||||||
|
185102 |
||||||
|
187450 |
||||||
|
185102 |
||||||
|
187989 |
||||||
|
188170 |
||||||
|
188117 |
||||||
|
188128 |
||||||
|
188200 |
||||||
|
188297 |
||||||
|
188310 |
||||||
|
188344 |
||||||
|
185101 |
||||||
|
188425 |
||||||
|
188428 |
||||||
|
188431 |
||||||
|
188560 |
||||||
|
188494 |
||||||
|
188564 |
||||||
|
188757 |
||||||
|
188779 |
||||||
|
188807 |
||||||
|
188865 |
||||||
|
188827 |
||||||
|
188910 |
||||||
|
188907 |
||||||
|
188913 |
||||||
|
188942 |
||||||
|
188964 |
||||||
|
189045 |
||||||
|
189051 |
||||||
|
189203 |
||||||
|
189214 |
||||||
|
189218 |
||||||
|
189228 |
||||||
|
189246 |
||||||
|
189242 |
||||||
|
189373 |
||||||
|
189312 |
||||||
|
189388 |
||||||
|
189913 |
||||||
|
189911 |
||||||
|
189932 |
||||||
|
189946 |
||||||
|
189106 |
||||||
|
186427 |
||||||
|
186544 |
||||||
|
190092 |
||||||
|
190112 |
||||||
|
188681 |
||||||
|
190138 |
||||||
|
188688 |
||||||
|
189172 |
||||||
|
183292 |
||||||
|
189178 |
||||||
|
184093 |
||||||
|
183080 |
||||||
|
189608 |
||||||
|
189625 |
||||||
|
189618 |
||||||
|
189170 |
||||||
|
189623 |
||||||
|
190151 |
||||||
|
183309 |
||||||
|
190214 |
||||||
|
188521 |
||||||
@ -0,0 +1,124 @@ |
|||||||
|
import os, sys, time, shutil, subprocess, shlex, json,oss2 |
||||||
|
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 |
||||||
|
|
||||||
|
def upload_xmp(pid): |
||||||
|
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 上传xmp文件之前先删除oss上的xmp文件所在目录...') |
||||||
|
pid = str(pid) |
||||||
|
psid = libs.getPSid(pid) |
||||||
|
#移除掉旧的文件夹 |
||||||
|
#config.oss_bucket.delete_object(f'xmps/{pid}/') |
||||||
|
#删除oss 上的文件夹里的内容 |
||||||
|
|
||||||
|
#判断是否存在该目录 |
||||||
|
if config.oss_bucket.object_exists(f'xmps/{psid}/') == True: |
||||||
|
object_list = oss2.ObjectIterator(config.oss_bucket, prefix=f'xmps/{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) |
||||||
|
##psid = libs.getPSid(pid) |
||||||
|
config.oss_bucket.put_object_from_file(f'xmps/{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/{psid}/mesh/{xmp}', os.path.join(workdir, 'photo1', xmp)) |
||||||
|
for xmp in os.listdir(os.path.join(workdir, 'photo2')): |
||||||
|
if xmp.endswith('.xmp'): |
||||||
|
config.oss_bucket.put_object_from_file(f'xmps/{psid}/texture/{xmp}', os.path.join(workdir, 'photo2', xmp)) |
||||||
|
|
||||||
|
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} xmp文件上传完成,共费时{time.time() - start_time}秒') |
||||||
|
|
||||||
|
def main(pid, lock=False): |
||||||
|
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 开始计算相机位姿...') |
||||||
|
start_time = time.time() |
||||||
|
libs.down_from_oss(config.oss_bucket, config.workdir, pid) |
||||||
|
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} {pid} 图片下载完成,共费时{libs.diff_time(start_time)}') |
||||||
|
|
||||||
|
start_time = time.time() |
||||||
|
photo1_path = os.path.join(config.workdir, pid, 'photo1') |
||||||
|
photo2_path = os.path.join(config.workdir, pid, 'photo2') |
||||||
|
photos1_count = len(os.listdir(photo1_path)) |
||||||
|
photos2_count = len(os.listdir(photo2_path)) |
||||||
|
# if photos1_count + photos2_count < 164: |
||||||
|
# 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) |
||||||
|
|
||||||
|
if lock: |
||||||
|
exportxmp = ' -exportXMP "D:\\make2\\config\\exportXMP.config.lock.xml" ' |
||||||
|
else: |
||||||
|
exportxmp = ' -exportXMP "D:\\make2\\config\\exportXMP.config.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")}" \ |
||||||
|
-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)}') |
||||||
|
|
||||||
|
# # TODO:加入report相机位姿质量评估 |
||||||
|
# if not lock: |
||||||
|
# upload_or_not = input('是否上传oss?(y/n)') |
||||||
|
# if upload_or_not == 'y': |
||||||
|
# upload_xmp(pid) |
||||||
|
# #上传坐标的话要判断该影棚是否走新的建模系统,如果不是走新的建模系统,就要更新为走新的建模系统 |
||||||
|
# libs_db.change_to_new_make_psid(psid) |
||||||
|
# print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} {pid} xmp文件上传完成,共费时{libs.diff_time(start_time)}') |
||||||
|
|
||||||
|
# delete_or_not = input('是否删除本地文件?(y/n)') |
||||||
|
# if delete_or_not == 'y': |
||||||
|
# shutil.rmtree(os.path.join(config.workdir, pid)) |
||||||
|
# print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} {pid} 本地文件已删除') |
||||||
|
# else: |
||||||
|
# print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} {pid} 本地文件未删除') |
||||||
|
|
||||||
|
if __name__ == '__main__': |
||||||
|
if len(sys.argv) == 2: |
||||||
|
pids = sys.argv[1].split(',') |
||||||
|
for pid in pids: |
||||||
|
main(pid) |
||||||
|
elif len(sys.argv) == 3: |
||||||
|
pids = sys.argv[1].split(',') |
||||||
|
for pid in pids: |
||||||
|
if sys.argv[2] == 'lock': |
||||||
|
main(pid, lock=True) |
||||||
|
else: |
||||||
|
main(pid, lock=False) |
||||||
|
else: |
||||||
|
print(f'useage: python {sys.argv[0]} pid1,pid2,pid3 [lock]') |
||||||
|
sys.exit(1) |
||||||
@ -0,0 +1,340 @@ |
|||||||
|
import os, sys, time, shlex, subprocess, shutil, requests, cv2, numpy as np |
||||||
|
from PIL import Image |
||||||
|
import platform,socket,atexit |
||||||
|
if platform.system() == 'Windows': |
||||||
|
sys.path.append('e:\\libs\\') |
||||||
|
#sys.path.append('libs') |
||||||
|
else: |
||||||
|
sys.path.append('/data/deploy/make3d/make2/libs/') |
||||||
|
import config, libs, libs_db,main_service_db,common |
||||||
|
|
||||||
|
def filter_dark_texture_image(pid): |
||||||
|
start_time = time.time() |
||||||
|
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 开始检测射灯异常图片...') |
||||||
|
def get_image_v(image): |
||||||
|
# 图片左上角和右上角各取200*200区域,计算V通道均值 |
||||||
|
left_rect = image[0:200, 0:200] |
||||||
|
right_rect = image[0:200, -200:] |
||||||
|
|
||||||
|
left_hsv = cv2.cvtColor(left_rect, cv2.COLOR_BGR2HSV) |
||||||
|
left_v = left_hsv[:, :, 2] |
||||||
|
left_avg_v = np.mean(left_v) |
||||||
|
# print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 图片左上角V通道均值:{left_avg_v}') |
||||||
|
|
||||||
|
right_hsv = cv2.cvtColor(right_rect, cv2.COLOR_BGR2HSV) |
||||||
|
right_v = right_hsv[:, :, 2] |
||||||
|
right_avg_v = np.mean(right_v) |
||||||
|
# print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 图片右上角V通道均值:{right_avg_v}') |
||||||
|
|
||||||
|
return (left_avg_v + right_avg_v) / 2 |
||||||
|
|
||||||
|
v_list = [] |
||||||
|
for filename in os.listdir(os.path.join(config.workdir, pid, 'photo2')): |
||||||
|
if filename.endswith(".jpg"): |
||||||
|
image = cv2.imread(os.path.join(config.workdir, pid, 'photo2', filename)) |
||||||
|
v = get_image_v(image) |
||||||
|
item = {'filename': filename, 'v': v} |
||||||
|
v_list.append(item) |
||||||
|
v_list.sort(key=lambda x: x['v']) |
||||||
|
v_list = v_list[5: -5] |
||||||
|
avg_v = np.mean([item['v'] for item in v_list]) |
||||||
|
for item in v_list: |
||||||
|
if abs(item['v'] - avg_v) > 50: |
||||||
|
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 图片{item["filename"]} V通道值{item["v"]},低于平均值{avg_v},将不参与贴图') |
||||||
|
libs.set_photo_join_type(config.workdir, pid, 'photo2', item['filename'].split('_')[0], mesh='1', texture='0') |
||||||
|
|
||||||
|
# 复制xmp文件到photo3目录,如果photo3目录存在的话 |
||||||
|
if os.path.exists(os.path.join(config.workdir, pid, 'photo3')): |
||||||
|
shutil.copyfile(os.path.join(config.workdir, pid, 'photo2', item['filename'].replace('jpg', 'xmp')), os.path.join(config.workdir, pid, 'photo3', item['filename'].replace('jpg', 'xmp'))) |
||||||
|
|
||||||
|
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 射灯异常图片检测完成,共费时{libs.diff_time(start_time)}') |
||||||
|
|
||||||
|
def detect_markers(psid, pid): |
||||||
|
def fix_region(): |
||||||
|
region_filename = os.path.join(config.workdir, pid, f'{pid}.rcbox') |
||||||
|
with open(region_filename, 'r') as f: |
||||||
|
lines = f.readlines() |
||||||
|
lines = [line.replace('"NONE" globalCoordinateSystemWkt="NONE" globalCoordinateSystemName="NONE"', '"+proj=geocent +ellps=WGS84 +no_defs" globalCoordinateSystemName="local:1 - Euclidean"') for line in lines] |
||||||
|
|
||||||
|
start_time = time.time() |
||||||
|
add_photo3 = ' ' |
||||||
|
textpicCmd = ' ' |
||||||
|
if os.path.exists(os.path.join(config.workdir, pid, 'photo3')): |
||||||
|
add_photo3 = ' -addFolder "' + os.path.join(config.workdir, pid, 'photo3') + '" ' |
||||||
|
|
||||||
|
textpicCmd ='-selectImage "'+os.path.join(config.workdir,pid,'photo3')+'\*" -enableTexturingAndColoring true' |
||||||
|
textpicCmd ='-selectImage "'+os.path.join(config.workdir,pid,'photo2')+'\*" -enableTexturingAndColoring false' |
||||||
|
else: |
||||||
|
textpicCmd ='-selectImage "'+os.path.join(config.workdir,pid,'photo2')+'\*" -enableTexturingAndColoring true' |
||||||
|
|
||||||
|
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")}" {config.r["setTextureFalse"]} -align -addFolder "{os.path.join(config.workdir, pid, "photo2")}" \ |
||||||
|
{add_photo3} -align -selectAllImages \ |
||||||
|
-detectMarkers "D:\\make2\\config\\detectMarkers.config.xml" \ |
||||||
|
{libs.get_defineDistances(psid)} -align -align -update {config.r2["setRegion"]} \ |
||||||
|
-exportXMP "D:\\make2\\config\\exportXMP.config.xml" \ |
||||||
|
-exportControlPointsMeasurements "{os.path.join(config.workdir, pid, f"{pid}.controlPoints.csv")}" "D:\\make2\\config\\exportControlPoints.config.xml" \ |
||||||
|
-exportReconstructionRegion "{os.path.join(config.workdir, pid, f"{pid}.rcbox")}" \ |
||||||
|
{textpicCmd} -save "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}" -quit' |
||||||
|
print(cmd) |
||||||
|
cmd = shlex.split(cmd) |
||||||
|
res = subprocess.run(cmd) |
||||||
|
time.sleep(3) |
||||||
|
fix_region() |
||||||
|
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 定位点检测完成, 共费时{libs.diff_time(start_time)}') |
||||||
|
|
||||||
|
if os.path.exists(os.path.join(config.workdir, pid, 'photo3')): |
||||||
|
for filename in os.listdir(os.path.join(config.workdir, pid, 'photo2')): |
||||||
|
if filename.endswith('_8.xmp'): |
||||||
|
# photo3 exist, 设置photo2的xmp文件,不参与贴图 |
||||||
|
libs.set_photo_join_type(config.workdir, pid, 'photo2', filename.split('_')[0], mesh='1', texture='0') |
||||||
|
for filename in os.listdir(os.path.join(config.workdir, pid, 'photo3')): |
||||||
|
if filename.endswith('_8.xmp'): |
||||||
|
# photo3 exist, 设置photo3的xmp文件,不参与建模 |
||||||
|
libs.set_photo_join_type(config.workdir, pid, 'photo3', filename.split('_')[0], mesh='0', texture='1') |
||||||
|
|
||||||
|
def step1(pid, experience=False, makeloop=True,task_distributed_id="",isNoColorTexture=""): |
||||||
|
libs_db.start_task({"task_type": "make", "task_key": pid}) |
||||||
|
|
||||||
|
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 开始处理{pid}建模任务') |
||||||
|
psid = libs.getPSid(pid) |
||||||
|
|
||||||
|
# 更新云端任务状态 |
||||||
|
res = requests.post(config.urls['update_status_modeling_url'], data={'id': pid}) |
||||||
|
print('更新建模中状态:', res.text) |
||||||
|
|
||||||
|
# 下载图片 |
||||||
|
start_time = time.time() |
||||||
|
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} {pid} 开始下载图片...') |
||||||
|
libs.down_from_oss(config.oss_bucket, config.workdir, pid) |
||||||
|
try: |
||||||
|
if str(psid) == "86": |
||||||
|
#移除指定文件 |
||||||
|
os.remove(f"D:\{pid}\photo1\\21_1.jpg") |
||||||
|
os.remove(f"D:\{pid}\photo2\\21_8.jpg") |
||||||
|
if str(psid) == "29": |
||||||
|
#移除指定文件 |
||||||
|
os.remove(f"D:\{pid}\photo1\\15_1.jpg") |
||||||
|
os.remove(f"D:\{pid}\photo2\\15_8.jpg") |
||||||
|
except Exception as e: |
||||||
|
print("移除异常") |
||||||
|
|
||||||
|
#旋转图片 |
||||||
|
os.system(f'python D:\\make2\\photo2rotate.py -w d:\ -p {pid} -i photo1 -o photo1') |
||||||
|
os.system(f'python D:\\make2\\photo2rotate.py -w d:\ -p {pid} -i photo2 -o photo2') |
||||||
|
|
||||||
|
os.system(f'python D:\\make2\\export_build_info\\gen_xmps_for_build_info.py {pid}') |
||||||
|
#print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} {pid} 图片下载完成,共费时{libs.diff_time(start_time)}') |
||||||
|
os.system(f'python main_step2.py {pid}') |
||||||
|
# start_time = time.time() |
||||||
|
# # TODO: 上报图片采集数量,更新影棚相机状态 |
||||||
|
|
||||||
|
# # 处理图片,如果experience=True,将图片缩减一半,已节省建模时间和算力成本 |
||||||
|
# # if experience: |
||||||
|
# # libs.resize_photos(os.path.join(config.workdir, pid, 'photo1')) |
||||||
|
# # libs.resize_photos(os.path.join(config.workdir, pid, 'photo2')) |
||||||
|
|
||||||
|
# # 根据配置调整photo2曝光,均衡贴图亮度,可能产生photo3 |
||||||
|
# libs.adjust_photos(config.workdir, pid) |
||||||
|
|
||||||
|
# # TODO: 检测模糊异常图片,上报微信通知 |
||||||
|
# # TODO: 处理图片,去反光算法 |
||||||
|
|
||||||
|
# # 检测图片定位点,定位异常及时上报微信通知给客服人员,人工判断是否需要重新拍摄或更换地贴。定义定位点距离,导出相机位姿信息 |
||||||
|
# detect_markers(psid, pid) |
||||||
|
|
||||||
|
# # 处理图片,检测photo2中的异常图片不参与贴图,以免破坏贴图效果,默认不检测射灯异常图片,以节省算力成本 |
||||||
|
# if not makeloop: |
||||||
|
# filter_dark_texture_image(pid) |
||||||
|
|
||||||
|
# # 处理图片,暗部提亮,提高贴图效果 |
||||||
|
|
||||||
|
# # TODO: 处理图片,去遮挡处理,提高建模与贴图质量 |
||||||
|
|
||||||
|
# # 加入photo2,计算重建区域,导出重建区域与相机位姿配置信息 |
||||||
|
# # cal_reconstruction_region(psid, pid) |
||||||
|
|
||||||
|
# print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} {pid} step1图片预处理完成,共费时{libs.diff_time(start_time)}') |
||||||
|
|
||||||
|
# if os.path.exists(os.path.join(config.sharedir, pid)): |
||||||
|
# shutil.rmtree(os.path.join(config.sharedir, pid), ignore_errors=True) |
||||||
|
# shutil.copytree(os.path.join(config.workdir, pid), os.path.join(config.sharedir, pid)) |
||||||
|
# print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} {pid} step1任务完成,移动到共享目录') |
||||||
|
|
||||||
|
|
||||||
|
# #指定photo2某些图片不参与贴图 |
||||||
|
# #是否不参与贴图,true 不参与贴图 |
||||||
|
# if isNoColorTexture == "NoColorTexture": |
||||||
|
# arrNoTextureColorPics = config.noTextureColorPics |
||||||
|
# if arrNoTextureColorPics is not None and len(arrNoTextureColorPics) > 0: |
||||||
|
# for camcerIndex in arrNoTextureColorPics: |
||||||
|
# #拼装坐标文件名称 |
||||||
|
# filename = os.path.join(config.sharedir, pid,"photo2",str(camcerIndex)+"_8.xmp") |
||||||
|
# #判断文件是否存在 |
||||||
|
# if os.path.exists(filename): |
||||||
|
# #存在就设置不参与贴图 |
||||||
|
# libs.set_photo_join_type(config.workdir, pid, 'photo2', camcerIndex, mesh='0', texture='0') |
||||||
|
|
||||||
|
|
||||||
|
# #移除当前文件夹 |
||||||
|
# shutil.rmtree(os.path.join(config.workdir, pid)) |
||||||
|
# # TODO: 更新本地step1任务状态,加入step2任务队列 |
||||||
|
# if task_distributed_id == "":#不是分布式任务的时候就自动往下个步骤走,是分布式任务的时候就就执行当前任务 |
||||||
|
# if makeloop: |
||||||
|
# os.system(f'python main_step2.py {pid}') |
||||||
|
# else: |
||||||
|
# os.system(f'python main_step2.py {pid}') |
||||||
|
# # if os.path.exists(os.path.join(config.sharedir, pid)): |
||||||
|
# # shutil.rmtree(os.path.join(config.sharedir, pid), ignore_errors=True) |
||||||
|
# # shutil.move(os.path.join(config.workdir, pid), config.sharedir) |
||||||
|
|
||||||
|
# # print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} {pid} step1任务完成,移动到共享目录') |
||||||
|
# else: |
||||||
|
# #分布式服务执行完后,需要更新任务状态,更新字表的finished_at字段 |
||||||
|
# main_service_db.update_task_distributed_detail({"task_distributed_id":task_distributed_id,"finished_at":time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}) |
||||||
|
# print("step1完成,休息6s") |
||||||
|
# time.sleep(4) |
||||||
|
# return |
||||||
|
|
||||||
|
|
||||||
|
def main(pid, experience=False, makeloop=True,task_distributed_id="",isNoColorTexture=""): |
||||||
|
if pid == '0': |
||||||
|
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 开始进入本地任务值守模式...') |
||||||
|
while True: |
||||||
|
# 取云端redis多个key任务,TODO:后续要改为api调用 |
||||||
|
experience = False |
||||||
|
pid = libs_db.get_task('make_experience') |
||||||
|
if pid == '': |
||||||
|
time.sleep(3) |
||||||
|
pid = libs_db.get_task('make') |
||||||
|
if pid == '': |
||||||
|
time.sleep(3) |
||||||
|
continue |
||||||
|
else: |
||||||
|
experience = False |
||||||
|
step1(pid, experience, makeloop,task_distributed_id,isNoColorTexture) |
||||||
|
else: |
||||||
|
step1(pid, experience, makeloop,task_distributed_id,isNoColorTexture) |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def is_already(pid): |
||||||
|
|
||||||
|
|
||||||
|
#读取已经完成的pid |
||||||
|
with open("D://make2/export_build_info/finished.txt", 'r') as f: |
||||||
|
lines = f.readlines() |
||||||
|
for line in lines: |
||||||
|
print("line",str(line.strip())) |
||||||
|
if str(pid) == str(line.strip()): |
||||||
|
print("匹配成功") |
||||||
|
return True |
||||||
|
return False |
||||||
|
|
||||||
|
if __name__ == '__main__': |
||||||
|
isNoColorTexture = "" |
||||||
|
if len(sys.argv) == 2: |
||||||
|
v = sys.argv[1] |
||||||
|
|
||||||
|
#判断是否是数字 |
||||||
|
if v.isdigit(): |
||||||
|
#print(f"正在处理输入的pid-{v}") |
||||||
|
main(str(v), experience=False, makeloop=False,task_distributed_id="",isNoColorTexture=isNoColorTexture) |
||||||
|
else: |
||||||
|
filePath = f"D://make2/export_build_info/pids/{v}.txt" |
||||||
|
if not os.path.exists(filePath): |
||||||
|
print(f"{filePath} 文件不存在") |
||||||
|
|
||||||
|
strPids = "" |
||||||
|
with open("D://make2/pid.text","r") as f: |
||||||
|
lines = f.readlines() |
||||||
|
for line in lines: |
||||||
|
strPids = str(line.strip()) |
||||||
|
|
||||||
|
errPids = "" |
||||||
|
with open("D://make2/errPid.text","r") as f: |
||||||
|
lines = f.readlines() |
||||||
|
for line in lines: |
||||||
|
errPids = str(line.strip()) |
||||||
|
|
||||||
|
arrErrPids = errPids.split(",") |
||||||
|
|
||||||
|
arrPids = strPids.split(",") |
||||||
|
ii = 0 |
||||||
|
with open(filePath, 'r') as f: |
||||||
|
lines = f.readlines() |
||||||
|
for line in lines: |
||||||
|
pid = str(line.strip()) |
||||||
|
if pid == "": |
||||||
|
break |
||||||
|
|
||||||
|
#判断是否存在了目录或者已经是处理过了 |
||||||
|
# tempFile = f"D://{pid}//finish.txt" |
||||||
|
# if os.path.exists(tempFile): |
||||||
|
# continue |
||||||
|
|
||||||
|
if str(pid) in arrErrPids: |
||||||
|
continue |
||||||
|
|
||||||
|
if str(pid) in arrPids: |
||||||
|
# print(f"已处理过{pid}") |
||||||
|
ii += 1 |
||||||
|
continue |
||||||
|
|
||||||
|
print(f"正在处理{pid}- 完成{ii}") |
||||||
|
main(str(pid), experience=False, makeloop=False,task_distributed_id="",isNoColorTexture=isNoColorTexture) |
||||||
|
ii += 1 |
||||||
|
print(f"已经完成-{ii}") |
||||||
|
|
||||||
|
|
||||||
|
else: |
||||||
|
print("cmd like python main_step1.py pid/单人/多人/双人/动物/人物") |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# # 取云端redis任务,完成第一步的数据预处理后,将数据放入共享存储目录,将第二步任务塞入本地mysql队列 |
||||||
|
# # 默认循环值守,可传参数运行单一任务,以方便调试 |
||||||
|
# #atexit.register(common.notify,socket.gethostname()+"建模任务已经停止") |
||||||
|
# # pid = '0' |
||||||
|
# isNoColorTexture = "" |
||||||
|
# # if len(sys.argv) == 2: |
||||||
|
# # pids = sys.argv[1].split(',') |
||||||
|
# # for pid in pids: |
||||||
|
# already = [184219,184215,184209,184069,184059,183868,183817,183791,183613,183054,182855,182854,184206,184201,184199,184164,184087,184076,184029,184013,183993,183952,183888,183882,183824,183815,183812] |
||||||
|
|
||||||
|
# arrPids = [184219,184215,184209,184206,184201,184199,184164,184087,184076,184069,184059,184029,184013,183993,183952,183888,183882,183868,183824,183817,183815,183812,183791,183777,183715,183705,183670,183613,183573,182974,182983,182985,182989,182997,183007,183051,183060,183054,183053,183097,183119,183108,183139,183141,183155,183163,183169,183180,183191,183196,183214,183244,183266,183278,183275,183309,183402,183422,183440,182974,182964,182958] |
||||||
|
# #,182956,182916,182855,182854,182820,182787,182800,182809,182780,182772,182770,182766,182754,182742,182740,182723,182707,182647,182643,182614,182595,182563,182557,182547,182546,182538,182530,182517,182498,182478,182452,182386,182352,182285,182266,182260,182230,182224 |
||||||
|
# i = 0 |
||||||
|
# for pid in arrPids: |
||||||
|
# if pid in already: |
||||||
|
# continue |
||||||
|
# print("正在处理-",pid) |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# if is_already(str(pid)) == True: |
||||||
|
# continue |
||||||
|
# # i += 1 |
||||||
|
# # continue |
||||||
|
# #写入到 |
||||||
|
# with open("D://make2/export_build_info/finished.txt", 'a+') as f: |
||||||
|
# f.write(f"{pid}\n") |
||||||
|
|
||||||
|
# main(str(pid), experience=False, makeloop=False,task_distributed_id="",isNoColorTexture=isNoColorTexture) |
||||||
|
|
||||||
|
# print("已处理-",i) |
||||||
|
# #exit() |
||||||
|
# # if len(sys.argv) == 3: |
||||||
|
# # experience = False |
||||||
|
# # if sys.argv[2] == '1': |
||||||
|
# # print('演示测试...') |
||||||
|
# # experience = False |
||||||
|
# # elif sys.argv[2] == 'NoColorTexture': |
||||||
|
# # isNoColorTexture = "NoColorTexture" |
||||||
|
# # pids = sys.argv[1].split(',') |
||||||
|
# # for pid in pids: |
||||||
|
# # main(pid, experience=experience, makeloop=False,task_distributed_id="",isNoColorTexture=isNoColorTexture) |
||||||
|
# # exit() |
||||||
|
# # main(pid, experience=False, makeloop=True,task_distributed_id="",isNoColorTexture=isNoColorTexture) |
||||||
@ -0,0 +1,267 @@ |
|||||||
|
import os, sys, time, shutil, subprocess, shlex |
||||||
|
import platform |
||||||
|
import pyautogui as ag |
||||||
|
if platform.system() == 'Windows': |
||||||
|
sys.path.append('e:\\libs\\') |
||||||
|
#sys.path.append('libs') |
||||||
|
else: |
||||||
|
sys.path.append('/data/deploy/make3d/make2/libs/') |
||||||
|
import config, libs, libs_db,common,main_service_db,computerRecboxCenterByPoint |
||||||
|
import export_already_build |
||||||
|
redisLocal = config.redis_local |
||||||
|
def load_model(pid): |
||||||
|
cmd = f'{config.rcbin} {config.r1["init"]} -load "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}"' |
||||||
|
print(cmd) |
||||||
|
cmd = shlex.split(cmd) |
||||||
|
res = subprocess.run(cmd) |
||||||
|
|
||||||
|
def get_rcver(): |
||||||
|
rcbin = '"C:\\Program Files\\Capturing Reality\\RealityCapture\\RealityCapture.exe"' |
||||||
|
if os.path.getsize(rcbin[1:-1]) == 20783616: |
||||||
|
return 1 |
||||||
|
else: |
||||||
|
return 2 |
||||||
|
|
||||||
|
def make3d(pid): |
||||||
|
if get_rcver() == 1: # old version |
||||||
|
#修改重建区域的大小 |
||||||
|
common.change_rcbox_s(pid,"1") |
||||||
|
#获取影棚id |
||||||
|
# psid = libs.getPSid(pid) |
||||||
|
# if int(psid) == 80: |
||||||
|
# change_rcbox_deepth(str(pid),0.03) |
||||||
|
psid = libs.getPSid(pid) |
||||||
|
simplify_value = 1000000 * libs.getHeadCount(pid) |
||||||
|
add_photo3 = ' ' |
||||||
|
#判断是否存在photo3 |
||||||
|
if os.path.exists(os.path.join(config.workdir, pid, 'photo3')): |
||||||
|
add_photo3 = ' -addFolder "' + os.path.join(config.workdir, pid, 'photo3') + '" -align -align ' |
||||||
|
#存在photo3 的情况下,photo2 不参与贴图 |
||||||
|
#遍历获取photo2 目录下的所有文件 |
||||||
|
directory = os.path.join(config.workdir, pid, 'photo2') |
||||||
|
for root, dirs, files in os.walk(directory): |
||||||
|
for file in files: |
||||||
|
#判断file 是否以 _8.xmp 结尾 |
||||||
|
if file.endswith("_8.xmp") == False: |
||||||
|
continue |
||||||
|
#修改文件内容不参与贴图 |
||||||
|
libs.set_photo_join_type(config.workdir, pid, 'photo2', file.split("_")[0], mesh='0', texture='0') |
||||||
|
else: |
||||||
|
pass |
||||||
|
#设置photo2参与贴图,因为有的时候贴图会黑 |
||||||
|
directory = os.path.join(config.workdir, pid, 'photo2') |
||||||
|
for root, dirs, files in os.walk(directory): |
||||||
|
for file in files: |
||||||
|
#判断file 是否以 _8.xmp 结尾 |
||||||
|
if file.endswith("_8.xmp") == False: |
||||||
|
continue |
||||||
|
#修改文件内容不参与贴图 |
||||||
|
libs.set_photo_join_type(config.workdir, pid, 'photo2', file.split("_")[0], mesh='0', texture='1') |
||||||
|
|
||||||
|
if get_rcver() == 1: # old version |
||||||
|
|
||||||
|
#判断oss 上是否存在 controlpoints 文件 |
||||||
|
isExistPoint = common.isExistControlPointsOss(pid) |
||||||
|
cmd = f'{config.rcbin} {config.r1["init"]} \ |
||||||
|
-addFolder "{os.path.join(config.workdir, pid, "photo1")}" -addFolder "{os.path.join(config.workdir, pid, "photo2")}" {add_photo3} \ |
||||||
|
-importControlPointsMeasurements "{os.path.join(config.workdir, pid, f"{pid}.controlPoints.csv")}" \ |
||||||
|
-align -exportRegistration "{os.path.join(config.workdir,"make2", "config","exportRegistration.xml")}" "{os.path.join(config.workdir, pid,str(pid)+"_align.csv")}" -save' |
||||||
|
|
||||||
|
cmd = cmd + f' "{os.path.join(config.workdir, pid, f"{pid}_wait.rcproj")}"' |
||||||
|
print(cmd) |
||||||
|
cmd = shlex.split(cmd) |
||||||
|
res = subprocess.run(cmd) |
||||||
|
time.sleep(2) |
||||||
|
|
||||||
|
|
||||||
|
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 定位点导入完成') |
||||||
|
time.sleep(3) |
||||||
|
# defind_distance |
||||||
|
#死循环阻塞获取 |
||||||
|
while True: |
||||||
|
print("循环阻塞开始") |
||||||
|
time.sleep(3) |
||||||
|
#判断是否有 pid_1 的的值 |
||||||
|
print(pid+"_1") |
||||||
|
if redisLocal.lpos('model:auto_distance',pid+"_1") == None: |
||||||
|
continue |
||||||
|
shutil.move(os.path.join(config.workdir, pid, f'{pid}_wait.rcproj'), os.path.join(config.workdir, pid, f'{pid}.rcproj')) |
||||||
|
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 定义定位点距离完成') |
||||||
|
#将 controlpoints_0.dat 文件拷贝到 oss 上作为公共的使用 |
||||||
|
common.uploadControlPointsOss(pid) |
||||||
|
|
||||||
|
#最后处理掉redis中的值 |
||||||
|
redisLocal.lrem('model:auto_distance', 0, pid+"_1") |
||||||
|
break |
||||||
|
print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),"循环阻塞结束,判断是否对齐成功") |
||||||
|
|
||||||
|
|
||||||
|
#查看对齐的数量 |
||||||
|
alignRes = common.isAlignNums(str(pid)) |
||||||
|
if alignRes == "rebuild": |
||||||
|
os.system(f'python d:\\make2\\tools\push_cmd.py rebuild {pid}') |
||||||
|
os.system(f'python d:\\make2\\main_service.py') |
||||||
|
return |
||||||
|
#区域的设置 建模 |
||||||
|
#update |
||||||
|
cmdSmall = "-align" |
||||||
|
#使用公共point文件的时候,就不能使用update , 而是要用 align |
||||||
|
if isExistPoint == True: |
||||||
|
cmdSmall = "-align" |
||||||
|
#{config.r1["init"]} |
||||||
|
|
||||||
|
if common.task_need_high_model(pid): |
||||||
|
if str(psid) == "41" or str(psid) == "85": |
||||||
|
calulate_type = "-mvs" |
||||||
|
else: |
||||||
|
calulate_type = '-mvsHigh' |
||||||
|
else: |
||||||
|
calulate_type = '-mvs' |
||||||
|
|
||||||
|
#翻转相机的线向下 |
||||||
|
cmd = f'{config.rcbin} -load "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}" {cmdSmall} \ |
||||||
|
-set "sfmEnableCameraPrior=True" -align -set "sfmEnableCameraPrior=False" -align -save "{os.path.join(config.workdir, pid, f"{pid}_point.rcproj")}" ' |
||||||
|
cmd = shlex.split(cmd) |
||||||
|
res = subprocess.run(cmd) |
||||||
|
#执行完成后命令会触发导出点云的定时程序 |
||||||
|
while True: |
||||||
|
print("判断是否导出点云文件循环阻塞开始") |
||||||
|
time.sleep(3) |
||||||
|
#判断是否有 pid_1 的的值 |
||||||
|
print(pid+"_3") |
||||||
|
if redisLocal.lpos('model:auto_distance',pid+"_3") == None: |
||||||
|
continue |
||||||
|
shutil.move(os.path.join(config.workdir, pid, f'{pid}_point.rcproj'), os.path.join(config.workdir, pid, f'{pid}.rcproj')) |
||||||
|
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 导出点云文件完成') |
||||||
|
#最后处理掉redis中的值 |
||||||
|
redisLocal.lrem('model:auto_distance', 0, pid+"_3") |
||||||
|
break |
||||||
|
|
||||||
|
#处理点云文件 |
||||||
|
centerRcboxValue = computerRecboxCenterByPoint.boxCenter(pid) |
||||||
|
if centerRcboxValue > 0: |
||||||
|
print("修改中心点的坐标",centerRcboxValue) |
||||||
|
#修改中心点的值 |
||||||
|
common.change_rcbox_center(pid,centerRcboxValue) |
||||||
|
|
||||||
|
cmd = f'{config.rcbin} -load "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}" -align \ |
||||||
|
-set "sfmEnableCameraPrior=True" -align -set "sfmEnableCameraPrior=False" -align -setReconstructionRegion "{os.path.join(config.workdir, pid, f"{pid}.rcbox")}" \ |
||||||
|
{calulate_type} -modelSelectMaximalConnectedComponent -modelInvertSelection -modelRemoveSelectedTriangles -closeHoles -clean -simplify {simplify_value} -smooth -unwrap -calculateTexture -renameModel {pid} -save "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}" -quit' |
||||||
|
print(cmd) |
||||||
|
cmd = shlex.split(cmd) |
||||||
|
res = subprocess.run(cmd) |
||||||
|
#保存在导出 |
||||||
|
# common.saveScreenImg(pid) |
||||||
|
# time.sleep(1) |
||||||
|
# ag.hotkey('alt', 'f4') |
||||||
|
time.sleep(3) |
||||||
|
#修改rcproj文件 |
||||||
|
flag = common.changeRcprojFile(pid) |
||||||
|
if flag == False: |
||||||
|
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} rcproj文件不存在') |
||||||
|
return |
||||||
|
|
||||||
|
#复制文件 |
||||||
|
shutil.copy(os.path.join(config.workdir, pid, f'{pid}.rcproj'), os.path.join(config.workdir, pid, f'{pid}_screen.rcproj')) |
||||||
|
time.sleep(2) |
||||||
|
#打开工程文件 |
||||||
|
cmd = f'{config.rcbin} -load "{os.path.join(config.workdir, pid, f"{pid}_screen.rcproj")}"' |
||||||
|
cmd = shlex.split(cmd) |
||||||
|
res = subprocess.run(cmd) |
||||||
|
|
||||||
|
#创建指定文件夹 |
||||||
|
if not os.path.exists(os.path.join(config.workdir, pid, "output")): |
||||||
|
os.makedirs(os.path.join(config.workdir, pid, "output")) |
||||||
|
|
||||||
|
#判断output目录下是否有文件,有的话删除 |
||||||
|
files = os.listdir(os.path.join(config.workdir, pid, "output")) |
||||||
|
|
||||||
|
#执行导出 |
||||||
|
cmd = f'{config.rcbin} -load "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}"\ |
||||||
|
-exportModel "{pid}" "{os.path.join(config.workdir, pid, "output", f"{pid}.obj")}" "d:\\make2\\config\\ModelExportParams102.xml" -quit' |
||||||
|
print(cmd) |
||||||
|
cmd = shlex.split(cmd) |
||||||
|
res = subprocess.run(cmd) |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
else: # new version |
||||||
|
#判断是否要进行高精模 |
||||||
|
if common.task_need_high_model(pid): |
||||||
|
if str(psid) == "41" or str(psid) == "85": |
||||||
|
calulate_type = "calculateNormalModel" |
||||||
|
else: |
||||||
|
calulate_type = 'calculateHighModel' |
||||||
|
else: |
||||||
|
calulate_type = 'calculateNormalModel' |
||||||
|
|
||||||
|
#创建指定文件夹 |
||||||
|
if not os.path.exists(os.path.join(config.workdir, pid, "output")): |
||||||
|
os.makedirs(os.path.join(config.workdir, pid, "output")) |
||||||
|
|
||||||
|
cmd = f'{config.rcbin} {config.r2["init"]} -setInstanceName {pid} \ |
||||||
|
-load "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}" \ |
||||||
|
-{calulate_type} \ |
||||||
|
-selectLargestModelComponent -invertTrianglesSelection -removeSelectedTriangles -simplify {simplify_value} -smooth -closeHoles -cleanModel -calculateTexture \ |
||||||
|
-save "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}" \ |
||||||
|
-exportSelectedModel "{os.path.join(config.workdir, pid, "output", f"{pid}.obj")}" "d:\\make2\\config\\ModelExportParams.xml" -quit'# -quit |
||||||
|
print(cmd) |
||||||
|
cmd = shlex.split(cmd) |
||||||
|
res = subprocess.run(cmd) |
||||||
|
|
||||||
|
export_already_build.exportInfo(pid) |
||||||
|
# #阻塞判断是否导出完成 |
||||||
|
# while True: |
||||||
|
# #判断 output 目录下是否存在 三个文件 |
||||||
|
# files = os.listdir(os.path.join(config.workdir, pid, "output")) |
||||||
|
# if len(files) >= 3: |
||||||
|
# break |
||||||
|
|
||||||
|
def step2(pid,task_distributed_id=""): |
||||||
|
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 开始建模任务step2') |
||||||
|
|
||||||
|
#判断是否要从共享目录拷贝数据 |
||||||
|
if os.path.exists(os.path.join(config.sharedir, pid)) and not os.path.exists(os.path.join(config.workdir, pid)): |
||||||
|
shutil.move(os.path.join(config.sharedir, pid), config.workdir) |
||||||
|
else: |
||||||
|
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 目录{os.path.join(config.sharedir, pid)}不存在,或{os.path.join(config.workdir, pid)}已存在') |
||||||
|
# return |
||||||
|
#最后还是要判断有没有存在目录 |
||||||
|
if not os.path.exists(os.path.join(config.workdir, pid)): |
||||||
|
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 目录{os.path.join(config.workdir, pid)}不存在') |
||||||
|
return |
||||||
|
|
||||||
|
start_time = time.time() |
||||||
|
make3d(pid) |
||||||
|
|
||||||
|
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 建模任务step2完成,共费时{libs.diff_time(start_time)},任务已提交到step3') |
||||||
|
# # 更新本地任务状态,加入step3任务队列 |
||||||
|
# if task_distributed_id == "": |
||||||
|
# os.system(f'python d:\\make2\\main_step3.py {pid}') |
||||||
|
# else: |
||||||
|
# #暂时 step2 step3 一起连续执行 |
||||||
|
# print('step2 执行完,开始执行step3') |
||||||
|
# os.system(f'python d:\\make2\\main_step3.py {pid}') |
||||||
|
# main_service_db.update_task_distributed({"id":task_distributed_id,"status":2,"finished_at":time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}) |
||||||
|
# main_service_db.update_task_distributed_detail({"task_distributed_id":task_distributed_id,"finished_at":time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}) |
||||||
|
# #return |
||||||
|
|
||||||
|
def main(pid): |
||||||
|
if pid == '0': |
||||||
|
while True: |
||||||
|
# 取本地mysql队列任务,完成第二步的建模任务 |
||||||
|
|
||||||
|
step2(pid) |
||||||
|
else: |
||||||
|
step2(pid) |
||||||
|
|
||||||
|
if __name__ == '__main__': |
||||||
|
# 取本地mysql队列任务,完成第二步的建模任务 |
||||||
|
# 默认循环值守,可传参数运行单一任务,以方便调试 |
||||||
|
pid = '0' |
||||||
|
if len(sys.argv) > 1: |
||||||
|
pids = sys.argv[1].split(',') |
||||||
|
for pid in pids: |
||||||
|
main(pid) |
||||||
|
exit() |
||||||
|
main(pid) |
||||||
@ -0,0 +1,185 @@ |
|||||||
|
import os, sys, time, shlex, subprocess, shutil, requests, cv2, numpy as np |
||||||
|
from PIL import Image |
||||||
|
import platform |
||||||
|
if platform.system() == 'Windows': |
||||||
|
sys.path.append('e:\\libs\\') |
||||||
|
#sys.path.append('libs') |
||||||
|
else: |
||||||
|
sys.path.append('/data/deploy/make3d/make2/libs/') |
||||||
|
import config, libs, libs_db,main_service_db |
||||||
|
# 2. 手动操作建模做成建模 |
||||||
|
# 2.0 检测是否存在项目,不存在就下载,存在就清除项目其它无用的文件 |
||||||
|
# 2.1 初始化工程, 根据参数 加入 photo1 或者 photo 2 的 照片, 对齐 , 导出坐标, 将坐标复制到 另外一个文件夹, 测距, 重建区域, 然后调用step2 |
||||||
|
|
||||||
|
#根据pid 检测是否存在项目,不存在就下载,存在就清除项目其它无用的文件 |
||||||
|
def check_pid_file(pid): |
||||||
|
#检测是否存在目录 |
||||||
|
path = os.path.join(config.workdir, pid) |
||||||
|
if not os.path.exists(path): |
||||||
|
#不存在就在就下载目录 |
||||||
|
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 开始计算相机位姿...') |
||||||
|
start_time = time.time() |
||||||
|
libs.down_from_oss(config.oss_bucket, config.workdir, pid) |
||||||
|
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} {pid} 图片下载完成,共费时{libs.diff_time(start_time)}') |
||||||
|
else: |
||||||
|
#存在的话就检测是否有photo1 和 photo2 之外的目录或者文件,有的话就删除 |
||||||
|
for file in os.listdir(path): |
||||||
|
if file != 'photo1' and file != 'photo2': |
||||||
|
if os.path.isfile(os.path.join(path, file)): |
||||||
|
os.remove(os.path.join(path, file)) |
||||||
|
else: |
||||||
|
shutil.rmtree(os.path.join(path, file)) |
||||||
|
|
||||||
|
#判断photo1 和 photo2 目录里的文件是否存在xmp 文件,存在的话就删除 |
||||||
|
for file in os.listdir(os.path.join(path, 'photo1')): |
||||||
|
if file.endswith('.xmp'): |
||||||
|
os.remove(os.path.join(path, 'photo1', file)) |
||||||
|
|
||||||
|
for file in os.listdir(os.path.join(path, 'photo2')): |
||||||
|
if file.endswith('.xmp'): |
||||||
|
os.remove(os.path.join(path, 'photo2', file)) |
||||||
|
|
||||||
|
|
||||||
|
#根据参数初始化操作 |
||||||
|
def cmd_run(pid,usePhoto = "1",lock=False): |
||||||
|
pid = str(pid) |
||||||
|
#检测文件并且下载处理文件 |
||||||
|
check_pid_file(pid) |
||||||
|
|
||||||
|
start_time = time.time() |
||||||
|
#文件路径 |
||||||
|
photo1_path = os.path.join(config.workdir, pid, 'photo1') |
||||||
|
photo2_path = os.path.join(config.workdir, pid, 'photo2') |
||||||
|
#计算文件里的数量 |
||||||
|
photos1_count = len(os.listdir(photo1_path)) |
||||||
|
photos2_count = len(os.listdir(photo2_path)) |
||||||
|
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} {pid} photo1数量{photos1_count} photo2数量{photos2_count}') |
||||||
|
|
||||||
|
#xmp 坐标是要用 lock的 还是 unlock 的 |
||||||
|
if lock: |
||||||
|
exportxmp = ' -exportXMP "D:\\make2\\config\\exportXMP.config.lock.xml" ' |
||||||
|
else: |
||||||
|
exportxmp = ' -exportXMP "D:\\make2\\config\\exportXMP.config.xml" ' |
||||||
|
|
||||||
|
usePhoto = "photo"+str(usePhoto) |
||||||
|
|
||||||
|
#执行命令 |
||||||
|
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, usePhoto)}" -selectAllImages \ |
||||||
|
-detectMarkers "D:\\make2\\config\\detectMarkers.config.xml" \ |
||||||
|
-align -align -align -align \ |
||||||
|
{exportxmp} \ |
||||||
|
-save "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}" -quit' |
||||||
|
print(cmd) |
||||||
|
cmd = shlex.split(cmd) |
||||||
|
res = subprocess.run(cmd) |
||||||
|
|
||||||
|
#根据参数转变路劲,复制photo1 里的xmp 文件到 photo2 里,或者 photo2 里的xmp 文件到 photo1 里 |
||||||
|
sourceFile = photo1_path |
||||||
|
targetFile = photo2_path |
||||||
|
if usePhoto == "photo2": |
||||||
|
sourceFile = photo2_path |
||||||
|
targetFile = photo1_path |
||||||
|
#复制xmp文件 |
||||||
|
for xmp in os.listdir(sourceFile): |
||||||
|
if xmp.endswith('.xmp'): |
||||||
|
if usePhoto == "photo1": |
||||||
|
shutil.copy(os.path.join(sourceFile, xmp), os.path.join(targetFile,xmp.replace('_1.xmp', '_8.xmp'))) |
||||||
|
|
||||||
|
if usePhoto == "photo2": |
||||||
|
shutil.copy(os.path.join(sourceFile, xmp), os.path.join(targetFile,xmp.replace('_8.xmp', '_1.xmp'))) |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#如果是photo2的话,就要将photo2 的 xmp 重命名成 _8.xmp |
||||||
|
# if usePhoto == "photo2": |
||||||
|
# for xmp in os.listdir(sourceFile): |
||||||
|
# if xmp.endswith('.xmp'): |
||||||
|
# #重名名.xmp 结尾的文件 |
||||||
|
# os.rename(os.path.join(sourceFile, xmp), os.path.join(sourceFile,xmp.replace('_1.xmp', '_8.xmp'))) |
||||||
|
# print("坐标复制完成") |
||||||
|
# exit() |
||||||
|
|
||||||
|
#将两组图片进行重新对齐 然后重建区域 |
||||||
|
psid = libs.getPSid(pid) |
||||||
|
cmd = f'{config.rcbin} -setInstanceName {pid} \ |
||||||
|
-load "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}" {config.r["setTextureFalse"]} \ |
||||||
|
-addFolder "{targetFile}" -selectAllImages \ |
||||||
|
-detectMarkers "D:\\make2\\config\\detectMarkers.config.xml" \ |
||||||
|
{libs.get_defineDistances(psid)} -update -align -align -align -align {config.r2["setRegion"]} \ |
||||||
|
{exportxmp} \ |
||||||
|
-exportReconstructionRegion "{os.path.join(config.workdir, pid, f"{pid}.rcbox")}" \ |
||||||
|
-selectImage "{os.path.join(config.workdir,pid,"photo2")}/*" -enableTexturingAndColoring true \ |
||||||
|
-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} step1完成,共费时{libs.diff_time(start_time)}') |
||||||
|
|
||||||
|
#调用step2 |
||||||
|
time.sleep(2) |
||||||
|
# os.system(f'python main_step2.py {pid}') |
||||||
|
os.system(f'python D://make2/export_build_info/main_step2.py {pid}') |
||||||
|
|
||||||
|
|
||||||
|
def is_already(pid): |
||||||
|
|
||||||
|
|
||||||
|
#读取已经完成的pid |
||||||
|
with open("D://make2/export_build_info/finished.txt", 'r') as f: |
||||||
|
lines = f.readlines() |
||||||
|
for line in lines: |
||||||
|
print("line",str(line.strip())) |
||||||
|
if str(pid) == str(line.strip()): |
||||||
|
print("匹配成功") |
||||||
|
return True |
||||||
|
return False |
||||||
|
|
||||||
|
if __name__ == '__main__': |
||||||
|
already = [184219,184215,184209,184069,184059,183868,183817,183791,183613,183054,182855,182854,184206,184201,184199,184164,184087,184076,184029,184013,183993,183952,183888,183882,183824,183815,183812] |
||||||
|
|
||||||
|
arrPids = [184219,184215,184209,184206,184201,184199,184164,184087,184076,184069,184059,184029,184013,183993,183952,183888,183882,183868,183824,183817,183815,183812,183791,183777,183715,183705,183670,183613,183573,182974,182983,182985,182989,182997,183007,183051,183060,183054,183053,183097,183119,183108,183139,183141,183155,183163,183169,183180,183191,183196,183214,183244,183266,183278,183275,183309,183402,183422,183440,182974,182964,182958,182956,182916,182855,182854,182820,182787,182800,182809,182780,182772,182770,182766,182754,182742,182740,182723,182707,182647,182643,182614,182595,182563,182557,182547,182546,182538,182530,182517,182498,182478,182452,182386,182352,182285,182266,182260,182230,182224] |
||||||
|
for pid in arrPids: |
||||||
|
if pid in already: |
||||||
|
continue |
||||||
|
print("正在处理-",pid) |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if is_already(str(pid)) == True: |
||||||
|
continue |
||||||
|
# i += 1 |
||||||
|
# continue |
||||||
|
#写入到 |
||||||
|
with open("D://make2/export_build_info/finished.txt", 'a+') as f: |
||||||
|
f.write(f"{pid}\n") |
||||||
|
|
||||||
|
|
||||||
|
cmd_run(str(pid),usePhoto = "1",lock=False) |
||||||
|
|
||||||
|
# if len(sys.argv) == 2: |
||||||
|
# pids = sys.argv[1].split(',') |
||||||
|
# for pid in pids: |
||||||
|
# cmd_run(pid,usePhoto = "1",lock=False) |
||||||
|
# elif len(sys.argv) == 3: |
||||||
|
# pids = sys.argv[1].split(',') |
||||||
|
# for pid in pids: |
||||||
|
# if sys.argv[2] == '2': |
||||||
|
# cmd_run(pid,usePhoto = "2",lock=False) |
||||||
|
# else: |
||||||
|
# cmd_run(pid,usePhoto = "1",lock=False) |
||||||
|
# elif len(sys.argv) == 4: |
||||||
|
# pids = sys.argv[1].split(',') |
||||||
|
# usePhoto = sys.argv[2] |
||||||
|
# lock = sys.argv[3] |
||||||
|
# for pid in pids: |
||||||
|
# cmd_run(pid,usePhoto = usePhoto,lock=lock) |
||||||
|
|
||||||
|
# else: |
||||||
|
# print(f'useage: python {sys.argv[0]} pid1,pid2,pid3 photo = 1/2 lock = True/False') |
||||||
|
# sys.exit(1) |
||||||
@ -0,0 +1,27 @@ |
|||||||
|
181561 |
||||||
|
181559 |
||||||
|
180990 |
||||||
|
180772 |
||||||
|
180538 |
||||||
|
180256 |
||||||
|
179927 |
||||||
|
179657 |
||||||
|
179627 |
||||||
|
178838 |
||||||
|
178714 |
||||||
|
178616 |
||||||
|
178604 |
||||||
|
178332 |
||||||
|
177920 |
||||||
|
176655 |
||||||
|
184102 |
||||||
|
183728 |
||||||
|
183538 |
||||||
|
183524 |
||||||
|
183274 |
||||||
|
183316 |
||||||
|
183345 |
||||||
|
182867 |
||||||
|
182658 |
||||||
|
182638 |
||||||
|
182560 |
||||||
@ -0,0 +1,28 @@ |
|||||||
|
181307 |
||||||
|
181287 |
||||||
|
181267 |
||||||
|
180402 |
||||||
|
179617 |
||||||
|
179613 |
||||||
|
178991 |
||||||
|
178892 |
||||||
|
178814 |
||||||
|
178787 |
||||||
|
178471 |
||||||
|
178469 |
||||||
|
178400 |
||||||
|
178156 |
||||||
|
177899 |
||||||
|
177894 |
||||||
|
176236 |
||||||
|
184133 |
||||||
|
184039 |
||||||
|
183848 |
||||||
|
183769 |
||||||
|
183637 |
||||||
|
183127 |
||||||
|
183238 |
||||||
|
182450 |
||||||
|
182031 |
||||||
|
181977 |
||||||
|
181960 |
||||||
@ -0,0 +1,393 @@ |
|||||||
|
181763 |
||||||
|
181757 |
||||||
|
181754 |
||||||
|
181687 |
||||||
|
181652 |
||||||
|
181642 |
||||||
|
181619 |
||||||
|
181597 |
||||||
|
181574 |
||||||
|
181542 |
||||||
|
181526 |
||||||
|
181515 |
||||||
|
181482 |
||||||
|
181435 |
||||||
|
181421 |
||||||
|
181408 |
||||||
|
181391 |
||||||
|
181388 |
||||||
|
181367 |
||||||
|
181333 |
||||||
|
181329 |
||||||
|
181327 |
||||||
|
181304 |
||||||
|
181274 |
||||||
|
181261 |
||||||
|
181257 |
||||||
|
181248 |
||||||
|
181232 |
||||||
|
181231 |
||||||
|
181229 |
||||||
|
181205 |
||||||
|
181204 |
||||||
|
181203 |
||||||
|
181202 |
||||||
|
181191 |
||||||
|
181188 |
||||||
|
181177 |
||||||
|
181176 |
||||||
|
181145 |
||||||
|
181143 |
||||||
|
181139 |
||||||
|
181117 |
||||||
|
181115 |
||||||
|
181108 |
||||||
|
181097 |
||||||
|
181062 |
||||||
|
181050 |
||||||
|
181046 |
||||||
|
181040 |
||||||
|
181039 |
||||||
|
181023 |
||||||
|
181020 |
||||||
|
180961 |
||||||
|
180958 |
||||||
|
180944 |
||||||
|
180943 |
||||||
|
180904 |
||||||
|
180903 |
||||||
|
180869 |
||||||
|
180864 |
||||||
|
180862 |
||||||
|
180846 |
||||||
|
180839 |
||||||
|
180819 |
||||||
|
180781 |
||||||
|
180776 |
||||||
|
180771 |
||||||
|
180770 |
||||||
|
180670 |
||||||
|
180661 |
||||||
|
180648 |
||||||
|
180593 |
||||||
|
180591 |
||||||
|
180588 |
||||||
|
180581 |
||||||
|
180461 |
||||||
|
180455 |
||||||
|
180450 |
||||||
|
180429 |
||||||
|
180424 |
||||||
|
180394 |
||||||
|
180327 |
||||||
|
180314 |
||||||
|
180308 |
||||||
|
180297 |
||||||
|
180292 |
||||||
|
180291 |
||||||
|
180281 |
||||||
|
180273 |
||||||
|
180225 |
||||||
|
180185 |
||||||
|
180167 |
||||||
|
180156 |
||||||
|
180145 |
||||||
|
180125 |
||||||
|
180085 |
||||||
|
180084 |
||||||
|
180082 |
||||||
|
179980 |
||||||
|
179978 |
||||||
|
179975 |
||||||
|
179942 |
||||||
|
179935 |
||||||
|
179895 |
||||||
|
179861 |
||||||
|
179850 |
||||||
|
179849 |
||||||
|
179815 |
||||||
|
179722 |
||||||
|
179704 |
||||||
|
179695 |
||||||
|
179688 |
||||||
|
179676 |
||||||
|
179652 |
||||||
|
179646 |
||||||
|
179623 |
||||||
|
179621 |
||||||
|
179585 |
||||||
|
179555 |
||||||
|
179551 |
||||||
|
179493 |
||||||
|
179489 |
||||||
|
179474 |
||||||
|
179471 |
||||||
|
179470 |
||||||
|
179461 |
||||||
|
179457 |
||||||
|
179451 |
||||||
|
179430 |
||||||
|
179355 |
||||||
|
179344 |
||||||
|
179331 |
||||||
|
179316 |
||||||
|
179282 |
||||||
|
179229 |
||||||
|
179226 |
||||||
|
179219 |
||||||
|
179205 |
||||||
|
179204 |
||||||
|
179166 |
||||||
|
179160 |
||||||
|
179151 |
||||||
|
179149 |
||||||
|
179147 |
||||||
|
179139 |
||||||
|
178752 |
||||||
|
178743 |
||||||
|
178677 |
||||||
|
178675 |
||||||
|
178674 |
||||||
|
178624 |
||||||
|
178606 |
||||||
|
178594 |
||||||
|
178591 |
||||||
|
178528 |
||||||
|
178526 |
||||||
|
178521 |
||||||
|
178520 |
||||||
|
178519 |
||||||
|
178493 |
||||||
|
178457 |
||||||
|
178452 |
||||||
|
178447 |
||||||
|
178390 |
||||||
|
178388 |
||||||
|
178369 |
||||||
|
178364 |
||||||
|
178349 |
||||||
|
178348 |
||||||
|
178347 |
||||||
|
178330 |
||||||
|
178319 |
||||||
|
178303 |
||||||
|
178302 |
||||||
|
178294 |
||||||
|
178287 |
||||||
|
178269 |
||||||
|
178236 |
||||||
|
178220 |
||||||
|
178219 |
||||||
|
178214 |
||||||
|
178203 |
||||||
|
178191 |
||||||
|
178187 |
||||||
|
178164 |
||||||
|
178159 |
||||||
|
178129 |
||||||
|
178100 |
||||||
|
178098 |
||||||
|
178054 |
||||||
|
178051 |
||||||
|
178048 |
||||||
|
178042 |
||||||
|
178034 |
||||||
|
178016 |
||||||
|
177467 |
||||||
|
177465 |
||||||
|
177453 |
||||||
|
177449 |
||||||
|
177447 |
||||||
|
177443 |
||||||
|
177431 |
||||||
|
177430 |
||||||
|
177412 |
||||||
|
177360 |
||||||
|
177353 |
||||||
|
177350 |
||||||
|
177337 |
||||||
|
177327 |
||||||
|
177309 |
||||||
|
178008 |
||||||
|
177999 |
||||||
|
177998 |
||||||
|
177992 |
||||||
|
177991 |
||||||
|
177984 |
||||||
|
177973 |
||||||
|
177972 |
||||||
|
177971 |
||||||
|
177948 |
||||||
|
177852 |
||||||
|
177830 |
||||||
|
177820 |
||||||
|
177812 |
||||||
|
177763 |
||||||
|
177706 |
||||||
|
177681 |
||||||
|
177659 |
||||||
|
177648 |
||||||
|
177647 |
||||||
|
177641 |
||||||
|
177628 |
||||||
|
177613 |
||||||
|
177611 |
||||||
|
177550 |
||||||
|
177293 |
||||||
|
177288 |
||||||
|
177280 |
||||||
|
177277 |
||||||
|
177265 |
||||||
|
177262 |
||||||
|
177257 |
||||||
|
177225 |
||||||
|
177213 |
||||||
|
177198 |
||||||
|
177172 |
||||||
|
177159 |
||||||
|
177146 |
||||||
|
177152 |
||||||
|
177108 |
||||||
|
177095 |
||||||
|
177092 |
||||||
|
177048 |
||||||
|
177046 |
||||||
|
177035 |
||||||
|
176822 |
||||||
|
176752 |
||||||
|
176739 |
||||||
|
176688 |
||||||
|
176678 |
||||||
|
176631 |
||||||
|
176609 |
||||||
|
176602 |
||||||
|
176525 |
||||||
|
176338 |
||||||
|
176333 |
||||||
|
176314 |
||||||
|
176305 |
||||||
|
176249 |
||||||
|
176238 |
||||||
|
184219 |
||||||
|
184215 |
||||||
|
184209 |
||||||
|
184206 |
||||||
|
184201 |
||||||
|
184199 |
||||||
|
184164 |
||||||
|
184087 |
||||||
|
184076 |
||||||
|
184069 |
||||||
|
184059 |
||||||
|
184029 |
||||||
|
184013 |
||||||
|
183993 |
||||||
|
183952 |
||||||
|
183888 |
||||||
|
183882 |
||||||
|
183868 |
||||||
|
183824 |
||||||
|
183817 |
||||||
|
183815 |
||||||
|
183812 |
||||||
|
183791 |
||||||
|
183777 |
||||||
|
183715 |
||||||
|
183705 |
||||||
|
183670 |
||||||
|
183613 |
||||||
|
183573 |
||||||
|
182974 |
||||||
|
182983 |
||||||
|
182985 |
||||||
|
182989 |
||||||
|
182997 |
||||||
|
183007 |
||||||
|
183051 |
||||||
|
183060 |
||||||
|
183054 |
||||||
|
183053 |
||||||
|
183097 |
||||||
|
183119 |
||||||
|
183108 |
||||||
|
183139 |
||||||
|
183141 |
||||||
|
183155 |
||||||
|
183163 |
||||||
|
183169 |
||||||
|
183180 |
||||||
|
183191 |
||||||
|
183196 |
||||||
|
183214 |
||||||
|
183244 |
||||||
|
183266 |
||||||
|
183278 |
||||||
|
183275 |
||||||
|
183309 |
||||||
|
183402 |
||||||
|
183422 |
||||||
|
183440 |
||||||
|
182974 |
||||||
|
182964 |
||||||
|
182958 |
||||||
|
182956 |
||||||
|
182916 |
||||||
|
182855 |
||||||
|
182854 |
||||||
|
182820 |
||||||
|
182787 |
||||||
|
182800 |
||||||
|
182809 |
||||||
|
182780 |
||||||
|
182772 |
||||||
|
182770 |
||||||
|
182766 |
||||||
|
182754 |
||||||
|
182742 |
||||||
|
182740 |
||||||
|
182723 |
||||||
|
182707 |
||||||
|
182647 |
||||||
|
182643 |
||||||
|
182614 |
||||||
|
182595 |
||||||
|
182563 |
||||||
|
182557 |
||||||
|
182547 |
||||||
|
182546 |
||||||
|
182538 |
||||||
|
182530 |
||||||
|
182517 |
||||||
|
182498 |
||||||
|
182478 |
||||||
|
182452 |
||||||
|
182386 |
||||||
|
182352 |
||||||
|
182285 |
||||||
|
182266 |
||||||
|
182260 |
||||||
|
182230 |
||||||
|
182224 |
||||||
|
182223 |
||||||
|
182191 |
||||||
|
182185 |
||||||
|
182182 |
||||||
|
182179 |
||||||
|
182106 |
||||||
|
182101 |
||||||
|
182072 |
||||||
|
181966 |
||||||
|
181965 |
||||||
|
181937 |
||||||
|
181928 |
||||||
|
181925 |
||||||
|
181924 |
||||||
|
181923 |
||||||
|
181900 |
||||||
|
181895 |
||||||
|
181860 |
||||||
|
181847 |
||||||
|
181836 |
||||||
|
181833 |
||||||
|
181811 |
||||||
|
181809 |
||||||
@ -0,0 +1,307 @@ |
|||||||
|
181593 |
||||||
|
181384 |
||||||
|
181337 |
||||||
|
181318 |
||||||
|
181263 |
||||||
|
181240 |
||||||
|
181211 |
||||||
|
181197 |
||||||
|
181187 |
||||||
|
181140 |
||||||
|
181103 |
||||||
|
181091 |
||||||
|
181054 |
||||||
|
181027 |
||||||
|
180763 |
||||||
|
180690 |
||||||
|
180684 |
||||||
|
180677 |
||||||
|
180599 |
||||||
|
180576 |
||||||
|
180389 |
||||||
|
180342 |
||||||
|
180337 |
||||||
|
180277 |
||||||
|
180265 |
||||||
|
180253 |
||||||
|
180101 |
||||||
|
180083 |
||||||
|
179905 |
||||||
|
179842 |
||||||
|
179811 |
||||||
|
179808 |
||||||
|
179791 |
||||||
|
179786 |
||||||
|
179700 |
||||||
|
179634 |
||||||
|
179593 |
||||||
|
179576 |
||||||
|
179485 |
||||||
|
179459 |
||||||
|
179400 |
||||||
|
179351 |
||||||
|
178995 |
||||||
|
178898 |
||||||
|
178750 |
||||||
|
178746 |
||||||
|
178723 |
||||||
|
178680 |
||||||
|
178673 |
||||||
|
178654 |
||||||
|
178527 |
||||||
|
178482 |
||||||
|
178465 |
||||||
|
178430 |
||||||
|
178413 |
||||||
|
178409 |
||||||
|
178297 |
||||||
|
178286 |
||||||
|
178281 |
||||||
|
178105 |
||||||
|
178062 |
||||||
|
178026 |
||||||
|
178025 |
||||||
|
178019 |
||||||
|
178017 |
||||||
|
178004 |
||||||
|
177851 |
||||||
|
177678 |
||||||
|
177677 |
||||||
|
177646 |
||||||
|
177545 |
||||||
|
177520 |
||||||
|
177300 |
||||||
|
177080 |
||||||
|
176757 |
||||||
|
176743 |
||||||
|
176648 |
||||||
|
176290 |
||||||
|
176280 |
||||||
|
176273 |
||||||
|
176247 |
||||||
|
184082 |
||||||
|
184074 |
||||||
|
184068 |
||||||
|
184061 |
||||||
|
184041 |
||||||
|
183893 |
||||||
|
183890 |
||||||
|
183810 |
||||||
|
183755 |
||||||
|
183680 |
||||||
|
183656 |
||||||
|
183592 |
||||||
|
183591 |
||||||
|
183589 |
||||||
|
183025 |
||||||
|
183086 |
||||||
|
183104 |
||||||
|
183162 |
||||||
|
183444 |
||||||
|
182907 |
||||||
|
182915 |
||||||
|
182871 |
||||||
|
182804 |
||||||
|
182778 |
||||||
|
182718 |
||||||
|
182675 |
||||||
|
182664 |
||||||
|
182625 |
||||||
|
182623 |
||||||
|
182542 |
||||||
|
182510 |
||||||
|
182473 |
||||||
|
182455 |
||||||
|
182388 |
||||||
|
182365 |
||||||
|
182343 |
||||||
|
182316 |
||||||
|
181957 |
||||||
|
181948 |
||||||
|
181941 |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,28 @@ |
|||||||
|
180891 |
||||||
|
180673 |
||||||
|
180584 |
||||||
|
180468 |
||||||
|
180164 |
||||||
|
180091 |
||||||
|
179992 |
||||||
|
179962 |
||||||
|
178627 |
||||||
|
178416 |
||||||
|
178255 |
||||||
|
178066 |
||||||
|
177983 |
||||||
|
177722 |
||||||
|
183832 |
||||||
|
183677 |
||||||
|
183183 |
||||||
|
183351 |
||||||
|
183361 |
||||||
|
183360 |
||||||
|
182853 |
||||||
|
182715 |
||||||
|
182630 |
||||||
|
182367 |
||||||
|
182253 |
||||||
|
182057 |
||||||
|
181868 |
||||||
|
181856 |
||||||
@ -0,0 +1,42 @@ |
|||||||
|
<Configuration id="{2D5793BC-A65D-4318-A1B9-A05044608385}"> |
||||||
|
<entry key="calexUndistResMode" value="2"/> |
||||||
|
<entry key="calexTrans" value="1"/> |
||||||
|
<entry key="calexUndistortNaming" value="5"/> |
||||||
|
<entry key="calexUndistortPixelFormat" value="24bppBGR"/> |
||||||
|
<entry key="calexHasDisabled" value="0x0"/> |
||||||
|
<entry key="calexRequiresUndistortPrincipal" value="0x1"/> |
||||||
|
<entry key="calexExportImages" value="true"/> |
||||||
|
<entry key="calexUndistortImageFormat" value="jpg"/> |
||||||
|
<entry key="MvsExportScaleZ" value="1.0"/> |
||||||
|
<entry key="MvsExportIsGeoreferenced" value="0x0"/> |
||||||
|
<entry key="MvsExportIsModelCoordinates" value="0"/> |
||||||
|
<entry key="calexRequiresColorCorrection" value="0x0"/> |
||||||
|
<entry key="MvsExportScaleY" value="1.0"/> |
||||||
|
<entry key="calexDownscale" value="0x1"/> |
||||||
|
<entry key="calexRequiresEqualResolution" value="0x0"/> |
||||||
|
<entry key="calexUndistMaxPixels" value="0"/> |
||||||
|
<entry key="calexInputHasLayers" value="0"/> |
||||||
|
<entry key="MvsExportScaleX" value="1.0"/> |
||||||
|
<entry key="calexUndistFitMode" value="2"/> |
||||||
|
<entry key="MvsExportRotationY" value="0.0"/> |
||||||
|
<entry key="MvsExportcoordinatesystemtype" value="0"/> |
||||||
|
<entry key="MvsExportNormalFlipZ" value="false"/> |
||||||
|
<entry key="MvsExportRotationX" value="0.0"/> |
||||||
|
<entry key="hasCalexFilePath" value="1"/> |
||||||
|
<entry key="calexFolderCustom" value="false"/> |
||||||
|
<entry key="MvsExportNormalFlipY" value="false"/> |
||||||
|
<entry key="MvsExportNormalSpace" value="Mikktspace"/> |
||||||
|
<entry key="calexHasUndistort" value="2"/> |
||||||
|
<entry key="MvsExportNormalFlipX" value="false"/> |
||||||
|
<entry key="MvsExportRotationZ" value="0.0"/> |
||||||
|
<entry key="calexFileFormat" value="Bundler v0.3"/> |
||||||
|
<entry key="MvsExportMoveZ" value="0.0"/> |
||||||
|
<entry key="calexFileFormatId" value="{ECC4131A-1665-466C-93BE-66DF2EBC9086}"/> |
||||||
|
<entry key="hasCalexFileName" value="1"/> |
||||||
|
<entry key="calexUndistCutOut" value="1.0"/> |
||||||
|
<entry key="calexHasImageExport" value="1"/> |
||||||
|
<entry key="calexUndistBackColor" value="0"/> |
||||||
|
<entry key="MvsExportMoveX" value="0.0"/> |
||||||
|
<entry key="MvsExportNormalRange" value="ZeroToOne"/> |
||||||
|
<entry key="MvsExportMoveY" value="0.0"/> |
||||||
|
</Configuration> |
||||||
@ -0,0 +1,13 @@ |
|||||||
|
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple |
||||||
|
pip config set install.trusted-host pypi.tuna.tsinghua.edu.cn |
||||||
|
|
||||||
|
python -m pip install --upgrade pip |
||||||
|
pip install oss2 redis MySQLdb pillow numpy opencv-python bpy tqdm pyautogui psutil pywin32 pymysql |
||||||
|
|
||||||
|
|
||||||
|
config |
||||||
|
set bin="C:\Program Files\Capturing Reality\RealityCapture\RealityCapture.exe" |
||||||
|
%bin% -disableOnlineCommunication -setInstanceName %pid% |
||||||
|
%bin% -disableOnlineCommunication -delegateTo %pid% |
||||||
|
%bin% -set "appCacheLocation=ProjectFolder" |
||||||
|
|
||||||
@ -0,0 +1,83 @@ |
|||||||
|
# mysql数据库常用任务函数封装 |
||||||
|
import pymysql, socket, time |
||||||
|
import config |
||||||
|
|
||||||
|
#公共连接库 |
||||||
|
def pymysqlAlias(): |
||||||
|
return pymysql.connect( |
||||||
|
host=config.mysql_gpu['host'], |
||||||
|
port=config.mysql_gpu['port'], |
||||||
|
user=config.mysql_gpu['user'], |
||||||
|
password=config.mysql_gpu['password'], |
||||||
|
db=config.mysql_gpu['db'], |
||||||
|
charset=config.mysql_gpu['charset'],) |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 新增新的任务 |
||||||
|
def add_reapeat_texture_task(data): |
||||||
|
try: |
||||||
|
|
||||||
|
resExist = is_exist(data["pid"]) |
||||||
|
if resExist == True: |
||||||
|
return |
||||||
|
|
||||||
|
with pymysqlAlias() as conn: |
||||||
|
cursor = conn.cursor() |
||||||
|
sql = f'insert into task_repeat_texture (pid,heads,createTime) values ("{data["pid"]}","{data["heads"]}","{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}")' |
||||||
|
print(f'sql: {sql}') |
||||||
|
cursor.execute(sql) |
||||||
|
conn.commit() |
||||||
|
except Exception as e: |
||||||
|
print(f"{time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())} 执行add_task({data})异常: {str(e)}") |
||||||
|
|
||||||
|
|
||||||
|
# |
||||||
|
def is_exist(pid): |
||||||
|
try: |
||||||
|
with pymysqlAlias() as conn: |
||||||
|
cursor = conn.cursor() |
||||||
|
sql = f'select count(*) from task_repeat_texture where pid = {pid} and status = 0' |
||||||
|
print(f'sql: {sql}') |
||||||
|
cursor.execute(sql) |
||||||
|
result = cursor.fetchone() |
||||||
|
if result[0] > 0: |
||||||
|
return True |
||||||
|
else: |
||||||
|
return False |
||||||
|
except Exception as e: |
||||||
|
print(f"{time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())} 执行is_new_make_psid()异常: {str(e)}") |
||||||
|
return "error" |
||||||
|
|
||||||
|
|
||||||
|
def get_pid_task(): |
||||||
|
try: |
||||||
|
with pymysqlAlias() as conn: |
||||||
|
cursor = conn.cursor() |
||||||
|
sql = f'select * from task_repeat_texture where status = 1 limit 1' |
||||||
|
print(f'sql: {sql}') |
||||||
|
cursor.execute(sql) |
||||||
|
result = cursor.fetchone() |
||||||
|
if result: |
||||||
|
return result |
||||||
|
else: |
||||||
|
return None |
||||||
|
except Exception as e: |
||||||
|
print(f"{time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())} 执行get_pid_task()异常: {str(e)}") |
||||||
|
return "error" |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#更新状态 |
||||||
|
def update_status(id,status): |
||||||
|
try: |
||||||
|
with pymysqlAlias() as conn: |
||||||
|
cursor = conn.cursor() |
||||||
|
|
||||||
|
hostname = socket.gethostname() |
||||||
|
sql = f'update task_repeat_texture set status = {status},updateTime = now() where id = {id}' |
||||||
|
print(f'开始任务sql: {sql}') |
||||||
|
cursor.execute(sql) |
||||||
|
conn.commit() |
||||||
|
except Exception as e: |
||||||
|
print(f"{time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())} 执行update_status()异常: {str(e)}") |
||||||
@ -0,0 +1,30 @@ |
|||||||
|
# mysql数据库常用任务函数封装 |
||||||
|
import pymysql, socket, time |
||||||
|
import config |
||||||
|
|
||||||
|
#公共连接库 |
||||||
|
def pymysqlAlias(): |
||||||
|
return pymysql.connect( |
||||||
|
host=config.mysql_task_rc['host'], |
||||||
|
port=config.mysql_task_rc['port'], |
||||||
|
user=config.mysql_task_rc['user'], |
||||||
|
password=config.mysql_task_rc['password'], |
||||||
|
db=config.mysql_task_rc['db'], |
||||||
|
charset=config.mysql_task_rc['charset'],) |
||||||
|
|
||||||
|
# 获取新的任务 |
||||||
|
def get_task_rc_count(): |
||||||
|
try: |
||||||
|
with pymysqlAlias() as conn: |
||||||
|
cursor = conn.cursor() |
||||||
|
sql = f'select count(*) from task_distributed where status != 2 and created_at >= "2024-09-02 00:00:00"' |
||||||
|
# print(f'sql: {sql}') |
||||||
|
cursor.execute(sql) |
||||||
|
data = cursor.fetchone() |
||||||
|
if data: |
||||||
|
return data[0] |
||||||
|
else: |
||||||
|
return '' |
||||||
|
except Exception as e: |
||||||
|
print(f"{time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())} get_task_rc_count()异常: {str(e)}") |
||||||
|
return '' |
||||||
@ -0,0 +1,101 @@ |
|||||||
|
#读取需要重新贴图的数据 |
||||||
|
import os,sys,time,shlex,subprocess,shutil |
||||||
|
import platform |
||||||
|
if platform.system() == 'Windows': |
||||||
|
sys.path.append('e:\\libs\\') |
||||||
|
#sys.path.append('libs') |
||||||
|
else: |
||||||
|
sys.path.append('/data/deploy/make3d/make2/libs/') |
||||||
|
import libs_db_repeat_texture |
||||||
|
import libs,config |
||||||
|
|
||||||
|
|
||||||
|
#读取 数据库的信息 |
||||||
|
def get_pid(): |
||||||
|
data = libs_db_repeat_texture.get_pid_task() |
||||||
|
if data != None and data != "error": |
||||||
|
return data[0],data[1] |
||||||
|
else: |
||||||
|
return None,None |
||||||
|
|
||||||
|
#开始处理任务 |
||||||
|
def start_task(pid): |
||||||
|
#下载Obj数据 |
||||||
|
print(f"处理{pid}任务") |
||||||
|
print("开始下载{pid}数据") |
||||||
|
# pid = str("175635") |
||||||
|
complateCloudPath = libs.down_obj_from_oss_for_repeat_texture(config.workdir, pid,"auto") |
||||||
|
if complateCloudPath == "error": |
||||||
|
return -1,"error-从oss上下载出问题" |
||||||
|
#下载下来之后重新加载obj 和texture |
||||||
|
print("complateCloudPath",complateCloudPath) |
||||||
|
|
||||||
|
|
||||||
|
outPath = os.path.join(config.workdir, pid, "output") |
||||||
|
if os.path.exists(outPath): |
||||||
|
print("移除文件夹") |
||||||
|
#移除文件夹 |
||||||
|
shutil.rmtree(outPath) |
||||||
|
|
||||||
|
cmd = f'{config.rcbin} {config.r2["init"]} -setInstanceName {pid} \ |
||||||
|
-load "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}" \ |
||||||
|
-importModel "{os.path.join(complateCloudPath, f"{pid}.obj")}" \ |
||||||
|
-calculateTexture -exportSelectedModel "{os.path.join(config.workdir, pid, "output", f"{pid}.obj")}" "d:\\make2\\config\\ModelExportParams0722.xml" -quit' |
||||||
|
print(cmd) |
||||||
|
cmd = shlex.split(cmd) |
||||||
|
res = subprocess.run(cmd) |
||||||
|
|
||||||
|
#检查out目录文件夹是否有多个 贴图文件。如果是的话只保留最新的一个,并且重命名为初始图像的名称 |
||||||
|
outFilePath = os.path.join(config.workdir, pid, "output") |
||||||
|
arrTempImage = [] |
||||||
|
for file in os.listdir(outFilePath): |
||||||
|
if file.endswith(".jpg") or file.endswith(".png"): |
||||||
|
#字符串替换 |
||||||
|
fileTempName = file.replace(f"{pid}_u0_v0_diffuse","") |
||||||
|
fileTempName = fileTempName.replace(".jpg","") |
||||||
|
fileTempName = fileTempName.replace(".png","") |
||||||
|
if "_" in fileTempName: |
||||||
|
fileTempName = fileTempName.replace("_","") |
||||||
|
arrTempImage.append(fileTempName) |
||||||
|
print(arrTempImage) |
||||||
|
if len(arrTempImage) > 1: |
||||||
|
#获取 arrTempImage 中最大的值 |
||||||
|
arrTempImage.sort() |
||||||
|
print(arrTempImage) |
||||||
|
#获取最大值 |
||||||
|
maxValue = arrTempImage[-1] |
||||||
|
|
||||||
|
for i in arrTempImage: |
||||||
|
if i == "": |
||||||
|
filePath1 = os.path.join(config.workdir, pid, "output",pid+"_u0_v0_diffuse.jpg") |
||||||
|
filePath2 = os.path.join(config.workdir, pid, "output",pid+"_u0_v0_diffuse.png") |
||||||
|
else: |
||||||
|
filePath1 = os.path.join(config.workdir, pid, "output",pid+"_u0_v0_diffuse_"+str(i)+".jpg") |
||||||
|
filePath2 = os.path.join(config.workdir, pid, "output",pid+"_u0_v0_diffuse_"+str(i)+".png") |
||||||
|
|
||||||
|
if i != maxValue: |
||||||
|
if os.path.exists(filePath1): |
||||||
|
os.remove(filePath1) |
||||||
|
if os.path.exists(filePath2): |
||||||
|
os.remove(filePath2) |
||||||
|
else: |
||||||
|
if os.path.exists(filePath1): |
||||||
|
os.rename(filePath1,os.path.join(config.workdir, pid, "output",pid+"_u0_v0_diffuse.jpg")) |
||||||
|
if os.path.exists(filePath2): |
||||||
|
os.rename(filePath2,os.path.join(config.workdir, pid, "output",pid+"_u0_v0_diffuse.jpg")) |
||||||
|
#执行step3 |
||||||
|
os.system(f'python d:\\make2\\main_step3.py {pid}') |
||||||
|
return 3,"success" |
||||||
|
|
||||||
|
if __name__ == '__main__': |
||||||
|
while True: |
||||||
|
id,pid = get_pid() |
||||||
|
print(f"读取的数据{pid}") |
||||||
|
if pid != None: |
||||||
|
#更新状态为2 |
||||||
|
libs_db_repeat_texture.update_status(id,2) |
||||||
|
statusres,res = start_task(str(pid)) |
||||||
|
libs_db_repeat_texture.update_status(id,statusres) |
||||||
|
else: |
||||||
|
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}-没有任务') |
||||||
|
time.sleep(10) |
||||||
@ -0,0 +1,499 @@ |
|||||||
|
189002 |
||||||
|
189819 |
||||||
|
190152 |
||||||
|
190141 |
||||||
|
190204 |
||||||
|
190210 |
||||||
|
190221 |
||||||
|
190234 |
||||||
|
190257 |
||||||
|
190264 |
||||||
|
190297 |
||||||
|
190377 |
||||||
|
190238 |
||||||
|
190409 |
||||||
|
190417 |
||||||
|
190144 |
||||||
|
190233 |
||||||
|
189879 |
||||||
|
190227 |
||||||
|
190463 |
||||||
|
190510 |
||||||
|
190531 |
||||||
|
164671 |
||||||
|
190241 |
||||||
|
190547 |
||||||
|
188521 |
||||||
|
190609 |
||||||
|
184467 |
||||||
|
188521 |
||||||
|
189772 |
||||||
|
188521 |
||||||
|
190724 |
||||||
|
190506 |
||||||
|
190509 |
||||||
|
190511 |
||||||
|
190578 |
||||||
|
183895 |
||||||
|
190584 |
||||||
|
190605 |
||||||
|
190611 |
||||||
|
190620 |
||||||
|
190635 |
||||||
|
190683 |
||||||
|
190684 |
||||||
|
190694 |
||||||
|
190697 |
||||||
|
190708 |
||||||
|
190726 |
||||||
|
183494 |
||||||
|
185507 |
||||||
|
188521 |
||||||
|
183494 |
||||||
|
190751 |
||||||
|
183895 |
||||||
|
190754 |
||||||
|
183895 |
||||||
|
189002 |
||||||
|
190784 |
||||||
|
190783 |
||||||
|
190795 |
||||||
|
190812 |
||||||
|
183895 |
||||||
|
190823 |
||||||
|
190837 |
||||||
|
190910 |
||||||
|
190838 |
||||||
|
190866 |
||||||
|
190905 |
||||||
|
190915 |
||||||
|
190927 |
||||||
|
190944 |
||||||
|
190939 |
||||||
|
190932 |
||||||
|
190379 |
||||||
|
190948 |
||||||
|
190959 |
||||||
|
190980 |
||||||
|
190975 |
||||||
|
190927 |
||||||
|
190996 |
||||||
|
190981 |
||||||
|
191001 |
||||||
|
190927 |
||||||
|
190992 |
||||||
|
182361 |
||||||
|
185080 |
||||||
|
191045 |
||||||
|
185416 |
||||||
|
191069 |
||||||
|
191082 |
||||||
|
191081 |
||||||
|
191103 |
||||||
|
191118 |
||||||
|
191116 |
||||||
|
191152 |
||||||
|
191180 |
||||||
|
191125 |
||||||
|
191227 |
||||||
|
191238 |
||||||
|
191246 |
||||||
|
191234 |
||||||
|
191275 |
||||||
|
191320 |
||||||
|
191283 |
||||||
|
191354 |
||||||
|
191388 |
||||||
|
191435 |
||||||
|
191441 |
||||||
|
191431 |
||||||
|
191380 |
||||||
|
191340 |
||||||
|
191350 |
||||||
|
191297 |
||||||
|
191472 |
||||||
|
191255 |
||||||
|
191268 |
||||||
|
191501 |
||||||
|
191192 |
||||||
|
191156 |
||||||
|
191517 |
||||||
|
191515 |
||||||
|
191525 |
||||||
|
191532 |
||||||
|
191261 |
||||||
|
191422 |
||||||
|
191024 |
||||||
|
191542 |
||||||
|
191587 |
||||||
|
191597 |
||||||
|
191676 |
||||||
|
191678 |
||||||
|
191711 |
||||||
|
191736 |
||||||
|
186628 |
||||||
|
191874 |
||||||
|
191937 |
||||||
|
191924 |
||||||
|
191945 |
||||||
|
191887 |
||||||
|
191868 |
||||||
|
191981 |
||||||
|
191885 |
||||||
|
191838 |
||||||
|
191882 |
||||||
|
191965 |
||||||
|
191822 |
||||||
|
191870 |
||||||
|
191920 |
||||||
|
191894 |
||||||
|
191811 |
||||||
|
191739 |
||||||
|
191681 |
||||||
|
191790 |
||||||
|
191738 |
||||||
|
191699 |
||||||
|
191781 |
||||||
|
191733 |
||||||
|
191746 |
||||||
|
191793 |
||||||
|
191829 |
||||||
|
191834 |
||||||
|
191907 |
||||||
|
191927 |
||||||
|
191969 |
||||||
|
191990 |
||||||
|
191998 |
||||||
|
192005 |
||||||
|
192021 |
||||||
|
192023 |
||||||
|
192026 |
||||||
|
191771 |
||||||
|
190829 |
||||||
|
192038 |
||||||
|
191906 |
||||||
|
192095 |
||||||
|
192107 |
||||||
|
192098 |
||||||
|
192123 |
||||||
|
191066 |
||||||
|
192150 |
||||||
|
192161 |
||||||
|
192178 |
||||||
|
191210 |
||||||
|
191849 |
||||||
|
191832 |
||||||
|
192093 |
||||||
|
192199 |
||||||
|
192208 |
||||||
|
192202 |
||||||
|
192213 |
||||||
|
192211 |
||||||
|
192204 |
||||||
|
183783 |
||||||
|
192220 |
||||||
|
192267 |
||||||
|
192223 |
||||||
|
190880 |
||||||
|
192288 |
||||||
|
188877 |
||||||
|
192283 |
||||||
|
192291 |
||||||
|
192079 |
||||||
|
192077 |
||||||
|
192072 |
||||||
|
192063 |
||||||
|
188201 |
||||||
|
192343 |
||||||
|
192353 |
||||||
|
192367 |
||||||
|
192373 |
||||||
|
192222 |
||||||
|
192399 |
||||||
|
192392 |
||||||
|
189979 |
||||||
|
189988 |
||||||
|
189996 |
||||||
|
190692 |
||||||
|
190709 |
||||||
|
191955 |
||||||
|
191912 |
||||||
|
192444 |
||||||
|
192438 |
||||||
|
187727 |
||||||
|
192479 |
||||||
|
192473 |
||||||
|
192469 |
||||||
|
192476 |
||||||
|
192140 |
||||||
|
192143 |
||||||
|
192158 |
||||||
|
192498 |
||||||
|
192169 |
||||||
|
192175 |
||||||
|
192186 |
||||||
|
192187 |
||||||
|
192197 |
||||||
|
192214 |
||||||
|
190362 |
||||||
|
192236 |
||||||
|
192239 |
||||||
|
192241 |
||||||
|
192242 |
||||||
|
192244 |
||||||
|
192248 |
||||||
|
192304 |
||||||
|
192261 |
||||||
|
192421 |
||||||
|
192425 |
||||||
|
192514 |
||||||
|
192162 |
||||||
|
192548 |
||||||
|
192550 |
||||||
|
184779 |
||||||
|
192495 |
||||||
|
192490 |
||||||
|
192583 |
||||||
|
192586 |
||||||
|
192591 |
||||||
|
192593 |
||||||
|
192595 |
||||||
|
184756 |
||||||
|
192235 |
||||||
|
187195 |
||||||
|
192378 |
||||||
|
192622 |
||||||
|
192129 |
||||||
|
192570 |
||||||
|
192566 |
||||||
|
192480 |
||||||
|
192481 |
||||||
|
192484 |
||||||
|
192482 |
||||||
|
192532 |
||||||
|
192624 |
||||||
|
192630 |
||||||
|
192682 |
||||||
|
192674 |
||||||
|
192690 |
||||||
|
192701 |
||||||
|
188185 |
||||||
|
192725 |
||||||
|
192729 |
||||||
|
192608 |
||||||
|
192732 |
||||||
|
192717 |
||||||
|
192609 |
||||||
|
192611 |
||||||
|
192612 |
||||||
|
192615 |
||||||
|
192744 |
||||||
|
192643 |
||||||
|
192650 |
||||||
|
192653 |
||||||
|
192659 |
||||||
|
192776 |
||||||
|
192664 |
||||||
|
192676 |
||||||
|
192680 |
||||||
|
192758 |
||||||
|
192759 |
||||||
|
192767 |
||||||
|
192775 |
||||||
|
192782 |
||||||
|
192783 |
||||||
|
185658 |
||||||
|
192838 |
||||||
|
192873 |
||||||
|
192875 |
||||||
|
192905 |
||||||
|
192895 |
||||||
|
192869 |
||||||
|
187718 |
||||||
|
188167 |
||||||
|
192929 |
||||||
|
192940 |
||||||
|
192955 |
||||||
|
192947 |
||||||
|
192907 |
||||||
|
192908 |
||||||
|
192887 |
||||||
|
192979 |
||||||
|
193038 |
||||||
|
193003 |
||||||
|
193005 |
||||||
|
192875 |
||||||
|
193112 |
||||||
|
193101 |
||||||
|
193085 |
||||||
|
193082 |
||||||
|
192986 |
||||||
|
192944 |
||||||
|
193132 |
||||||
|
193141 |
||||||
|
193058 |
||||||
|
193160 |
||||||
|
193074 |
||||||
|
193217 |
||||||
|
193239 |
||||||
|
192208 |
||||||
|
193285 |
||||||
|
193260 |
||||||
|
193287 |
||||||
|
193288 |
||||||
|
193298 |
||||||
|
193281 |
||||||
|
193335 |
||||||
|
193332 |
||||||
|
193349 |
||||||
|
193165 |
||||||
|
193185 |
||||||
|
193010 |
||||||
|
193231 |
||||||
|
193364 |
||||||
|
193295 |
||||||
|
193313 |
||||||
|
193339 |
||||||
|
193354 |
||||||
|
193357 |
||||||
|
193360 |
||||||
|
193375 |
||||||
|
193376 |
||||||
|
193377 |
||||||
|
193378 |
||||||
|
193353 |
||||||
|
193193 |
||||||
|
193454 |
||||||
|
192317 |
||||||
|
193405 |
||||||
|
193468 |
||||||
|
193475 |
||||||
|
193483 |
||||||
|
193479 |
||||||
|
193486 |
||||||
|
193508 |
||||||
|
193504 |
||||||
|
193511 |
||||||
|
193503 |
||||||
|
193520 |
||||||
|
193562 |
||||||
|
193571 |
||||||
|
193560 |
||||||
|
193237 |
||||||
|
193569 |
||||||
|
193591 |
||||||
|
193590 |
||||||
|
193593 |
||||||
|
193617 |
||||||
|
193615 |
||||||
|
193637 |
||||||
|
193625 |
||||||
|
193642 |
||||||
|
193646 |
||||||
|
193683 |
||||||
|
193671 |
||||||
|
193677 |
||||||
|
193616 |
||||||
|
193702 |
||||||
|
193700 |
||||||
|
193604 |
||||||
|
193721 |
||||||
|
193745 |
||||||
|
193770 |
||||||
|
193768 |
||||||
|
193758 |
||||||
|
193762 |
||||||
|
193636 |
||||||
|
193652 |
||||||
|
190141 |
||||||
|
193771 |
||||||
|
193781 |
||||||
|
193813 |
||||||
|
193806 |
||||||
|
193812 |
||||||
|
193818 |
||||||
|
193835 |
||||||
|
193863 |
||||||
|
193907 |
||||||
|
193832 |
||||||
|
193896 |
||||||
|
193903 |
||||||
|
193906 |
||||||
|
193380 |
||||||
|
193383 |
||||||
|
193384 |
||||||
|
193925 |
||||||
|
193386 |
||||||
|
193480 |
||||||
|
193387 |
||||||
|
193666 |
||||||
|
193711 |
||||||
|
193757 |
||||||
|
193934 |
||||||
|
193778 |
||||||
|
193795 |
||||||
|
193809 |
||||||
|
193822 |
||||||
|
193817 |
||||||
|
193843 |
||||||
|
193918 |
||||||
|
193876 |
||||||
|
193922 |
||||||
|
193567 |
||||||
|
193564 |
||||||
|
193551 |
||||||
|
192320 |
||||||
|
193117 |
||||||
|
193961 |
||||||
|
193969 |
||||||
|
193524 |
||||||
|
193547 |
||||||
|
193990 |
||||||
|
193995 |
||||||
|
194012 |
||||||
|
194022 |
||||||
|
194027 |
||||||
|
194021 |
||||||
|
194069 |
||||||
|
194048 |
||||||
|
194035 |
||||||
|
194070 |
||||||
|
194015 |
||||||
|
194018 |
||||||
|
194093 |
||||||
|
194098 |
||||||
|
194144 |
||||||
|
194104 |
||||||
|
194112 |
||||||
|
194119 |
||||||
|
194108 |
||||||
|
194126 |
||||||
|
194153 |
||||||
|
194163 |
||||||
|
194044 |
||||||
|
194047 |
||||||
|
194206 |
||||||
|
194004 |
||||||
|
194229 |
||||||
|
194218 |
||||||
|
194240 |
||||||
|
194242 |
||||||
|
194278 |
||||||
|
194271 |
||||||
|
194293 |
||||||
|
194081 |
||||||
|
194173 |
||||||
|
194176 |
||||||
|
194211 |
||||||
|
194245 |
||||||
|
194270 |
||||||
|
194285 |
||||||
|
194292 |
||||||
|
194294 |
||||||
|
194296 |
||||||
|
194300 |
||||||
|
194347 |
||||||
|
190480 |
||||||
|
190483 |
||||||
|
194258 |
||||||
|
194266,194276,194444,194419,194454,194471,194470,194473,194475,194480,194493,194497,194499,194480,194460,192716,194465,194514,194515,194527,194501,194500,194526,194531,194536,194540,194551,194564,194577,194582,194580,187324,194599,194601,194628,194625,194623,189048,186982,194627,194508,194510,189048,194640,194642,194654,194685,194686,194707,194720,194719,194744,194734,194634,194738,194760,194765,194764,194768,194774,190697,194566,194356,194365,194369,194806,194376,194064,194772,194097,194773,194100,194103,194812,194810,194223,194181,194178,194589,194588,186685,194831,194830,194832,194834,194854,194817,194878,191283,191321,194900,194904,194858,194901,194885,194916,194924,194925,194802,194927,194932,194906,194908,194911,194912,194914,194915,194917,194920,194953,194926,194928,194930,194935,194957,194817,190531,189819,194989,194987,194995,194996,192305,194998,195015,195013,195023,195018,195021,195032,195005,195050,189864,195067,195072,195091,195026,195031,195104,195029,195102,195051,195063,195093,195125,195146,193800,195160,195172,195154,195184,194210,186610,191005,187854,193794, |
||||||
@ -0,0 +1,5 @@ |
|||||||
|
old version |
||||||
|
|
||||||
|
init: |
||||||
|
|
||||||
|
'"C:\\Program Files\\Capturing Reality\\RealityCapture\\RealityCapture.exe" -disableOnlineCommunication -set \"sfmEnableCameraPrior=False\" -set \"sfmMaxFeaturesPerMpx=20000\" -set \"sfmMaxFeaturesPerImage=200000\" -set \"sfmImagesOverlap=High\" -set \"sfmMaxFeatureReprojectionError=1\" -addFolder "D:\\{pid}\\photo1" -addFolder "D:\\{pid}\\photo2" -importControlPointsMeasurements "D:\\{pid}\\{pid}..controlPoints.csv" -align -save' |
||||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -1,15 +1,18 @@ |
|||||||
import psutil |
import re |
||||||
|
|
||||||
# 获取硬盘分区列表 |
def extract_o_option(file_path): |
||||||
partitions = psutil.disk_partitions() |
pattern = re.compile(r'o\s+(\S+)') |
||||||
|
with open(file_path, 'r') as file: |
||||||
|
for line in file: |
||||||
|
match = pattern.search(line) |
||||||
|
if match: |
||||||
|
return match.group(1) |
||||||
|
return None |
||||||
|
|
||||||
for partition in partitions: |
# 使用示例 |
||||||
print("分区信息",partition) |
file_path = 'C:/Users/Administrator/Desktop/29282/29282_9cm_x1.obj' |
||||||
# 获取指定分区(比如'C:')的使用情况 |
result = extract_o_option(file_path) |
||||||
if partition.mountpoint == 'G:\\': # 更改为您要检测的硬盘分区 |
if result: |
||||||
usage = psutil.disk_usage(partition.mountpoint) |
print(f'Found -o option with value: {result}') |
||||||
|
else: |
||||||
print(f"Total: {usage.total / (1024**3):.2f} GB") |
print('No -o option found') |
||||||
print(f"Used: {usage.used / (1024**3):.2f} GB") |
|
||||||
print(f"Free: {usage.free / (1024**3):.2f} GB") |
|
||||||
print(f"Percentage: {usage.percent}%") |
|
||||||
|
|||||||
@ -0,0 +1,74 @@ |
|||||||
|
import redis,time,requests,json,os |
||||||
|
|
||||||
|
|
||||||
|
def getOrderInfoByOrderId(orderId): |
||||||
|
try: |
||||||
|
|
||||||
|
url = "https://mp.api.suwa3d.com/api/physical/infoModelSizeByOrderId?order_id="+str(orderId) |
||||||
|
print("url:",url) |
||||||
|
res = requests.get(url) |
||||||
|
if res.status_code != 200: |
||||||
|
print('获取失败,程序退出') |
||||||
|
return "error","error" |
||||||
|
print("res",res) |
||||||
|
res = json.loads(res.text) |
||||||
|
print("res",res) |
||||||
|
#获取到model_size |
||||||
|
modelSize = res['data']['model_size'] |
||||||
|
pid = res['data']['pid'] |
||||||
|
return pid,modelSize |
||||||
|
|
||||||
|
except Exception as e: |
||||||
|
print(f"获取订单信息异常: {str(e)}") |
||||||
|
return "error","error" |
||||||
|
|
||||||
|
if __name__ == '__main__': |
||||||
|
r = redis.Redis(host="106.14.158.208",password="kcV2000",port=6379,db=6) |
||||||
|
while True: |
||||||
|
print(f"时间-{time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())}") |
||||||
|
if r.llen('model:weight') == 0: |
||||||
|
print('队列为空,等待10秒') |
||||||
|
time.sleep(10) |
||||||
|
continue |
||||||
|
|
||||||
|
# info 的数据格式为有以下几种情况 1. orderId 2 orderId_print_9,1.2,45,27 3. orderId_auto_9,1.2,45,27 |
||||||
|
info = r.lpop('model:weight') |
||||||
|
if info is None: |
||||||
|
print('队列为空,等待10秒') |
||||||
|
time.sleep(10) |
||||||
|
info = info.decode('utf-8') |
||||||
|
orderId = 0 |
||||||
|
pid = 0 |
||||||
|
modelSize = [] |
||||||
|
typeModel = "print" |
||||||
|
#判断info是什么类型的数据 |
||||||
|
arrInfo = info.split("_") |
||||||
|
if len(arrInfo) == 1: |
||||||
|
orderId = arrInfo[0] |
||||||
|
pid,modelSize = getOrderInfoByOrderId(orderId) |
||||||
|
if pid == "error": |
||||||
|
print("获取订单信息失败") |
||||||
|
continue |
||||||
|
|
||||||
|
elif len(arrInfo) == 3: |
||||||
|
orderId = arrInfo[0] |
||||||
|
pid,temp = getOrderInfoByOrderId(orderId) |
||||||
|
if pid == "error": |
||||||
|
print("获取订单信息失败") |
||||||
|
continue |
||||||
|
typeModel = arrInfo[1] |
||||||
|
modelSize = arrInfo[2] |
||||||
|
if typeModel != "print" and typeModel != "auto": |
||||||
|
print("typeModel类型不对") |
||||||
|
continue |
||||||
|
|
||||||
|
|
||||||
|
if int(orderId) == 0 or int(pid) == 0 or len(modelSize) == 0: |
||||||
|
print("orderId pid modelSize 有出现问题") |
||||||
|
continue |
||||||
|
|
||||||
|
#转成数组 |
||||||
|
arrModelSize = modelSize.split(",") |
||||||
|
print(f'执行脚本--- "python D:/make2/tools/cal_weight.py {typeModel} {pid} {modelSize} {orderId}"') |
||||||
|
#发起计算请求 |
||||||
|
os.system(f"python D:/make2/tools/cal_weight.py {typeModel} {pid} {modelSize} {orderId}") |
||||||
@ -0,0 +1,8 @@ |
|||||||
|
import time,os |
||||||
|
if __name__ == '__main__': |
||||||
|
#开启死循环 |
||||||
|
while True: |
||||||
|
#检测当前打印 和 脚底板 和 gs 队列长度 |
||||||
|
os.system("python E:\\make2\\tools\\push_cmd.py auto_view") |
||||||
|
#一个小时检测一次 |
||||||
|
time.sleep(60*60) |
||||||
@ -0,0 +1,102 @@ |
|||||||
|
import platform,sys,redis,time,requests,json,atexit |
||||||
|
sys.path.append('../libs/') |
||||||
|
|
||||||
|
import config,libs,libs_db_temp,common |
||||||
|
|
||||||
|
import os, sys, time, argparse, requests, json, re, oss2, probreg |
||||||
|
import bpy, bmesh |
||||||
|
import open3d as o3d |
||||||
|
import numpy as np |
||||||
|
import cupy as cp |
||||||
|
from mathutils import Matrix |
||||||
|
import math |
||||||
|
import logging |
||||||
|
import matplotlib.pyplot as plt |
||||||
|
|
||||||
|
#获取真实身高 |
||||||
|
def get_real_height(input_path): |
||||||
|
get_real_height_url = 'https://mp.api.suwa3d.com/api/physical/infoByPid' |
||||||
|
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}: Getting real height from {input_path}') |
||||||
|
pid = re.findall(r'(\d+)', input_path)[0] |
||||||
|
print(f'pid: {pid}') |
||||||
|
res = requests.get(get_real_height_url, params={'pid': pid}) |
||||||
|
res = json.loads(res.text) |
||||||
|
if res['code'] == -1: |
||||||
|
print(f'Error: {res["message"]}, return default height 160') |
||||||
|
return 160 |
||||||
|
height = res['data']['height'] |
||||||
|
if height == 0: |
||||||
|
print(f'Error: height=0, return default height 160') |
||||||
|
return 160 |
||||||
|
print(f'height: {height}') |
||||||
|
return height |
||||||
|
|
||||||
|
|
||||||
|
def base_fix(input_path): |
||||||
|
if not os.path.exists(input_path): |
||||||
|
print(f'Error: {input_path} does not exist.') |
||||||
|
sys.exit(1) |
||||||
|
|
||||||
|
bpy.ops.wm.read_homefile() |
||||||
|
bpy.ops.object.delete(use_global=False, confirm=False) |
||||||
|
bpy.ops.wm.obj_import(filepath=input_path) |
||||||
|
bpy.context.scene.unit_settings.scale_length = 1 |
||||||
|
bpy.context.scene.unit_settings.length_unit = 'CENTIMETERS' |
||||||
|
bpy.context.scene.unit_settings.mass_unit = 'GRAMS' |
||||||
|
|
||||||
|
obj = bpy.context.selected_objects[0] |
||||||
|
bpy.context.view_layer.objects.active = obj |
||||||
|
obj.select_set(True) |
||||||
|
|
||||||
|
# 脚底贴地 |
||||||
|
bpy.ops.object.align(align_mode='OPT_1', relative_to='OPT_1', align_axis={'Z'}) |
||||||
|
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True) |
||||||
|
|
||||||
|
real_height = get_real_height(input_path) |
||||||
|
print(obj.dimensions) |
||||||
|
scale = real_height / obj.dimensions[2] / 100 # 除以100是因为单位是厘米 |
||||||
|
bpy.context.object.scale = (scale, scale, scale) |
||||||
|
bpy.context.object.rotation_euler = (0, 0, 0) |
||||||
|
bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_VOLUME', center='MEDIAN') |
||||||
|
bpy.context.object.location[0] = 0 # 移动到特定位置(1m, 1m)是为了让human3d可以正确识别 |
||||||
|
bpy.context.object.location[1] = 0 |
||||||
|
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True) |
||||||
|
|
||||||
|
# # bpy.ops.wm.save_mainfile(filepath=args.input_path.replace('.obj', '.blend')) |
||||||
|
output_file = input_path.replace('.obj', '_baseFixed.obj') |
||||||
|
bpy.ops.wm.obj_export(filepath=output_file) |
||||||
|
return obj |
||||||
|
|
||||||
|
|
||||||
|
def readTask(): |
||||||
|
# #读取数据库的任务 |
||||||
|
# pid = libs_db_temp.get_task_by_level() |
||||||
|
# pid = str(pid) |
||||||
|
# #下载pid的对应的oss端的文件 |
||||||
|
# tempName = libs.down_obj_from_oss_for_fix("E://obj_fix", pid, "print") |
||||||
|
# if tempName == "": |
||||||
|
# print("找不到对应的obj文件") |
||||||
|
# #记录状态为异常 -1 |
||||||
|
# libs_db_temp.update_fix_status(pid,-1) |
||||||
|
# return "" |
||||||
|
|
||||||
|
# #记录状态为处理中 |
||||||
|
# libs_db_temp.update_fix_status(pid,1) |
||||||
|
# #处理逻辑 |
||||||
|
# return pid |
||||||
|
pid=7013 |
||||||
|
|
||||||
|
base_fix(f'E://obj_fix/{pid}/{pid}.obj') |
||||||
|
|
||||||
|
# print(pid) |
||||||
|
# print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())+"-读取数据库任务") |
||||||
|
|
||||||
|
#程序主入口 |
||||||
|
if __name__ == '__main__': |
||||||
|
#atexit.register(common.notify,"处理数据校准任务已经停止") |
||||||
|
readTask() |
||||||
|
# while True: |
||||||
|
# print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())+"-开始执行任务") |
||||||
|
# pid = readTask() |
||||||
|
# if pid != "": |
||||||
|
# break |
||||||
@ -0,0 +1,43 @@ |
|||||||
|
import os,sys,requests,json |
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__": |
||||||
|
#获取参数 |
||||||
|
args = sys.argv |
||||||
|
print("args:",args) |
||||||
|
if len(args) != 2: |
||||||
|
print("参数错误") |
||||||
|
exit() |
||||||
|
|
||||||
|
pid = args[1] |
||||||
|
print("pid",pid) |
||||||
|
#根据pid查询order_id的集合 |
||||||
|
url="https://mp.api.suwa3d.com/api/physical/listOrderIdByPid?pid="+str(pid) |
||||||
|
res=requests.get(url) |
||||||
|
if res.status_code != 200: |
||||||
|
print('获取失败,程序退出') |
||||||
|
exit() |
||||||
|
res = json.loads(res.text) |
||||||
|
print("res",res) |
||||||
|
if res["code"] != 1000: |
||||||
|
exit() |
||||||
|
orderIds = res['data'] |
||||||
|
print("orderIds:",orderIds) |
||||||
|
#循环处理 |
||||||
|
for orderId in orderIds: |
||||||
|
#os.system(f"python D:/make2/tools/cal_weight.py print {pid} {orderId}") |
||||||
|
url = "https://mp.api.suwa3d.com/api/physical/infoModelSizeByOrderId?order_id="+str(orderId) |
||||||
|
print("url:",url) |
||||||
|
res = requests.get(url) |
||||||
|
if res.status_code != 200: |
||||||
|
print('获取失败,程序退出') |
||||||
|
continue |
||||||
|
print("res",res) |
||||||
|
res = json.loads(res.text) |
||||||
|
print("res",res) |
||||||
|
#获取到model_size |
||||||
|
modelSize = res['data']['model_size'] |
||||||
|
pid = res['data']['pid'] |
||||||
|
print(f"执行脚本 python D:/make2/tools/cal_weight.py auto {pid} {modelSize} {orderId}") |
||||||
|
os.system(f"python D:/make2/tools/cal_weight.py auto {pid} {modelSize} {orderId}") |
||||||
|
# python D:/make2/tools/get_weight_by_pid.py |
||||||
@ -0,0 +1,6 @@ |
|||||||
|
1. pip install -r requirements.txt安装requirements.txt所需的python包 (python3.10) |
||||||
|
2. 使用python optimize_model.py -ip 输入的obj路径 -op 输出的obj路径 |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
python optimize_model.py -ip "D:\finished\190104\output\190104.obj" -op "D:\finished\190104\output\190104_new.obj" |
||||||
@ -0,0 +1,381 @@ |
|||||||
|
import os, time, json, requests, shutil, oss2, psutil |
||||||
|
from tqdm import tqdm |
||||||
|
from PIL import Image, ImageEnhance |
||||||
|
import config,libs_db,common |
||||||
|
import threading |
||||||
|
from concurrent.futures import ThreadPoolExecutor |
||||||
|
|
||||||
|
def find_blender_bin_path(): |
||||||
|
base_path = 'C:\\Program Files\\Blender Foundation\\' |
||||||
|
if os.path.exists(base_path): |
||||||
|
for dir in os.listdir(base_path): |
||||||
|
if dir.startswith('Blender'): |
||||||
|
blender_bin_path = base_path + dir + '\\blender.exe' |
||||||
|
return f'"{blender_bin_path}"' |
||||||
|
else: |
||||||
|
print('未找到blender安装目录') |
||||||
|
exit(1) |
||||||
|
|
||||||
|
def resize_photos(photo_path, ratio=0.5): |
||||||
|
for filename in os.listdir(photo_path): |
||||||
|
if filename.endswith('.jpg'): |
||||||
|
img = Image.open(os.path.join(photo_path, filename)) |
||||||
|
img = rotate_image(img) |
||||||
|
w, h = img.size |
||||||
|
img = img.resize((int(w * ratio), int(h * ratio))) |
||||||
|
img.save(os.path.join(photo_path, filename)) |
||||||
|
|
||||||
|
def rotate_image(image): |
||||||
|
# 检查图像的EXIF数据是否包含方向信息 |
||||||
|
try: |
||||||
|
exif = image._getexif() |
||||||
|
orientation = exif.get(0x0112) |
||||||
|
except: |
||||||
|
orientation = None |
||||||
|
|
||||||
|
# 根据方向信息旋转图像 |
||||||
|
if orientation == 3: |
||||||
|
image = image.rotate(180, expand=True) |
||||||
|
elif orientation == 6: |
||||||
|
image = image.rotate(270, expand=True) |
||||||
|
elif orientation == 8: |
||||||
|
image = image.rotate(90, expand=True) |
||||||
|
return image |
||||||
|
|
||||||
|
def get_ps_adjust_photo_para(psid): |
||||||
|
res = requests.get(config.urls['get_ps_adjust_photo_para_url'], params={'id': psid}) |
||||||
|
print(res.json()) |
||||||
|
paras = res.json()['data'] |
||||||
|
brightness_factor, saturation_factor, temperature_factor = float(paras['brightness']), float(paras['saturation']), float(paras['colorTemperature']) |
||||||
|
return brightness_factor, saturation_factor, temperature_factor |
||||||
|
|
||||||
|
def adjust_photos(workdir, pid): |
||||||
|
def adjust_brightness(image, brightness_factor): |
||||||
|
if brightness_factor == 1 or brightness_factor == 0 : |
||||||
|
return image |
||||||
|
enhancer = ImageEnhance.Brightness(image) |
||||||
|
adjusted_image = enhancer.enhance(brightness_factor) |
||||||
|
return adjusted_image |
||||||
|
|
||||||
|
def adjust_saturation(image, saturation_factor): |
||||||
|
if saturation_factor == 1: |
||||||
|
return image |
||||||
|
enhancer = ImageEnhance.Color(image) |
||||||
|
adjusted_image = enhancer.enhance(saturation_factor) |
||||||
|
return adjusted_image |
||||||
|
|
||||||
|
def adjust_temperature(image, temperature_factor): |
||||||
|
if temperature_factor == 1: |
||||||
|
return image |
||||||
|
r, g, b = image.split() |
||||||
|
r = r.point(lambda i: i * temperature_factor) |
||||||
|
adjusted_image = Image.merge("RGB", (r, g, b)) |
||||||
|
return adjusted_image |
||||||
|
if not os.path.exists(os.path.join(workdir, pid, 'photo2')): |
||||||
|
print(f"Directory {os.path.join(workdir, pid, 'photo2')} does not exist") |
||||||
|
return False |
||||||
|
|
||||||
|
psid = getPSid(pid) |
||||||
|
brightness_factor, saturation_factor, temperature_factor = get_ps_adjust_photo_para(psid) |
||||||
|
|
||||||
|
if (brightness_factor == 1 and saturation_factor == 1 and temperature_factor == 1): |
||||||
|
print("No need to adjust") |
||||||
|
return False |
||||||
|
if os.path.exists(os.path.join(workdir, pid, 'photo3')): |
||||||
|
print(f'{os.path.join(workdir, pid, "photo3")}目录已存在,跳过') |
||||||
|
return |
||||||
|
os.makedirs(os.path.join(workdir, pid, 'photo3'), exist_ok=True) |
||||||
|
|
||||||
|
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 开始调整图片曝光...') |
||||||
|
start_time = time.time() |
||||||
|
for filename in os.listdir(os.path.join(workdir, pid, 'photo2')): |
||||||
|
if filename.endswith(".jpg"): |
||||||
|
# print(f"Adjusting {filename}:brightness={brightness_factor}, saturation={saturation_factor}, temperature={temperature_factor}") |
||||||
|
image = Image.open(os.path.join(workdir, pid, 'photo2', filename)) |
||||||
|
image = rotate_image(image) |
||||||
|
|
||||||
|
brightened_image = adjust_brightness(image, brightness_factor) |
||||||
|
saturated_image = adjust_saturation(brightened_image, saturation_factor) |
||||||
|
adjusted_image = adjust_temperature(saturated_image, temperature_factor) |
||||||
|
|
||||||
|
adjusted_image.save(os.path.join(workdir, pid, 'photo3', filename)) |
||||||
|
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 图片曝光调整完成,共费时{diff_time(start_time)}') |
||||||
|
return True |
||||||
|
|
||||||
|
def getPSid(pid): |
||||||
|
res = requests.get(config.urls['get_psid_url'], params={'pid': pid}) |
||||||
|
print('get_psid_url:', res.url) |
||||||
|
print('res:', res.text) |
||||||
|
res = json.loads(res.text) |
||||||
|
return str(res['data']) |
||||||
|
|
||||||
|
def getHeadCount(pid): |
||||||
|
res = requests.get(config.urls['get_printinfo_url'], params={'id': pid}) |
||||||
|
print('get_printinfo_url:', res.url) |
||||||
|
print('res:', res.text) |
||||||
|
if res.status_code != 200: |
||||||
|
print('获取人数失败,程序退出') |
||||||
|
exit(1) |
||||||
|
res = json.loads(res.text) |
||||||
|
return res['data']['headcount'] |
||||||
|
|
||||||
|
def get_ps_type(pid): |
||||||
|
# return 1:圆形影棚 2:方形影棚 |
||||||
|
res = requests.get(config.urls['get_ps_type_url'], params={'pid': pid}) |
||||||
|
return res.json()['data']['type'] |
||||||
|
|
||||||
|
def find_valid_camera_on_oss(pid): |
||||||
|
if get_ps_type(pid) == 1: |
||||||
|
print('当前拍照影棚为:圆形影棚') |
||||||
|
cameras = (103, 93, 113) |
||||||
|
else: |
||||||
|
print('当前拍照影棚为:方形影棚') |
||||||
|
cameras = (74, 64, 84) |
||||||
|
find_camera = 0 |
||||||
|
for camera in cameras: |
||||||
|
objectkey = f'photos/{pid}/photo2/{camera}_8.jpg' |
||||||
|
find = config.oss_bucket.object_exists(objectkey) |
||||||
|
if find: |
||||||
|
find_camera = camera |
||||||
|
break |
||||||
|
|
||||||
|
print('找到有效正脸相机:', find_camera) |
||||||
|
if find_camera == 0: |
||||||
|
print('{cameras}没有找到照片,程序退出') |
||||||
|
exit(1) |
||||||
|
return find_camera |
||||||
|
|
||||||
|
def aliyun_face(pid): |
||||||
|
high = False |
||||||
|
style = 'imm/detectface' |
||||||
|
camera = find_valid_camera_on_oss(pid) |
||||||
|
objectkey = f'photos/{pid}/photo2/{camera}_8.jpg' |
||||||
|
try: |
||||||
|
res = config.oss_bucket.get_object(objectkey, process=style) |
||||||
|
except oss2.exceptions.NoSuchKey: |
||||||
|
print('没有找到文件:', objectkey) |
||||||
|
return high |
||||||
|
res = json.loads(res.read()) |
||||||
|
if res['success']: |
||||||
|
if res['Faces'] is None: |
||||||
|
print('no face') |
||||||
|
return None |
||||||
|
else: |
||||||
|
print('faces num:', len(res['Faces'])) |
||||||
|
for face in res['Faces']: |
||||||
|
print('-' * 20) |
||||||
|
print('face_id:', face['FaceId']) |
||||||
|
print('gender:', face['Gender']) |
||||||
|
print('age:', face['Age']) |
||||||
|
|
||||||
|
if face['Gender'] == 'FEMALE' and face['Age'] < 22: high = True |
||||||
|
if face['Gender'] == 'MALE' and face['Age'] < 15: high = True |
||||||
|
else: |
||||||
|
print('face detect failed...') |
||||||
|
return high |
||||||
|
|
||||||
|
def down_obj_from_oss(workdir, pid, action): |
||||||
|
if os.path.exists(os.path.join(workdir, action, pid)): |
||||||
|
print(f'目录{os.path.join(workdir, action, pid)}已存在,跳过') |
||||||
|
return |
||||||
|
else: |
||||||
|
os.makedirs(os.path.join(workdir, action, pid)) |
||||||
|
|
||||||
|
# 根据前缀获取文件列表 |
||||||
|
prefix = f'objs/{action}/{pid}/' |
||||||
|
filelist = oss2.ObjectIteratorV2(config.oss_bucket, prefix=prefix) |
||||||
|
print('正在下载:', prefix) |
||||||
|
obj_filename = "" |
||||||
|
for file in filelist: |
||||||
|
filename = file.key.split('/')[-1] |
||||||
|
if filename.endswith('.obj'): |
||||||
|
obj_filename = filename |
||||||
|
# print('正在下载:', file.key) |
||||||
|
localfile = os.path.join(workdir, action, pid, filename) |
||||||
|
config.oss_bucket.get_object_to_file(file.key, localfile) |
||||||
|
|
||||||
|
return obj_filename |
||||||
|
|
||||||
|
def set_photos_join_type(workdir, pid, photoN, mesh = '0', texture='0'): |
||||||
|
photoN_path = os.path.join(workdir, pid, photoN) |
||||||
|
for xmp in os.listdir(photoN_path): |
||||||
|
if xmp.endswith('.xmp'): |
||||||
|
xmp_path = os.path.join(photoN_path, xmp) |
||||||
|
with open(xmp_path, 'r') as f: |
||||||
|
lines = f.readlines() |
||||||
|
lines = [line.replace('xcr:InMeshing="0"', f'xcr:InMeshing="{mesh}"') for line in lines] |
||||||
|
lines = [line.replace('xcr:InMeshing="1"', f'xcr:InMeshing="{mesh}"') for line in lines] |
||||||
|
lines = [line.replace('xcr:InTexturing="0"', f'xcr:InTexturing="{texture}"') for line in lines] |
||||||
|
lines = [line.replace('xcr:InTexturing="1"', f'xcr:InTexturing="{texture}"') for line in lines] |
||||||
|
with open(xmp_path, 'w') as f: |
||||||
|
f.writelines(lines) |
||||||
|
|
||||||
|
def set_photo_join_type(workdir, pid, photoN, camera_id, mesh = '0', texture='0'): |
||||||
|
if photoN == 'photo1': |
||||||
|
filename = os.path.join(workdir, pid, photoN, f'{camera_id}_1.xmp') |
||||||
|
else: |
||||||
|
filename = os.path.join(workdir, pid, photoN, f'{camera_id}_8.xmp') |
||||||
|
with open(filename, 'r') as f: |
||||||
|
lines = f.readlines() |
||||||
|
lines = [line.replace('xcr:InMeshing="0"', f'xcr:InMeshing="{mesh}"') for line in lines] |
||||||
|
lines = [line.replace('xcr:InMeshing="1"', f'xcr:InMeshing="{mesh}"') for line in lines] |
||||||
|
lines = [line.replace('xcr:InTexturing="0"', f'xcr:InTexturing="{texture}"') for line in lines] |
||||||
|
lines = [line.replace('xcr:InTexturing="1"', f'xcr:InTexturing="{texture}"') for line in lines] |
||||||
|
with open(filename, 'w') as f: |
||||||
|
f.writelines(lines) |
||||||
|
|
||||||
|
def down_from_oss(oss_client, workdir, pid, per=100,photoPath=""): |
||||||
|
start_time = time.time() |
||||||
|
path = os.path.join(workdir, pid) |
||||||
|
if os.path.exists(path): |
||||||
|
print(f"Directory {path} already exists, skip") |
||||||
|
return |
||||||
|
os.makedirs(os.path.join(path, 'photo1')) |
||||||
|
os.makedirs(os.path.join(path, 'photo2')) |
||||||
|
|
||||||
|
psid = getPSid(pid) |
||||||
|
# 根据前缀获取文件列表 |
||||||
|
prefix = f'photos/{pid}/' |
||||||
|
filelist = oss2.ObjectIteratorV2(oss_client, prefix=prefix) |
||||||
|
for file in tqdm(filelist): |
||||||
|
filename = file.key.split('/')[-1] |
||||||
|
localfile = "" |
||||||
|
# print('正在下载:', file.key) |
||||||
|
if photoPath == "": |
||||||
|
if filename.endswith('_1.jpg'): |
||||||
|
localfile = os.path.join(path, 'photo1', filename) |
||||||
|
else: |
||||||
|
localfile = os.path.join(path, 'photo2', filename) |
||||||
|
else: |
||||||
|
if photoPath=="1": |
||||||
|
if filename.endswith('_1.jpg'): |
||||||
|
localfile = os.path.join(path, 'photo1', filename) |
||||||
|
else: |
||||||
|
if filename.endswith('_8.jpg'): |
||||||
|
localfile = os.path.join(path, 'photo2', filename) |
||||||
|
if localfile == "": |
||||||
|
continue |
||||||
|
style = f'image/resize,p_{per}' |
||||||
|
if per == 100: |
||||||
|
oss_client.get_object_to_file(file.key, localfile) |
||||||
|
else: |
||||||
|
oss_client.get_object_to_file(file.key, localfile, process=style) |
||||||
|
|
||||||
|
#判断localfile 是否有包含 photo2 |
||||||
|
|
||||||
|
|
||||||
|
#遍历处理photo2的数数据 |
||||||
|
# if str(psid) == "96" or str(pid) == "118994": |
||||||
|
# path = os.path.join(workdir, pid, 'photo2') |
||||||
|
# files = [] |
||||||
|
# for fileName in os.listdir(path): |
||||||
|
# if ".jpg" in fileName: |
||||||
|
# files.append(path+"\\"+fileName) |
||||||
|
# beginTime = time.time() |
||||||
|
# with ThreadPoolExecutor(max_workers=6) as executor: |
||||||
|
# executor.map(process_image, files) |
||||||
|
|
||||||
|
# print(f'{localfile}灰度处理费时{diff_time(beginTime)}') |
||||||
|
|
||||||
|
|
||||||
|
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 图片下载完成, 共费时{diff_time(start_time)}') |
||||||
|
|
||||||
|
#灰度处理图片 |
||||||
|
def process_image(localfile): |
||||||
|
if ".jpg" in localfile: |
||||||
|
common.remove_gray_and_sharpening(localfile) |
||||||
|
|
||||||
|
def get_defineDistances(psid): |
||||||
|
res = '' |
||||||
|
distances = libs_db.get_floor_sticker_distances(psid).split(';') |
||||||
|
print("distances",distances) |
||||||
|
for d in distances: |
||||||
|
p1, p2, distance = d.split(' ') |
||||||
|
res = res + f' -defineDistance {p1} {p2} {distance}' |
||||||
|
return res.strip() |
||||||
|
|
||||||
|
def is_running(psname): |
||||||
|
for p in psutil.process_iter(['name']): |
||||||
|
if psname.strip() in p.info['name']: |
||||||
|
return True |
||||||
|
return False |
||||||
|
|
||||||
|
def diff_time(start_time): |
||||||
|
# 按照分:秒的方式返回时间差 |
||||||
|
end_time = time.time() |
||||||
|
diff = end_time - start_time |
||||||
|
m, s = divmod(diff, 60) |
||||||
|
return f'{int(m)}分{int(s)}秒' |
||||||
|
|
||||||
|
def down_obj_from_oss_for_fix(workdir, pid, action): |
||||||
|
if os.path.exists(os.path.join(workdir, action, pid)): |
||||||
|
print(f'目录{os.path.join(workdir, action, pid)}已存在,跳过') |
||||||
|
return |
||||||
|
else: |
||||||
|
os.makedirs(os.path.join(workdir, action, pid)) |
||||||
|
|
||||||
|
# 根据前缀获取文件列表 |
||||||
|
prefix = f'objs/{action}/{pid}/' |
||||||
|
filelist = oss2.ObjectIteratorV2(config.oss_bucket, prefix=prefix) |
||||||
|
print('正在下载:', prefix) |
||||||
|
obj_filename = "" |
||||||
|
for file in filelist: |
||||||
|
filename = file.key.split('/')[-1] |
||||||
|
if filename.endswith(f'{pid}.obj') == False: |
||||||
|
continue |
||||||
|
|
||||||
|
if filename.endswith('.obj'): |
||||||
|
obj_filename = filename |
||||||
|
|
||||||
|
# print('正在下载:', file.key) |
||||||
|
localfile = os.path.join(workdir, action, pid, filename) |
||||||
|
config.oss_bucket.get_object_to_file(file.key, localfile) |
||||||
|
return obj_filename |
||||||
|
|
||||||
|
def down_obj_from_oss_for_repeat_texture(workdir, pid, action): |
||||||
|
print(os.path.join(workdir, pid)) |
||||||
|
if not os.path.exists(os.path.join(workdir, pid)): |
||||||
|
print("目录不存在,无法处理") |
||||||
|
return "error" |
||||||
|
|
||||||
|
#判断是否有专门新建的目录用来重新贴图 |
||||||
|
newPath = os.path.join(workdir, pid,'repeat_texture','completion_cloud') |
||||||
|
if not os.path.exists(newPath): |
||||||
|
os.makedirs(newPath) |
||||||
|
|
||||||
|
|
||||||
|
# 根据前缀获取文件列表 |
||||||
|
prefix = f'objs/{action}/{pid}/ai/repeat_texture/completion_cloud' |
||||||
|
filelist = oss2.ObjectIteratorV2(config.oss_bucket, prefix=prefix) |
||||||
|
print('正在下载:', prefix) |
||||||
|
for file in filelist: |
||||||
|
filename = file.key.split('/')[-1] |
||||||
|
if filename == "": |
||||||
|
continue |
||||||
|
localfile = os.path.join(newPath, filename) |
||||||
|
config.oss_bucket.get_object_to_file(file.key, localfile) |
||||||
|
return newPath |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def down_obj_from_oss_auto(pid,action,pathStr): |
||||||
|
#pathStr = os.path.join(workdir, str(pid)+"_ai") |
||||||
|
if not os.path.exists(pathStr): |
||||||
|
os.makedirs(pathStr) |
||||||
|
|
||||||
|
# 根据前缀获取文件列表 |
||||||
|
prefix = f'objs/{action}/{pid}' |
||||||
|
filelist = oss2.ObjectIteratorV2(config.oss_bucket, prefix=prefix) |
||||||
|
print('正在下载:', prefix) |
||||||
|
for file in filelist: |
||||||
|
filename = file.key.split('/')[-1] |
||||||
|
if filename == "": |
||||||
|
continue |
||||||
|
|
||||||
|
if filename != f"{pid}.jpg" and filename != f"{pid}.obj" and filename != f"{pid}.mtl": |
||||||
|
continue |
||||||
|
|
||||||
|
print(filename) |
||||||
|
localfile = os.path.join(pathStr, filename) |
||||||
|
config.oss_bucket.get_object_to_file(file.key, localfile) |
||||||
@ -0,0 +1,31 @@ |
|||||||
|
import paramiko,time,sys |
||||||
|
|
||||||
|
def main_optimize_model(pid): |
||||||
|
try: |
||||||
|
# 创建SSH对象 |
||||||
|
ssh = paramiko.SSHClient() |
||||||
|
# 允许连接不在known_hosts文件中的主机 |
||||||
|
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) |
||||||
|
print('start connect') |
||||||
|
# 连接服务器 |
||||||
|
ssh.connect('connect.bjc1.seetacloud.com', username='root', password='QoQA8q3Ds2VB', port=33733) |
||||||
|
print('connect success') |
||||||
|
|
||||||
|
# 使用nohup执行命令,并将输出重定向到文件 |
||||||
|
command = f'nohup seg_python /data/code/optimize_model_xj/optimize_model.py -pid {pid} >{pid}.log 2>&1&' |
||||||
|
stdin, stdout, stderr = ssh.exec_command(command) |
||||||
|
|
||||||
|
# 打印命令是否启动成功 |
||||||
|
print("Command executed") |
||||||
|
finally: |
||||||
|
# 确保连接被关闭 |
||||||
|
if ssh: |
||||||
|
time.sleep(1) |
||||||
|
ssh.close() |
||||||
|
|
||||||
|
if __name__ == '__main__': |
||||||
|
|
||||||
|
if len(sys.argv) == 2: |
||||||
|
pid = sys.argv[1] |
||||||
|
main_optimize_model(pid) |
||||||
|
|
||||||
@ -0,0 +1,244 @@ |
|||||||
|
import bpy |
||||||
|
import sys |
||||||
|
import open3d as o3d |
||||||
|
import numpy as np |
||||||
|
from sklearn.neighbors import NearestNeighbors |
||||||
|
import os |
||||||
|
import argparse |
||||||
|
|
||||||
|
def estimate_point_curvatures(point_cloud, k=30): |
||||||
|
point_cloud_points = np.asarray(point_cloud.points) |
||||||
|
# Initialize the nearest neighbors finder |
||||||
|
nn = NearestNeighbors(n_neighbors=k) |
||||||
|
nn.fit(point_cloud_points) |
||||||
|
curvatures = {i: 0 for i in range(len(point_cloud.points))} |
||||||
|
for i, point in enumerate(point_cloud_points): |
||||||
|
# Find the k-nearest neighbors (including the point itself) |
||||||
|
distances, indices = nn.kneighbors([point]) |
||||||
|
neighbors = point_cloud_points[indices[0]] |
||||||
|
# Compute the covariance matrix |
||||||
|
covariance_matrix = np.cov(neighbors - neighbors.mean(axis=0), rowvar=False) |
||||||
|
# Compute the eigenvalues (sorted) |
||||||
|
eigenvalues, _ = np.linalg.eigh(covariance_matrix) |
||||||
|
eigenvalues.sort() |
||||||
|
# Calculate curvature using the smallest eigenvalue |
||||||
|
curvature = eigenvalues[0] / sum(eigenvalues) |
||||||
|
curvatures[i] = curvature |
||||||
|
return curvatures |
||||||
|
|
||||||
|
def compute_adjacent_normal_angle_variance(pcd, pcd_normal, distance_scale): |
||||||
|
kdtree = o3d.geometry.KDTreeFlann(pcd) |
||||||
|
distances = [] |
||||||
|
for i in range(len(pcd.points)): |
||||||
|
[k, idx, dist] = kdtree.search_knn_vector_3d(pcd.points[i], 2) |
||||||
|
dist = dist[1:] # distances to the actual neighbors |
||||||
|
distances.append(dist) |
||||||
|
mean_distance = np.mean(distances) |
||||||
|
adjacent_normal_angles_variance = {i: 0 for i in range(len(np.asarray(pcd.points)))} |
||||||
|
for i, point in enumerate(pcd.points): |
||||||
|
# Search for the k-nearest neighbors of the point, up to 1500 |
||||||
|
k, idx, dist = kdtree.search_knn_vector_3d(point, 200) |
||||||
|
idx = np.asarray(idx) |
||||||
|
indices = idx[dist < mean_distance * distance_scale] |
||||||
|
current_normal = pcd_normal[i] |
||||||
|
# Calculate dot products between the current normal and its neighbors' normals |
||||||
|
dot_products = np.dot(pcd_normal[indices], current_normal) |
||||||
|
# Handle any potential NaN values in dot products |
||||||
|
valid_dot_products = np.isfinite(dot_products) |
||||||
|
dot_products = dot_products[valid_dot_products] |
||||||
|
# Clip dot product values to valid range for arccos |
||||||
|
dot_products = np.clip(dot_products, -1.0, 1.0) |
||||||
|
# Compute angles in degrees and adjust for any NaNs which might be due to numerical errors |
||||||
|
angles_array = np.degrees(np.arccos(dot_products)) |
||||||
|
# Set the angle with itself to zero since it's not meaningful |
||||||
|
angles_array[indices == i] = 0 |
||||||
|
# Calculate the mean angle excluding the zero for the current point |
||||||
|
valid_angles = angles_array[indices != i] |
||||||
|
if valid_angles.size > 0: |
||||||
|
adjacent_normal_angles_variance[i] = np.std(valid_angles) |
||||||
|
else: |
||||||
|
adjacent_normal_angles_variance[i] = 0 # Default to 0 if no valid neighbors exist |
||||||
|
return adjacent_normal_angles_variance |
||||||
|
|
||||||
|
def compute_adjacent_point_vector_degrees_mean(pcd, pcd_normal, distance_scale): |
||||||
|
kdtree = o3d.geometry.KDTreeFlann(pcd) |
||||||
|
distances = [] |
||||||
|
for i in range(len(pcd.points)): |
||||||
|
[k, idx, dist] = kdtree.search_knn_vector_3d(pcd.points[i], 2) |
||||||
|
dist = dist[1:] # distances to the actual neighbors |
||||||
|
distances.append(dist) |
||||||
|
mean_distance = np.mean(distances) |
||||||
|
adjacent_point_vector_degrees_mean = {i: 0 for i in range(len(np.asarray(pcd.points)))} |
||||||
|
for i, point in enumerate(pcd.points): |
||||||
|
# Search for the k-nearest neighbors of the point, up to 200 |
||||||
|
k, idx, dist = kdtree.search_knn_vector_3d(point, 200) |
||||||
|
idx = np.asarray(idx) |
||||||
|
indices = idx[dist < mean_distance * distance_scale] |
||||||
|
indices = indices[indices != i] |
||||||
|
# Retrieve the normal of the current point |
||||||
|
current_normal = pcd_normal[i] |
||||||
|
adjacent_point_vector = np.asarray(pcd.points)[indices] - point |
||||||
|
adjacent_point_vector_cos = np.dot(adjacent_point_vector, current_normal) / np.linalg.norm(adjacent_point_vector, axis = 1) * 1 |
||||||
|
valid_adjacent_point_vector_cos = np.isfinite(adjacent_point_vector_cos) |
||||||
|
adjacent_point_vector_cos = adjacent_point_vector_cos[valid_adjacent_point_vector_cos] |
||||||
|
if len(adjacent_point_vector_cos) > 0: |
||||||
|
adjacent_point_vector_degrees = np.degrees(np.arccos(adjacent_point_vector_cos)) |
||||||
|
adjacent_point_vector_mean_degrees = np.mean(adjacent_point_vector_degrees) |
||||||
|
adjacent_point_vector_degrees_mean[i] = adjacent_point_vector_mean_degrees |
||||||
|
else: |
||||||
|
adjacent_point_vector_degrees_mean[i] = 0 |
||||||
|
return adjacent_point_vector_degrees_mean |
||||||
|
|
||||||
|
def spread_point(pcd, selected_index, distance_scale, count = False): |
||||||
|
kdtree = o3d.geometry.KDTreeFlann(pcd) |
||||||
|
distances = [] |
||||||
|
for i in range(len(pcd.points)): |
||||||
|
[k, idx, dist] = kdtree.search_knn_vector_3d(pcd.points[i], 2) |
||||||
|
dist = dist[1:] # distances to the actual neighbors |
||||||
|
distances.append(dist) |
||||||
|
mean_distance = np.mean(distances) |
||||||
|
if count is False: |
||||||
|
spread_selected_index = set() |
||||||
|
for i in selected_index: |
||||||
|
k, idx, dist = kdtree.search_knn_vector_3d(pcd.points[i], 200) |
||||||
|
idx = np.asarray(idx) |
||||||
|
dist = np.asarray(dist) |
||||||
|
indices = idx[dist < mean_distance * distance_scale] |
||||||
|
spread_selected_index.update(indices) |
||||||
|
spread_selected_index = np.array(list(spread_selected_index)) |
||||||
|
else: |
||||||
|
spread_selected_index = {i: 0 for i in range(len(np.asarray(pcd.points)))} |
||||||
|
for i in selected_index: |
||||||
|
k, idx, dist = kdtree.search_knn_vector_3d(pcd.points[i], 200) |
||||||
|
idx = np.asarray(idx) |
||||||
|
dist = np.asarray(dist) |
||||||
|
indices = idx[dist < mean_distance * distance_scale] |
||||||
|
for indice in indices: |
||||||
|
spread_selected_index[indice] += 1 |
||||||
|
return spread_selected_index |
||||||
|
|
||||||
|
def ApplySmoothEffort(object, selected_vertice_indices = None, factor = 0.5, iterations = 30): |
||||||
|
if selected_vertice_indices is not None: |
||||||
|
# Assuming 'mesh' is already defined, e.g., mesh = bpy.context.object.data |
||||||
|
selected_vertices_index = set() # Initialize an empty set to store unique vertex indices |
||||||
|
# Iterate over each index in the list of polygon indices |
||||||
|
for idx in selected_vertice_indices: |
||||||
|
polygon = object.data.polygons[idx] |
||||||
|
for vert_idx in polygon.vertices: |
||||||
|
selected_vertices_index.add(vert_idx) |
||||||
|
# Switch to Edit mode |
||||||
|
bpy.ops.object.mode_set(mode='EDIT') |
||||||
|
# Ensure we're dealing with the latest data |
||||||
|
bpy.ops.object.mode_set(mode='OBJECT') |
||||||
|
for i, vertex in enumerate(object.data.vertices): |
||||||
|
vertex.select = False |
||||||
|
if i in selected_vertices_index: |
||||||
|
vertex.select = True |
||||||
|
# Update the object to reflect changes |
||||||
|
bpy.ops.object.mode_set(mode='EDIT') |
||||||
|
bpy.ops.object.mode_set(mode='OBJECT') |
||||||
|
# Add a Smooth modifier and set it to use the vertex group |
||||||
|
smooth_mod = object.modifiers.new(name="SmoothMod", type='SMOOTH') |
||||||
|
if selected_vertice_indices is not None: |
||||||
|
# Create a new vertex group |
||||||
|
group = object.vertex_groups.new(name='Smooth Group') |
||||||
|
# Add selected vertices to the vertex group |
||||||
|
group.add([v.index for v in object.data.vertices if v.select], weight=1.0, type='ADD') |
||||||
|
smooth_mod.vertex_group = 'Smooth Group' |
||||||
|
smooth_mod.factor = factor |
||||||
|
smooth_mod.iterations = iterations |
||||||
|
# bpy.ops.object.modifier_apply(modifier="SmoothMod") |
||||||
|
# if selected_vertice_indices is not None: |
||||||
|
# object.vertex_groups.clear() |
||||||
|
|
||||||
|
def process(input_mesh_path, output_mesh_path): |
||||||
|
# Select and delete all objects in the current scene to start fresh |
||||||
|
bpy.ops.object.select_all(action='SELECT') |
||||||
|
bpy.ops.object.delete(confirm=False) |
||||||
|
# Path to the OBJ file to be imported |
||||||
|
bpy.ops.wm.obj_import(filepath=input_mesh_path) |
||||||
|
# Set the current object to the newly imported mesh |
||||||
|
current_obj = bpy.context.object |
||||||
|
# Retrieve the mesh data from the current object |
||||||
|
mesh_data = current_obj.data |
||||||
|
bpy.context.view_layer.update() |
||||||
|
# Convert Blender mesh vertices to a NumPy array |
||||||
|
vertices_array = np.array([vertex.co[:] for vertex in mesh_data.vertices]) |
||||||
|
# Convert Blender mesh polygons to a NumPy array of triangles |
||||||
|
triangles_array = np.array([polygon.vertices[:] for polygon in mesh_data.polygons]) |
||||||
|
|
||||||
|
# Create an Open3D mesh object from the arrays |
||||||
|
open3d_mesh = o3d.geometry.TriangleMesh() |
||||||
|
open3d_mesh.vertices = o3d.utility.Vector3dVector(vertices_array) |
||||||
|
open3d_mesh.triangles = o3d.utility.Vector3iVector(triangles_array) |
||||||
|
open3d_mesh.compute_triangle_normals() |
||||||
|
# Retrieve and store the normals as a NumPy array |
||||||
|
triangle_normals_array = np.asarray(open3d_mesh.triangle_normals) |
||||||
|
|
||||||
|
# Compute centroids for each face of the mesh |
||||||
|
triangle_centroids_array = np.array([ |
||||||
|
np.mean(vertices_array[triangle], axis=0) |
||||||
|
for triangle in open3d_mesh.triangles |
||||||
|
]) |
||||||
|
# Create a point cloud of face centroids |
||||||
|
pcd_triangle_centroid = o3d.geometry.PointCloud() |
||||||
|
pcd_triangle_centroid.points = o3d.utility.Vector3dVector(triangle_centroids_array) |
||||||
|
|
||||||
|
point_curvatures = estimate_point_curvatures(pcd_triangle_centroid, 30) |
||||||
|
np_point_curvatures = np.array(list(point_curvatures.values())) |
||||||
|
point_curvatures_index = np.arange(len(np_point_curvatures))[np_point_curvatures > 0.25] |
||||||
|
|
||||||
|
spread_point_curvatures_index = spread_point(pcd_triangle_centroid, point_curvatures_index, 50) |
||||||
|
|
||||||
|
ApplySmoothEffort(current_obj, spread_point_curvatures_index, 0.5, 30) |
||||||
|
|
||||||
|
adjacent_normal_angle_variance = compute_adjacent_normal_angle_variance(pcd_triangle_centroid, triangle_normals_array, 40) |
||||||
|
adjacent_point_vector_degrees_mean = compute_adjacent_point_vector_degrees_mean(pcd_triangle_centroid, triangle_normals_array, 40) |
||||||
|
|
||||||
|
array_adjacent_point_vector_degrees_mean = np.array(list(adjacent_point_vector_degrees_mean.values())) |
||||||
|
array_adjacent_normal_angle_variance = np.array(list(adjacent_normal_angle_variance.values())) |
||||||
|
|
||||||
|
use_data = np.where(array_adjacent_point_vector_degrees_mean < 90, array_adjacent_normal_angle_variance, 0) |
||||||
|
# Calculate the minimum and maximum values in the angle array, ignoring NaNs. |
||||||
|
min_angle = np.nanmin(use_data) |
||||||
|
max_angle = np.nanmax(use_data) |
||||||
|
# Perform min-max normalization on the angles to scale them between 0 and 1. |
||||||
|
# This normalization helps in comparing values on a common scale. |
||||||
|
normalized_angles = (use_data - min_angle) / (max_angle - min_angle) |
||||||
|
first_select_thread = normalized_angles > 0.2 |
||||||
|
first_select_thread_number = first_select_thread.astype(np.float64) |
||||||
|
thread_normalized_angles_index = np.arange(len(first_select_thread))[first_select_thread] |
||||||
|
|
||||||
|
spread_point_count = spread_point(pcd_triangle_centroid, thread_normalized_angles_index, 3, count=True) |
||||||
|
|
||||||
|
overlapp_trigular_points = np.array(list(spread_point_count.values())) > 3 |
||||||
|
overlapp_trigular_points_index = np.arange(len(overlapp_trigular_points))[overlapp_trigular_points] |
||||||
|
|
||||||
|
ApplySmoothEffort(current_obj, overlapp_trigular_points_index, 0.5, 30) |
||||||
|
|
||||||
|
ApplySmoothEffort(current_obj, factor=0.5, iterations=30) |
||||||
|
|
||||||
|
bpy.ops.wm.obj_export(filepath=output_mesh_path) |
||||||
|
|
||||||
|
def process_meshes(input_path, output_path): |
||||||
|
""" |
||||||
|
Processes each mesh file in the input directory and saves the cleaned meshes in the output directory. |
||||||
|
|
||||||
|
Args: |
||||||
|
input_path (str): Directory containing the input meshes or a single mesh file. |
||||||
|
output_path (str): Directory where the cleaned meshes will be saved. |
||||||
|
""" |
||||||
|
if os.path.isdir(input_path): |
||||||
|
for filename in sorted(os.listdir(input_path)): |
||||||
|
full_input_path = os.path.join(input_path, filename) |
||||||
|
full_output_path = os.path.join(output_path, filename) |
||||||
|
process(full_input_path, full_output_path) |
||||||
|
else: |
||||||
|
process(input_path, output_path) |
||||||
|
|
||||||
|
if __name__ == "__main__": |
||||||
|
parser = argparse.ArgumentParser(description="Processes mesh files.") |
||||||
|
parser.add_argument("-ip", "--input_path", type=str, required=True, help="Input path for the mesh file or directory.") |
||||||
|
parser.add_argument("-op", "--output_path", type=str, required=True, help="Output path for the cleaned mesh file or directory.") |
||||||
|
args = parser.parse_args() |
||||||
|
process_meshes(args.input_path, args.output_path) |
||||||
@ -0,0 +1,5 @@ |
|||||||
|
open3d |
||||||
|
numpy |
||||||
|
sklearn |
||||||
|
argparse |
||||||
|
bpy |
||||||
@ -0,0 +1,78 @@ |
|||||||
|
|
||||||
|
import os,sys,time,shlex,subprocess,shutil,requests,json |
||||||
|
import platform |
||||||
|
if platform.system() == 'Windows': |
||||||
|
sys.path.append('e:\\libs\\') |
||||||
|
#sys.path.append('libs') |
||||||
|
else: |
||||||
|
sys.path.append('/data/deploy/make3d/make2/libs/') |
||||||
|
import libs,config |
||||||
|
def main(pid = 0): |
||||||
|
print(f'开始时间-{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}') |
||||||
|
if pid == 0: |
||||||
|
#获取要处理PID的url |
||||||
|
url = "https://repair.api.suwa3d.com/api/modelRepairOrder/getRepairOrderListByPriority" |
||||||
|
#发起请求 |
||||||
|
res = requests.get(url) |
||||||
|
print('res:', res.text) |
||||||
|
if res.status_code != 200: |
||||||
|
print('获取失败,程序退出') |
||||||
|
return |
||||||
|
res = json.loads(res.text) |
||||||
|
pid = 0 |
||||||
|
try: |
||||||
|
pid = res['data']['pid'] |
||||||
|
except Exception as e: |
||||||
|
return 0 |
||||||
|
|
||||||
|
if pid == 0: |
||||||
|
return 0 |
||||||
|
|
||||||
|
#调用oss下载功能,下载对应的文件 |
||||||
|
pathStr = os.path.join(config.workdir,str(pid)+"_ai") |
||||||
|
libs.down_obj_from_oss_auto(str(pid),"auto",pathStr) |
||||||
|
#检查是否存在产生的对应的文件 |
||||||
|
if not os.path.exists(os.path.join(pathStr,f'{pid}.obj')): |
||||||
|
print(f"找不到{pid}obj文件") |
||||||
|
return |
||||||
|
|
||||||
|
if not os.path.exists(os.path.join(pathStr,f'{pid}.mtl')): |
||||||
|
print(f"找不到{pid}mtl文件") |
||||||
|
return |
||||||
|
#下载完成后调用 |
||||||
|
os.system(f"python optimize_model.py -ip {pathStr}/{pid}.obj -op {pathStr}/{pid}_ai.obj") |
||||||
|
#检查是否存在产生的对应的文件 |
||||||
|
if not os.path.exists(os.path.join(pathStr,f'{pid}_ai.obj')): |
||||||
|
print(f"找不到{pid}ai_obj文件") |
||||||
|
return |
||||||
|
|
||||||
|
if not os.path.exists(os.path.join(pathStr,f'{pid}_ai.mtl')): |
||||||
|
print(f"找不到{pid}ai_mtl文件") |
||||||
|
return |
||||||
|
|
||||||
|
#处理完成完后上传到oss指定目录 |
||||||
|
config.oss_bucket.put_object_from_file(f'objs/auto/{pid}/ai/fix_mesh/{pid}_ai.obj', os.path.join(pathStr,f'{pid}_ai.obj')) |
||||||
|
config.oss_bucket.put_object_from_file(f'objs/auto/{pid}/ai/fix_mesh/{pid}_ai.mtl', os.path.join(pathStr,f'{pid}_ai.mtl')) |
||||||
|
config.oss_bucket.put_object_from_file(f'objs/auto/{pid}/ai/fix_mesh/{pid}.jpg', os.path.join(pathStr,f'{pid}.jpg')) |
||||||
|
#更新处理结果 |
||||||
|
url = "https://repair.api.suwa3d.com/api/modelRepairOrder/updateShootOrderBuildModelType?pid="+str(pid) |
||||||
|
#发起请求 |
||||||
|
requests.get(url) |
||||||
|
#移除文件夹 |
||||||
|
shutil.rmtree(pathStr) |
||||||
|
print(f'结束时间-{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}') |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__': |
||||||
|
|
||||||
|
if len(sys.argv) == 2: |
||||||
|
pid = sys.argv[1] |
||||||
|
main(pid) |
||||||
|
print(f"{pid}-处理结束") |
||||||
|
else: |
||||||
|
while True: |
||||||
|
res = main() |
||||||
|
if res == 0: |
||||||
|
print("休眠60s") |
||||||
|
time.sleep(60) |
||||||
@ -0,0 +1,22 @@ |
|||||||
|
import paramiko |
||||||
|
|
||||||
|
try: |
||||||
|
# 创建SSH对象 |
||||||
|
ssh = paramiko.SSHClient() |
||||||
|
# 允许连接不在known_hosts文件中的主机 |
||||||
|
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) |
||||||
|
print('start connect') |
||||||
|
# 连接服务器 |
||||||
|
ssh.connect('connect.bjc1.seetacloud.com', username='root', password='QoQA8q3Ds2VB', port=33733) |
||||||
|
print('connect success') |
||||||
|
|
||||||
|
# 使用nohup执行命令,并将输出重定向到文件 |
||||||
|
command = 'nohup seg_python /data/code/optimize_model_xj/optimize_model.py -pid 189813 > output.log 2>&1 &' |
||||||
|
stdin, stdout, stderr = ssh.exec_command(command) |
||||||
|
|
||||||
|
# 打印命令是否启动成功 |
||||||
|
print("Command executed") |
||||||
|
finally: |
||||||
|
# 确保连接被关闭 |
||||||
|
if ssh: |
||||||
|
ssh.close() |
||||||
@ -1,3 +1,42 @@ |
|||||||
|
|
||||||
#建模完成,需要减面 smooth 封闭洞 清理模型 贴图 |
#建模完成,需要减面 smooth 封闭洞 清理模型 贴图 |
||||||
%bin% -delegateTo %pid% -simplify 3000000 -smooth -closeHoles -cleanModel -calculateTexture -save "D:\123446\123446.rcproj" -exportSelectedModel "D:\123446\output\123446.obj" "d:\make2\config\ModelExportParams.xml" -quit |
%bin% -delegateTo 161082 -simplify 2000000 -smooth -closeHoles -cleanModel -calculateTexture -save "D:\161082\161082.rcproj" -exportSelectedModel "D:\161082\output\161082.obj" "d:\make2\config\ModelExportParams.xml" |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
%bin% -delegateTo 161082 -defineDistance 36h11:007 36h11:008 0.21 -update -align -align -setReconstructionRegionOnCPs 36h11:001 36h11:002 36h11:003 2.1 -moveReconstructionRegion 0 0 -2.1 -rotateReconstructionRegion 180 0 180 -setGroundPlaneFromReconstructionRegion -scaleReconstructionRegion 1.8 1.6 2.1 absolute center -moveReconstructionRegion 0 0 0.0025 -exportXMP "D:\make2\config\exportXMP.config.xml" |
||||||
|
|
||||||
|
|
||||||
|
%bin% -delegateTo 156600 -defineDistance 36h11:001 36h11:002 1 -update -setReconstructionRegionOnCPs 36h11:001 36h11:002 36h11:004 2.1 -moveReconstructionRegion 0 0 -2.1 -rotateReconstructionRegion 180 0 180 -setGroundPlaneFromReconstructionRegion -scaleReconstructionRegion 1.8 1.6 2.1 absolute center -moveReconstructionRegion 0 0 0.0025 -exportXMP "D:\make2\config\exportXMP.config.xml" |
||||||
|
|
||||||
|
|
||||||
|
%bin% -delegateTo 156600 -defineDistance 36h11:007 36h11:008 0.21 -update -align -align -setReconstructionRegionOnCPs 36h11:001 36h11:002 36h11:004 2.1 -moveReconstructionRegion 0 0 -2.1 -rotateReconstructionRegion 180 0 180 -setGroundPlaneFromReconstructionRegion -scaleReconstructionRegion 1.8 1.6 2.1 absolute center -moveReconstructionRegion 0 0 0.0025 -exportXMP "D:\make2\config\exportXMP.config.xml" -exportReconstructionRegion "D:\156600\156600.rcbox" -selectImage "D:\156600\photo2/*" -enableTexturingAndColoring true -save "D:\156600\156600.rcproj" |
||||||
|
|
||||||
|
%bin% -delegateTo 156600 -setReconstructionRegionOnCPs 36h11:001 36h11:002 36h11:003 2.1 -moveReconstructionRegion 0 0 -2.1 -rotateReconstructionRegion 180 0 180 -setGroundPlaneFromReconstructionRegion -scaleReconstructionRegion 1.8 1.6 2.1 absolute center -moveReconstructionRegion 0 0 0.0025 -exportXMP "D:\make2\config\exportXMP.config.xml" -exportControlPointsMeasurements "D:\156600\156600.controlPoints.csv" "D:\make2\config\exportControlPoints.config.xml" -exportReconstructionRegion "D:\156600\156600.rcbox" -selectImage "D:\156600\photo2\*" -enableTexturingAndColoring true -save "D:\156600\156600.rcproj" |
||||||
|
|
||||||
|
|
||||||
|
-defineDistance 36h11:007 36h11:008 0.21 -update -align -align -setReconstructionRegionOnCPs 36h11:001 36h11:002 36h11:003 2.1 -moveReconstructionRegion 0 0 -2.1 -rotateReconstructionRegion 180 0 180 -setGroundPlaneFromReconstructionRegion -scaleReconstructionRegion 1.8 1.6 2.1 absolute center -moveReconstructionRegion 0 0 0.0025 -exportXMP "D:\make2\config\exportXMP.config.xml" -exportReconstructionRegion "D:\140241\140241.rcbox" -selectImage "D:\140241\photo2/*" -enableTexturingAndColoring true -save "D:\140241\140241.rcproj" |
||||||
|
|
||||||
|
-defineDistance 36h11:007 36h11:008 0.21 -align -align -update -setReconstructionRegionOnCPs 36h11:001 36h11:002 36h11:003 2.1 -moveReconstructionRegion 0 0 -2.1 -rotateReconstructionRegion 180 0 180 -setGroundPlaneFromReconstructionRegion -scaleReconstructionRegion 1.8 1.6 2.1 absolute center -moveReconstructionRegion 0 0 0.0025 -exportXMP "D:\make2\config\exportXMP.config.xml" -exportControlPointsMeasurements "D:\147024\147024.controlPoints.csv" "D:\make2\config\exportControlPoints.config.xml" -exportReconstructionRegion "D:\147024\147024.rcbox" -selectImage "D:\147024\photo2\*" -enableTexturingAndColoring true -save "D:\147024\147024.rcproj" |
||||||
|
|
||||||
|
|
||||||
|
%bin% -delegateTo 155007 -defineDistance 36h11:007 36h11:008 0.21 -update -align -align -setReconstructionRegionOnCPs 36h11:001 36h11:002 36h11:004 2.1 -moveReconstructionRegion 0 0 -2.1 -rotateReconstructionRegion 180 0 180 -setGroundPlaneFromReconstructionRegion -scaleReconstructionRegion 1.8 1.6 2.1 absolute center -moveReconstructionRegion 0 0 0.0025 -exportXMP "D:\make2\config\exportXMP.config.xml" -exportReconstructionRegion "D:\155007\155007.rcbox" -save "D:\155007\155007.rcproj" |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
%bin% -delegateTo 153982 -defineDistance 36h11:007 36h11:008 0.21 -update -align -align -setReconstructionRegionOnCPs 36h11:001 36h11:002 36h11:004 2.1 -moveReconstructionRegion 0 0 -2.1 -rotateReconstructionRegion 180 0 180 -setGroundPlaneFromReconstructionRegion -scaleReconstructionRegion 1.8 1.6 2.1 absolute center -moveReconstructionRegion 0 0 0.0025 -exportXMP "D:\make2\config\exportXMP.config.xml" -exportReconstructionRegion "D:\153982\153982.rcbox" -selectImage "D:\153982\photo2/*" -enableTexturingAndColoring true -save "D:\153982\153982.rcproj" |
||||||
|
|
||||||
|
|
||||||
|
%bin% -delegateTo 155686 -defineDistance 36h11:007 36h11:008 0.21 -align -align -update -setReconstructionRegionOnCPs 36h11:001 36h11:002 36h11:004 2.1 -moveReconstructionRegion 0 0 -2.1 -rotateReconstructionRegion 180 0 180 -setGroundPlaneFromReconstructionRegion -scaleReconstructionRegion 1.8 1.6 2.1 absolute center -moveReconstructionRegion 0 0 0.0025 -exportXMP "D:\make2\config\exportXMP.config.xml" -exportControlPointsMeasurements "D:\155686\155686.controlPoints.csv" "D:\make2\config\exportControlPoints.config.xml" -exportReconstructionRegion "D:\155686\155686.rcbox" -selectImage "D:\155686\photo2\*" -enableTexturingAndColoring true -save "D:\155686\155686.rcproj" |
||||||
|
|
||||||
|
%bin% -delegateTo 155686 -defineDistance 36h11:007 36h11:008 0.21 -defineDistance 36h11:002 36h11:004 1 -defineDistance 36h11:004 36h11:003 1 -defineDistance 36h11:003 36h11:001 1 -align -align -update -setReconstructionRegionOnCPs 36h11:001 36h11:002 36h11:003 2.1 -moveReconstructionRegion 0 0 -2.1 -rotateReconstructionRegion 180 0 180 -setGroundPlaneFromReconstructionRegion -scaleReconstructionRegion 1.8 1.6 2.1 absolute center -moveReconstructionRegion 0 0 0.0025 -exportXMP "D:\make2\config\exportXMP.config.xml" -exportControlPointsMeasurements "D:\155686\155686.controlPoints.csv" "D:\make2\config\exportControlPoints.config.xml" -exportReconstructionRegion "D:\155686\155686.rcbox" -selectImage "D:\155686\photo2\*" -enableTexturingAndColoring true -save "D:\155686\155686.rcproj" |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
%bin% -delegateTo 158508 -defineDistance 36h11:007 36h11:008 0.21 -align -align -update -setReconstructionRegionOnCPs 36h11:001 36h11:002 36h11:004 2.1 -moveReconstructionRegion 0 0 -2.1 -rotateReconstructionRegion 180 0 180 -setGroundPlaneFromReconstructionRegion -scaleReconstructionRegion 1.8 1.6 2.1 absolute center -moveReconstructionRegion 0 0 0.0025 -exportXMP "D:\make2\config\exportXMP.config.xml" -exportControlPointsMeasurements "D:\158508\158508.controlPoints.csv" "D:\make2\config\exportControlPoints.config.xml" -exportReconstructionRegion "D:\158508\158508.rcbox" -selectImage "D:\158508\photo2\*" -enableTexturingAndColoring true -save "D:\158508\158508.rcproj" |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
%bin% -delegateTo 161086 -defineDistance 36h11:007 36h11:008 0.21 -align -align -update -setReconstructionRegionOnCPs 36h11:001 36h11:002 36h11:004 2.1 -moveReconstructionRegion 0 0 -2.1 -rotateReconstructionRegion 180 0 180 -setGroundPlaneFromReconstructionRegion -scaleReconstructionRegion 1.8 1.6 2.1 absolute center -moveReconstructionRegion 0 0 0.0025 -exportXMP "D:\make2\config\exportXMP.config.xml" -exportControlPointsMeasurements "D:\161086\161086.controlPoints.csv" "D:\make2\config\exportControlPoints.config.xml" -exportReconstructionRegion "D:\161086\161086.rcbox" -selectImage "D:\161086\photo2\*" -enableTexturingAndColoring true -save "D:\161086\161086.rcproj" |
||||||
Loading…
Reference in new issue