新的信息

This commit is contained in:
dongchangxi committed 2024-09-02 16:52:37 +08:00
1 parent c66fc76e10
commit 345790cb05
51 files changed
+5187 -61

No files matched your search

View File
Whitespace-only changes.
+125
View File
@@ -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)
+26
View File
@@ -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>
View File
Whitespace-only changes.
+206
View File
@@ -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")
+90
View File
@@ -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
View File
Whitespace-only changes.
@@ -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)
+340
View File
@@ -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)
+267
View File
@@ -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)
+185
View File
@@ -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)
+27
View File
@@ -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
+28
View File
@@ -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
+393
View File
@@ -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
+307
View File
@@ -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
+28
View File
@@ -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>
Whitespace-only changes.