Delete multicamera_sync

This commit is contained in:
jj
2025-02-10 15:45:18 +08:00
parent 14e9a89d0e
commit ff40e1d2c5
9 changed files with 0 additions and 2211 deletions
@@ -1,42 +0,0 @@
{
"deviceVid": "0x2BC5",
"devicePid": "0x0800",
"primarySerialNumber": "CP1S34D0004J",
"devices": [{
"index": 0,
"isPrimaryDevice": true,
"vid": "0x2BC5",
"pid": "0x0800",
"name": "Orbbec Gemini 335",
"firmwareVersion": "1.3.64",
"serialNumber": "CP1S34D0004J",
"hardwareVersion": "0.1",
"ipAddress": "0.0.0.0",
"extensionInfo": {
"ExtensionInfo": {
"IspFwVer": "20240820",
"IspNeedVer": "20240820",
"HwType": "R1",
"HwVer": "V1.1"
}
}
}, {
"index": 1,
"isPrimaryDevice": false,
"vid": "0x2BC5",
"pid": "0x0800",
"name": "Orbbec Gemini 335",
"firmwareVersion": "1.3.64",
"serialNumber": "CP1S34D00038",
"hardwareVersion": "0.1",
"ipAddress": "0.0.0.0",
"extensionInfo": {
"ExtensionInfo": {
"IspFwVer": "20240820",
"IspNeedVer": "20240820",
"HwType": "R1",
"HwVer": "V1.0"
}
}
}]
}
@@ -1,5 +0,0 @@
[Parameter]
# 单位:FPS,请依据数据集实际帧率填写,否则会导致匹配不准确
frameRate=60
# 单位:ms,当匹配后某组数据帧的时间戳极差大于等于tspRangeThreshold,文件名会增加标注
tspRangeThreshold=4
@@ -1,97 +0,0 @@
import os
import subprocess
import json
import platform
def list_subdirectories(path):
# 遍历指定目录
for f in os.listdir(path):
# 判断是否是子目录
if os.path.isdir(os.path.join(path, f)):
yield f
def read_pid_from_device_json(frames_dir):
file_path = frames_dir + "/DevicesInfo.txt"
if not os.path.exists(file_path):
print(file_path + " not exists. Please check it")
return ""
with open(file_path, 'r') as f:
data = json.load(f)
if not 'devicePid' in data:
print("Not found 'devicePid' in " + file_path)
return ""
return data['devicePid']
def execute_sync_width_pid(frames_dir, pid):
sync_script_file=""
if pid.lower() == "0x0675":
sync_script_file="script/config_frameMatch_Gemini2VL.py"
elif pid.lower() == "0x0670" or pid.lower() == "0x0701":
sync_script_file="script/config_frameMatch-systemTimestamp.py"
elif pid.lower() == "0x0660":
sync_script_file="script/config_frameMatch-Astra2_new.py"
elif pid.lower() == "0x0800" or pid.lower() == "0x0804" or pid.lower() == "0x0803" or pid.lower() == "0x0807" or pid.lower() == "0x0801" or pid.lower() == "0x0805" or pid.lower() == "0x080b" or pid.lower() == "0x080e" or pid.lower() == "0x080f" or pid.lower() == "0x0A13":
sync_script_file="script/config_frameMatch_g330.py"
else:
sync_script_file="script/config_frameMatch.py"
if len(sync_script_file) > 0:
print(f"execute synchronize frames. script_file={sync_script_file}, frames_dir={frames_dir}")
if platform.system() == "Windows":
output = subprocess.check_output(["python", sync_script_file, os.path.abspath(f"{frames_dir}"), os.getcwd()])
print(output.decode("gbk"))
else:
output = subprocess.check_output(["python3", sync_script_file, os.path.abspath(f"{frames_dir}"), os.getcwd()])
print(output.decode("utf-8"))
else:
print("Invalid pid=" + pid + ", not match sync frame script")
def sync_frames(frames_dir):
pid = read_pid_from_device_json(frames_dir)
if len(pid) <= 0:
print("Get pid failed.")
return
execute_sync_width_pid(frames_dir, pid)
def main():
# 指定目录路径
frames_output_path = os.path.abspath("../output")
# 获取所有子目录
subdirectories = list(list_subdirectories(frames_output_path))
if not subdirectories:
print("No subdirectories found in the specified directory.")
# 打印子目录列表并让用户选择
for i, subdir in enumerate(subdirectories):
print(f"{i + 1}. {subdir}")
# 获取用户输入
choice = input("Please select a subdirectory by number (or 'q' to quit): ")
if choice.lower() == 'q':
return
# 验证用户输入
is_index_valid = False
try:
index = int(choice) - 1
if 0 <= index < len(subdirectories):
is_index_valid = True
else:
print(f"Invalid choice. index={index}. Please enter a number between 1 and the total number of subdirectories.")
except ValueError:
print("Invalid choice(ValueException). Please enter a number between 1 and the total number of subdirectories")
if is_index_valid:
selected_subdir = subdirectories[index]
print(f"You selected the subdirectory: {selected_subdir}")
sync_frames(f"{frames_output_path }/{selected_subdir}")
if __name__ == "__main__":
main()
@@ -1,385 +0,0 @@
import os.path
import argparse
import sys
import json
import shutil
import configparser
from pathlib import Path
from datetime import datetime
## Config.ini中配置
# 单位:FPS,请依据数据集实际帧率填写,否则会导致匹配不准确
frameRate = -1
# 单位:ms,当匹配后某组数据帧的时间戳极差大于等于tspRangeThreshold,文件名会增加标注
tspRangeThreshold = -1
## Python脚本自动解析, 不要修改
primaryId = '-1' #主机ID
mainPythonWorkPath = "" # SyncFramesMain.py的工作目录
sourceFramesPath = "" # 请勿修改,固定值,TotalMode目录路径
sourceRootPath = "" # 存放TotalMode的根目录
resultPath = "" # 保存sync分析结果
streamProfileDict = dict() # 保存Python结果
class PictureInfo(object):
class Struct(object):
def __init__(self, deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt):
self.deviceId = deviceId
self.sensorType = sensorType
self.syncTimeStamp = syncTimeStamp
self.picturePath = picturePath
self.deviceIdFull = deviceIdFull
self.fileExt = fileExt
def make_struct(self, deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt):
return self.Struct(deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt)
class StreamProfileInfo:
def __init__(self, sensorType, width, height, format, fps):
self.sensorType = sensorType
self.width = width
self.height = height
self.format = format
self.fps = fps
def initPrimaryId():
global primaryId
deviceInfoPath = f"{sourceRootPath}/DevicesInfo.txt"
if not os.path.exists(deviceInfoPath):
print(f"Initialize primaryId failed. {deviceInfoPath} not exists")
return False
with open(deviceInfoPath, 'r') as f:
data = json.load(f)
if not 'devices' in data:
print(f"Initialize primaryId failed. {deviceInfoPath} not contain item 'devices'")
return False
for item in data['devices']:
if 'isPrimaryDevice' in item and 'index' in item and item['isPrimaryDevice']:
primaryId = str(item['index'])
return True
return False
def initSyncConfigParams():
global frameRate, tspRangeThreshold
configPath = f"{mainPythonWorkPath}/Config.ini"
if not os.path.exists(configPath):
print(f"Initliaze synchronized config parameter failed. {configPath} not exists.")
return False
# 创建ConfigParser对象
config = configparser.ConfigParser()
# 读取ini文件
config.read(configPath, 'utf-8')
if not config.has_option('Parameter', 'frameRate'):
print(f"Initliaze synchronized config parameter failed. Not define 'frameRate' in ${configPath}")
return False
if not config.has_option('Parameter', 'tspRangeThreshold'):
print(f"Initliaze synchronized config parameter failed. Not define 'tspRangeThreshold' in ${configPath}")
return False
frameRate = config.getfloat('Parameter', 'frameRate')
if frameRate <= 0 or frameRate >= 1000:
print(f"Initliaze synchronized config parameter failed. Invalid frameRate={frameRate}")
return False
tspRangeThreshold = config.getfloat('Parameter', 'tspRangeThreshold')
if tspRangeThreshold <= 0:
print(f"Initliaze synchronized config parameter failed. Invalid tspRangeThreshold={tspRangeThreshold}")
return False
return True
def getDeviceCount():
deviceInfoPath = f"{sourceRootPath}/DevicesInfo.txt"
if not os.path.exists(deviceInfoPath):
print(f"Get device count failed. {deviceInfoPath} not exists")
return 0
with open(deviceInfoPath, 'r') as f:
data = json.load(f)
if not 'devices' in data:
print(f"Get device count failed. {deviceInfoPath} not contain item 'devices'")
return 0
return len(data['devices'])
def initProfileInfoDict():
global streamProfileDict
streamProfileDict = dict()
profilePath = f"{sourceRootPath}/StreamProfileInfo.txt"
if not os.path.exists(profilePath):
print(f"Initialize profile information dictionary failed. {profilePath} not exists")
return False
with open(profilePath, 'r') as f:
data = json.load(f)
if not 'streamProfiles' in data:
print(f"Initialize profile information dictionary failed. {profilePath} not contain item 'streamProfiles'")
return False
for item in data['streamProfiles']:
if 'sensorType' in item and 'width' in item and 'height' in item and 'format' in item and 'fps' in item:
profileInfo = StreamProfileInfo(item['sensorType'], item['width'], item['height'], item['format'], item['fps'])
streamProfileDict.setdefault(item['sensorType'], profileInfo)
else:
print(f"Initialize profile information dictionary. Error invalid StreamProfile, {item}")
return len(streamProfileDict.items()) > 0
def initResultDir():
global resultPath
timeText = datetime.now().strftime("%Y-%m-%d_%H%M%S")
resultPath = f"{sourceRootPath}/results-{timeText}"
if not os.path.exists(resultPath):
os.makedirs(resultPath)
def isFrameFile(fileName):
fileExt = os.path.splitext(fileName)
if len(fileExt) < 2:
return False
frameExts = {".jpeg", ".jpg", ".png", ".raw", "bmp"}
return fileExt[1] in frameExts
def initPictureInfoDictionary(rootFilePath, pictureInfoDict):
frameFileCount = 0
for dirpath, dirnames, filenames in os.walk(rootFilePath):
# print(f"dirpath={dirpath}, dirpath.basename=" + os.path.basename(dirpath))
for fileName in filenames:
filePath = os.path.join(dirpath, fileName)
if not isFrameFile(fileName):
continue
frameFileCount += 1
fileNameNoExt = os.path.splitext(fileName)[0]
pictureNameList = fileNameNoExt.split('_')
deviceId = pictureNameList[2][5:]
sensorType = pictureNameList[0].replace('#', '_')
syncTimeStamp = int(pictureNameList[3][1:])
# 创建结构体
pictureInfo = PictureInfo()
info = pictureInfo.make_struct(deviceId, sensorType, syncTimeStamp, filePath, os.path.basename(dirpath), os.path.splitext(fileName)[1])
# 格式化字典一个key对应一个数组
pictureInfoDict.setdefault(deviceId, []).append(info)
if 0 == frameFileCount:
print("initialize pictureInfoDict failed. Not found frame file")
def matchFrame(pictureInfoDict):
global primaryId, frameRate
global streamProfileDict
# 获取比较图像数组,取第一个设备的Color数组来进行比较
compareList = []
for key in pictureInfoDict:
listTmp = list(pictureInfoDict[key])
for info in listTmp:
if info.deviceId == primaryId and info.sensorType == 'color':
compareList.append(info)
sorted_dict = dict(sorted(pictureInfoDict.items(), key=lambda x: x[1], reverse=False))
pictureInfoDict = sorted_dict
# 根据开流情况动态分析,减少循环次数
hasColorProfile = 'OB_SENSOR_COLOR' in streamProfileDict
hasDepthProfile = 'OB_SENSOR_DEPTH' in streamProfileDict
hasIRProfile = 'OB_SENSOR_IR' in streamProfileDict
# 匹配相邻帧
resultDict = {}
consumedList = []
dictIndex = 0
frameTspGap = int(1000.0/frameRate+0.5)
for comparePic in compareList:
resultDict.setdefault(dictIndex, []).append(comparePic)
for key in pictureInfoDict:
listTmp = list(pictureInfoDict[key])
# 对比彩色
if hasColorProfile:
for info in listTmp:
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
continue
if info in consumedList:
continue
if info.sensorType == 'color' and info.syncTimeStamp >= comparePic.syncTimeStamp and info.syncTimeStamp - comparePic.syncTimeStamp <= frameTspGap:
resultDict.setdefault(dictIndex, []).append(info)
consumedList.append(info)
break
# 对Depth
if hasDepthProfile:
for info in listTmp:
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
continue
if info in consumedList:
continue
if info.sensorType == 'depth' and info.syncTimeStamp >= comparePic.syncTimeStamp and info.syncTimeStamp - comparePic.syncTimeStamp <= frameTspGap:
resultDict.setdefault(dictIndex, []).append(info)
consumedList.append(info)
break
# IR
if hasIRProfile:
for info in listTmp:
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
continue
if info in consumedList:
continue
if info.sensorType == 'ir' and info.syncTimeStamp >= comparePic.syncTimeStamp and info.syncTimeStamp - comparePic.syncTimeStamp <= frameTspGap:
resultDict.setdefault(dictIndex, []).append(info)
consumedList.append(info)
break
# 计算偏差
for info in resultDict[dictIndex]:
info.tspDiff = info.syncTimeStamp - comparePic.syncTimeStamp
dictIndex += 1
return resultDict
def safe_make_dir(path):
if not os.path.exists(path):
os.makedirs(path)
def handleSyncFrames():
global resultPath
global sourceFramesPath
global streamProfileDict
fp = open(f"{resultPath}/frameMatchLog.txt", "w")
if not initProfileInfoDict():
print("Initialize stream profile dictionary failed. exit")
return
print(f"Stream profiles: {streamProfileDict}")
streamProfileCount = len(streamProfileDict.items())
pictureInfoDict = {}
initPictureInfoDictionary(Path(sourceFramesPath), pictureInfoDict)
if len(pictureInfoDict) <= 0:
print("init pictureInfoDict failed. pictureInfoDict.len = 0")
return
# # Dump pictureInfoDict
# for key in pictureInfoDict:
# print("===================key:%s" % key)
# listTmp = list(pictureInfoDict[key])
# for info in listTmp:
# print("=====================value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s" % (info.deviceId,info.sensorType,info.syncTimeStamp,info.picturePath))
deviceCount = getDeviceCount()
print("=================device count:%d" % deviceCount)
resultDict = {}
resultDict = matchFrame(pictureInfoDict)
for key in resultDict:
fp.write("===================result key:%s\n" % key)
print("===================result key:%s" % key)
listTmp = list(resultDict[key])
for info in listTmp:
fp.write("=====================result value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s\n" % (
info.deviceId, info.sensorType, info.syncTimeStamp, info.picturePath))
print("=====================result value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s" % (
info.deviceId, info.sensorType, info.syncTimeStamp, info.picturePath))
matchPath = f"{resultPath}/matchFrames/"
safe_make_dir(matchPath)
notMatchPath = f"{resultPath}/notMatchFrames/"
abnormalPath = f"{resultPath}/abnormal/"
for key in resultDict:
listTmp = list(resultDict[key])
if (len(listTmp) == (deviceCount * streamProfileCount)):
haveAbnormalData = False
for info in listTmp:
if info.tspDiff >= tspRangeThreshold:
path = matchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + "_xxxxxx" + info.fileExt
shutil.copy(info.picturePath, path)
haveAbnormalData = True
else:
path = matchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + info.fileExt
shutil.copy(info.picturePath, path)
if haveAbnormalData:
safe_make_dir(abnormalPath)
for info in listTmp:
if info.tspDiff >= tspRangeThreshold:
path = abnormalPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + "_xxxxxx" + info.fileExt
shutil.copy(info.picturePath, path)
else:
path = abnormalPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + info.fileExt
shutil.copy(info.picturePath, path)
else:
safe_make_dir(notMatchPath)
for info in listTmp:
newFilePath = notMatchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + info.fileExt
shutil.copy(info.picturePath, newFilePath)
def main():
if not initPrimaryId():
print("Initialize primaryId failed. exit.")
return
if not initSyncConfigParams():
print("Initialized Sync config parameter failed. exit.")
return
initResultDir()
print(f"PrimaryId={primaryId}, frameRate={frameRate}, tspRangeThreshold={tspRangeThreshold}")
handleSyncFrames()
return
if __name__ == '__main__':
parser = argparse.ArgumentParser(description="Synchronize frames support for 'Orbbec Astra2'")
parser.add_argument('frames_dir', type=str, help="Frames directory")
parser.add_argument('main_script_root_dir', type=str, help="SyncFramesMain.py working directory")
args = parser.parse_args()
sourceRootPath = args.frames_dir
sourceFramesPath = f"{args.frames_dir}/TotalModeFrames"
mainPythonWorkPath = args.main_script_root_dir
print(f"Start of Astra2 synchronize frame. sourceRootPath={sourceRootPath}")
main()
print("Finish of Astra2 synchronize frame.")
@@ -1,408 +0,0 @@
import os.path
import argparse
import sys
import json
import shutil
import configparser
from pathlib import Path
from datetime import datetime
## Config.ini中配置
# 单位:FPS,请依据数据集实际帧率填写,否则会导致匹配不准确
frameRate = -1
# 单位:ms,当匹配后某组数据帧的时间戳极差大于等于tspRangeThreshold,文件名会增加标注
tspRangeThreshold = -1
## Python脚本自动解析, 不要修改
primaryId = '-1' #主机ID
mainPythonWorkPath = "" # SyncFramesMain.py的工作目录
sourceFramesPath = "" # 请勿修改,固定值,TotalMode目录路径
sourceRootPath = "" # 存放TotalMode的根目录
resultPath = "" # 保存sync分析结果
streamProfileDict = dict() # 保存Python结果
class PictureInfo(object):
class Struct(object):
def __init__(self, deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt):
self.deviceId = deviceId
self.sensorType = sensorType
self.syncTimeStamp = syncTimeStamp
self.picturePath = picturePath
self.deviceIdFull = deviceIdFull
self.fileExt = fileExt
def make_struct(self, deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt):
return self.Struct(deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt)
class StreamProfileInfo:
def __init__(self, sensorType, width, height, format, fps):
self.sensorType = sensorType
self.width = width
self.height = height
self.format = format
self.fps = fps
def initPrimaryId():
global primaryId
deviceInfoPath = f"{sourceRootPath}/DevicesInfo.txt"
if not os.path.exists(deviceInfoPath):
print(f"Initialize primaryId failed. {deviceInfoPath} not exists")
return False
with open(deviceInfoPath, 'r') as f:
data = json.load(f)
if not 'devices' in data:
print(f"Initialize primaryId failed. {deviceInfoPath} not contain item 'devices'")
return False
for item in data['devices']:
if 'isPrimaryDevice' in item and 'index' in item and item['isPrimaryDevice']:
primaryId = str(item['index'])
return True
return False
def initSyncConfigParams():
global frameRate, tspRangeThreshold
configPath = f"{mainPythonWorkPath}/Config.ini"
if not os.path.exists(configPath):
print(f"Initliaze synchronized config parameter failed. {configPath} not exists.")
return False
# 创建ConfigParser对象
config = configparser.ConfigParser()
# 读取ini文件
config.read(configPath, 'utf-8')
if not config.has_option('Parameter', 'frameRate'):
print(f"Initliaze synchronized config parameter failed. Not define 'frameRate' in ${configPath}")
return False
if not config.has_option('Parameter', 'tspRangeThreshold'):
print(f"Initliaze synchronized config parameter failed. Not define 'tspRangeThreshold' in ${configPath}")
return False
frameRate = config.getfloat('Parameter', 'frameRate')
if frameRate <= 0 or frameRate >= 1000:
print(f"Initliaze synchronized config parameter failed. Invalid frameRate={frameRate}")
return False
tspRangeThreshold = config.getfloat('Parameter', 'tspRangeThreshold')
if tspRangeThreshold <= 0:
print(f"Initliaze synchronized config parameter failed. Invalid tspRangeThreshold={tspRangeThreshold}")
return False
return True
def getDeviceCount():
deviceInfoPath = f"{sourceRootPath}/DevicesInfo.txt"
if not os.path.exists(deviceInfoPath):
print(f"Get device count failed. {deviceInfoPath} not exists")
return 0
with open(deviceInfoPath, 'r') as f:
data = json.load(f)
if not 'devices' in data:
print(f"Get device count failed. {deviceInfoPath} not contain item 'devices'")
return 0
return len(data['devices'])
def initProfileInfoDict():
global streamProfileDict
streamProfileDict = dict()
profilePath = f"{sourceRootPath}/StreamProfileInfo.txt"
if not os.path.exists(profilePath):
print(f"Initialize profile information dictionary failed. {profilePath} not exists")
return False
with open(profilePath, 'r') as f:
data = json.load(f)
if not 'streamProfiles' in data:
print(f"Initialize profile information dictionary failed. {profilePath} not contain item 'streamProfiles'")
return False
for item in data['streamProfiles']:
if 'sensorType' in item and 'width' in item and 'height' in item and 'format' in item and 'fps' in item:
profileInfo = StreamProfileInfo(item['sensorType'], item['width'], item['height'], item['format'], item['fps'])
streamProfileDict.setdefault(item['sensorType'], profileInfo)
else:
print(f"Initialize profile information dictionary. Error invalid StreamProfile, {item}")
return len(streamProfileDict.items()) > 0
def initResultDir():
global resultPath
timeText = datetime.now().strftime("%Y-%m-%d_%H%M%S")
resultPath = f"{sourceRootPath}/results-{timeText}"
if not os.path.exists(resultPath):
os.makedirs(resultPath)
def isFrameFile(fileName):
fileExt = os.path.splitext(fileName)
if len(fileExt) < 2:
return False
frameExts = {".jpeg", ".jpg", ".png", ".raw", "bmp"}
return fileExt[1] in frameExts
def initPictureInfoDictionary(rootFilePath, pictureInfoDict):
frameFileCount = 0
for dirpath, dirnames, filenames in os.walk(rootFilePath):
# print(f"dirpath={dirpath}, dirpath.basename=" + os.path.basename(dirpath))
for fileName in filenames:
filePath = os.path.join(dirpath, fileName)
if not isFrameFile(fileName):
continue
frameFileCount += 1
fileNameNoExt = os.path.splitext(fileName)[0]
pictureNameList = fileNameNoExt.split('_')
deviceId = pictureNameList[2][5:]
sensorType = pictureNameList[0].replace('#', '_')
syncTimeStamp = int(pictureNameList[5][1:])
# 创建结构体
pictureInfo = PictureInfo()
info = pictureInfo.make_struct(deviceId, sensorType, syncTimeStamp, filePath, os.path.basename(dirpath), os.path.splitext(fileName)[1])
# 格式化字典一个key对应一个数组
pictureInfoDict.setdefault(deviceId, []).append(info)
if 0 == frameFileCount:
print("initialize pictureInfoDict failed. Not found frame file")
def matchFrame(pictureInfoDict):
global primaryId, frameRate
global streamProfileDict
# 获取比较图像数组,取第一个设备的Color数组来进行比较
compareList = []
for key in pictureInfoDict:
listTmp = list(pictureInfoDict[key])
for info in listTmp:
if info.deviceId == primaryId and info.sensorType == 'color':
compareList.append(info)
# 根据开流情况动态分析,减少循环次数
hasColorProfile = 'OB_SENSOR_COLOR' in streamProfileDict
hasDepthProfile = 'OB_SENSOR_DEPTH' in streamProfileDict
hasIRProfile = 'OB_SENSOR_IR' in streamProfileDict
hasIRLeftProfile = 'OB_SENSOR_IR_LEFT' in streamProfileDict
hasIRRightProfile = 'OB_SENSOR_IR_RIGHT' in streamProfileDict
# 匹配相邻帧
resultDict = {}
consumedList = []
dictIndex = 0
frameTspHalfGap = int(1000.0/frameRate/2.0+0.5)
for comparePic in compareList:
resultDict.setdefault(dictIndex, []).append(comparePic)
for key in pictureInfoDict:
listTmp = list(pictureInfoDict[key])
# 对比彩色
if hasColorProfile:
for info in listTmp:
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
continue
if info in consumedList:
continue
if info.sensorType == 'color' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
resultDict.setdefault(dictIndex, []).append(info)
consumedList.append(info)
break
# 对Depth
if hasDepthProfile:
for info in listTmp:
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
continue
if info in consumedList:
continue
if info.sensorType == 'depth' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
resultDict.setdefault(dictIndex, []).append(info)
consumedList.append(info)
break
# IR
if hasIRProfile:
for info in listTmp:
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
continue
if info in consumedList:
continue
if info.sensorType == 'ir' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
resultDict.setdefault(dictIndex, []).append(info)
consumedList.append(info)
break
# 左IR
if hasIRLeftProfile:
for info in listTmp:
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
continue
if info in consumedList:
continue
if info.sensorType == 'ir_left' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
resultDict.setdefault(dictIndex, []).append(info)
consumedList.append(info)
break
# 右IR
if hasIRRightProfile:
for info in listTmp:
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
continue
if info in consumedList:
continue
if info.sensorType == 'ir_right' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
resultDict.setdefault(dictIndex, []).append(info)
consumedList.append(info)
break
# 计算偏差
minTsp = min(resultDict[dictIndex], key=lambda x: x.syncTimeStamp)
for info in resultDict[dictIndex]:
info.tspDiff = info.syncTimeStamp - minTsp.syncTimeStamp
dictIndex += 1
return resultDict
def safe_make_dir(path):
if not os.path.exists(path):
os.makedirs(path)
def handleSyncFrames():
global resultPath
global sourceFramesPath
global streamProfileDict
fp = open(f"{resultPath}/frameMatchLog.txt", "w")
if not initProfileInfoDict():
print("Initialize stream profile dictionary failed. exit")
return
print(f"Stream profiles: {streamProfileDict}")
streamProfileCount = len(streamProfileDict.items())
pictureInfoDict = {}
initPictureInfoDictionary(Path(sourceFramesPath), pictureInfoDict)
if len(pictureInfoDict) <= 0:
print("init pictureInfoDict failed. pictureInfoDict.len = 0")
return
# # Dump pictureInfoDict
# for key in pictureInfoDict:
# print("===================key:%s" % key)
# listTmp = list(pictureInfoDict[key])
# for info in listTmp:
# print("=====================value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s" % (info.deviceId,info.sensorType,info.syncTimeStamp,info.picturePath))
deviceCount = getDeviceCount()
print("=================device count:%d" % deviceCount)
resultDict = {}
resultDict = matchFrame(pictureInfoDict)
for key in resultDict:
fp.write("===================result key:%s\n" % key)
print("===================result key:%s" % key)
listTmp = list(resultDict[key])
for info in listTmp:
fp.write("=====================result value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s\n" % (
info.deviceId, info.sensorType, info.syncTimeStamp, info.picturePath))
print("=====================result value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s" % (
info.deviceId, info.sensorType, info.syncTimeStamp, info.picturePath))
matchPath = f"{resultPath}/matchFrames/"
safe_make_dir(matchPath)
notMatchPath = f"{resultPath}/notMatchFrames/"
abnormalPath = f"{resultPath}/abnormal/"
for key in resultDict:
listTmp = list(resultDict[key])
if (len(listTmp) == (deviceCount * streamProfileCount)):
haveAbnormalData = False
for info in listTmp:
if info.tspDiff >= tspRangeThreshold:
path = matchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + "_xxxxxx" + info.fileExt
shutil.copy(info.picturePath, path)
haveAbnormalData = True
else:
path = matchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + info.fileExt
shutil.copy(info.picturePath, path)
if haveAbnormalData:
safe_make_dir(abnormalPath)
for info in listTmp:
if info.tspDiff >= tspRangeThreshold:
path = abnormalPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + "_xxxxxx" + info.fileExt
shutil.copy(info.picturePath, path)
else:
path = abnormalPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + info.fileExt
shutil.copy(info.picturePath, path)
else:
safe_make_dir(notMatchPath)
for info in listTmp:
newFilePath = notMatchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + info.fileExt
shutil.copy(info.picturePath, newFilePath)
def main():
if not initPrimaryId():
print("Initialize primaryId failed. exit.")
return
if not initSyncConfigParams():
print("Initialized Sync config parameter failed. exit.")
return
initResultDir()
print(f"PrimaryId={primaryId}, frameRate={frameRate}, tspRangeThreshold={tspRangeThreshold}")
handleSyncFrames()
return
if __name__ == '__main__':
parser = argparse.ArgumentParser(description="Synchronize frames support for 'Orbbec Gemini 2'")
parser.add_argument('frames_dir', type=str, help="Frames directory")
parser.add_argument('main_script_root_dir', type=str, help="SyncFramesMain.py working directory")
args = parser.parse_args()
sourceRootPath = args.frames_dir
sourceFramesPath = f"{args.frames_dir}/TotalModeFrames"
mainPythonWorkPath = args.main_script_root_dir
print(f"Start of Gemini2 synchronize frame. sourceRootPath={sourceRootPath}")
main()
print("Finish of Gemini2 synchronize frame.")
@@ -1,423 +0,0 @@
import os.path
import argparse
import sys
import json
import shutil
import configparser
from pathlib import Path
from datetime import datetime
import os
import re
## Config.ini中配置
# 单位:FPS,请依据数据集实际帧率填写,否则会导致匹配不准确
frameRate = -1
# 单位:ms,当匹配后某组数据帧的时间戳极差大于等于tspRangeThreshold,文件名会增加标注
tspRangeThreshold = -1
## Python脚本自动解析, 不要修改
primaryId = '-1' #主机ID
mainPythonWorkPath = "" # SyncFramesMain.py的工作目录
sourceFramesPath = "" # 请勿修改,固定值,TotalMode目录路径
sourceRootPath = "" # 存放TotalMode的根目录
resultPath = "" # 保存sync分析结果
streamProfileDict = dict() # 保存Python结果
class PictureInfo(object):
class Struct(object):
def __init__(self, deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt):
self.deviceId = deviceId
self.sensorType = sensorType
self.syncTimeStamp = syncTimeStamp
self.picturePath = picturePath
self.deviceIdFull = deviceIdFull
self.fileExt = fileExt
def make_struct(self, deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt):
return self.Struct(deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt)
class StreamProfileInfo:
def __init__(self, sensorType, width, height, format, fps):
self.sensorType = sensorType
self.width = width
self.height = height
self.format = format
self.fps = fps
def initPrimaryId():
global primaryId
deviceInfoPath = f"{sourceRootPath}/DevicesInfo.txt"
if not os.path.exists(deviceInfoPath):
print(f"Initialize primaryId failed. {deviceInfoPath} not exists")
return False
with open(deviceInfoPath, 'r') as f:
data = json.load(f)
if not 'devices' in data:
print(f"Initialize primaryId failed. {deviceInfoPath} not contain item 'devices'")
return False
for item in data['devices']:
if 'isPrimaryDevice' in item and 'index' in item and item['isPrimaryDevice']:
primaryId = str(item['index'])
return True
return False
def initSyncConfigParams():
global frameRate, tspRangeThreshold
configPath = f"{mainPythonWorkPath}/Config.ini"
if not os.path.exists(configPath):
print(f"Initliaze synchronized config parameter failed. {configPath} not exists.")
return False
# 创建ConfigParser对象
config = configparser.ConfigParser()
# 读取ini文件
config.read(configPath, 'utf-8')
if not config.has_option('Parameter', 'frameRate'):
print(f"Initliaze synchronized config parameter failed. Not define 'frameRate' in ${configPath}")
return False
if not config.has_option('Parameter', 'tspRangeThreshold'):
print(f"Initliaze synchronized config parameter failed. Not define 'tspRangeThreshold' in ${configPath}")
return False
frameRate = config.getfloat('Parameter', 'frameRate')
if frameRate <= 0 or frameRate >= 1000:
print(f"Initliaze synchronized config parameter failed. Invalid frameRate={frameRate}")
return False
tspRangeThreshold = config.getfloat('Parameter', 'tspRangeThreshold')
if tspRangeThreshold <= 0:
print(f"Initliaze synchronized config parameter failed. Invalid tspRangeThreshold={tspRangeThreshold}")
return False
return True
def getDeviceCount():
deviceInfoPath = f"{sourceRootPath}/DevicesInfo.txt"
if not os.path.exists(deviceInfoPath):
print(f"Get device count failed. {deviceInfoPath} not exists")
return 0
with open(deviceInfoPath, 'r') as f:
data = json.load(f)
if not 'devices' in data:
print(f"Get device count failed. {deviceInfoPath} not contain item 'devices'")
return 0
return len(data['devices'])
def initProfileInfoDict():
global streamProfileDict
streamProfileDict = dict()
profilePath = f"{sourceRootPath}/StreamProfileInfo.txt"
if not os.path.exists(profilePath):
print(f"Initialize profile information dictionary failed. {profilePath} not exists")
return False
with open(profilePath, 'r') as f:
data = json.load(f)
if not 'streamProfiles' in data:
print(f"Initialize profile information dictionary failed. {profilePath} not contain item 'streamProfiles'")
return False
for item in data['streamProfiles']:
if 'sensorType' in item and 'width' in item and 'height' in item and 'format' in item and 'fps' in item:
profileInfo = StreamProfileInfo(item['sensorType'], item['width'], item['height'], item['format'], item['fps'])
streamProfileDict.setdefault(item['sensorType'], profileInfo)
else:
print(f"Initialize profile information dictionary. Error invalid StreamProfile, {item}")
return len(streamProfileDict.items()) > 0
def initResultDir():
global resultPath
timeText = datetime.now().strftime("%Y-%m-%d_%H%M%S")
resultPath = f"{sourceRootPath}/results-{timeText}"
if not os.path.exists(resultPath):
os.makedirs(resultPath)
def isFrameFile(fileName):
fileExt = os.path.splitext(fileName)
if len(fileExt) < 2:
return False
frameExts = {".jpeg", ".jpg", ".png", ".raw", "bmp"}
return fileExt[1] in frameExts
def extract_number(filename):
"""提取文件名中以'g'开头的数字部分"""
match_g = re.search(r'g(\d+)', filename)
if match_g:
return int(match_g.group(1))
"""提取文件名中以'd'开头的数字部分"""
match_d = re.search(r'd(\d+)', filename)
if match_d:
return int(match_d.group(1))
return float('inf')
def initPictureInfoDictionary(rootFilePath, pictureInfoDict):
frameFileCount = 0
for dirpath, dirnames, filenames in os.walk(rootFilePath):
filenames.sort(key=extract_number) # 排序,按文件名中的'd'和'g'后面的数字从小到大排序
for fileName in filenames:
filePath = os.path.join(dirpath, fileName)
if not isFrameFile(fileName):
continue
frameFileCount += 1
fileNameNoExt = os.path.splitext(fileName)[0]
pictureNameList = fileNameNoExt.split('_')
deviceId = pictureNameList[2][5:]
sensorType = pictureNameList[0].replace('#', '_')
syncTimeStamp = int(pictureNameList[3][1:])
# 创建结构体
pictureInfo = PictureInfo()
info = pictureInfo.make_struct(deviceId, sensorType, syncTimeStamp, filePath, os.path.basename(dirpath), os.path.splitext(fileName)[1])
# 格式化字典一个key对应一个数组
pictureInfoDict.setdefault(deviceId, []).append(info)
if 0 == frameFileCount:
print("initialize pictureInfoDict failed. Not found frame file")
def matchFrame(pictureInfoDict):
global primaryId, frameRate
global streamProfileDict
# 获取比较图像数组,取第一个设备的Color数组来进行比较
compareList = []
for key in pictureInfoDict:
listTmp = list(pictureInfoDict[key])
for info in listTmp:
if info.deviceId == primaryId and info.sensorType == 'color':
compareList.append(info)
# 根据开流情况动态分析,减少循环次数
hasColorProfile = 'OB_SENSOR_COLOR' in streamProfileDict
hasDepthProfile = 'OB_SENSOR_DEPTH' in streamProfileDict
hasIRProfile = 'OB_SENSOR_IR' in streamProfileDict
hasIRLeftProfile = 'OB_SENSOR_IR_LEFT' in streamProfileDict
hasIRRightProfile = 'OB_SENSOR_IR_RIGHT' in streamProfileDict
# 匹配相邻帧
resultDict = {}
consumedList = []
dictIndex = 0
frameTspHalfGap = int(1000.0/frameRate/2.0+0.5)
for comparePic in compareList:
resultDict.setdefault(dictIndex, []).append(comparePic)
for key in pictureInfoDict:
listTmp = list(pictureInfoDict[key])
# 对比彩色
if hasColorProfile:
for info in listTmp:
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
continue
if info in consumedList:
continue
if info.sensorType == 'color' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
resultDict.setdefault(dictIndex, []).append(info)
consumedList.append(info)
break
# 对Depth
if hasDepthProfile:
for info in listTmp:
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
continue
if info in consumedList:
continue
if info.sensorType == 'depth' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
resultDict.setdefault(dictIndex, []).append(info)
consumedList.append(info)
break
# IR
if hasIRProfile:
for info in listTmp:
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
continue
if info in consumedList:
continue
if info.sensorType == 'ir' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
resultDict.setdefault(dictIndex, []).append(info)
consumedList.append(info)
break
# 对左IR
if hasIRLeftProfile:
for info in listTmp:
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
continue
if info in consumedList:
continue
if info.sensorType == 'ir_left' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
resultDict.setdefault(dictIndex, []).append(info)
consumedList.append(info)
break
# 对右IR
if hasIRRightProfile:
for info in listTmp:
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
continue
if info in consumedList:
continue
if info.sensorType == 'ir_right' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
resultDict.setdefault(dictIndex, []).append(info)
consumedList.append(info)
break
# 计算偏差
minTsp = min(resultDict[dictIndex], key=lambda x: x.syncTimeStamp)
for info in resultDict[dictIndex]:
info.tspDiff = info.syncTimeStamp - minTsp.syncTimeStamp
dictIndex += 1
return resultDict
def safe_make_dir(path):
if not os.path.exists(path):
os.makedirs(path)
def handleSyncFrames():
global resultPath
global sourceFramesPath
global streamProfileDict
fp = open(f"{resultPath}/frameMatchLog.txt", "w")
if not initProfileInfoDict():
print("Initialize stream profile dictionary failed. exit")
return
print(f"Stream profiles: {streamProfileDict}")
streamProfileCount = len(streamProfileDict.items())
pictureInfoDict = {}
initPictureInfoDictionary(Path(sourceFramesPath), pictureInfoDict)
if len(pictureInfoDict) <= 0:
print("init pictureInfoDict failed. pictureInfoDict.len = 0")
return
# # Dump pictureInfoDict
# for key in pictureInfoDict:
# print("===================key:%s" % key)
# listTmp = list(pictureInfoDict[key])
# for info in listTmp:
# print("=====================value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s" % (info.deviceId,info.sensorType,info.syncTimeStamp,info.picturePath))
deviceCount = getDeviceCount()
print("=================device count:%d" % deviceCount)
resultDict = {}
resultDict = matchFrame(pictureInfoDict)
for key in resultDict:
fp.write("===================result key:%s\n" % key)
print("===================result key:%s" % key)
listTmp = list(resultDict[key])
for info in listTmp:
fp.write("=====================result value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s\n" % (
info.deviceId, info.sensorType, info.syncTimeStamp, info.picturePath))
print("=====================result value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s" % (
info.deviceId, info.sensorType, info.syncTimeStamp, info.picturePath))
matchPath = f"{resultPath}/matchFrames/"
safe_make_dir(matchPath)
notMatchPath = f"{resultPath}/notMatchFrames/"
abnormalPath = f"{resultPath}/abnormal/"
for key in resultDict:
listTmp = list(resultDict[key])
if (len(listTmp) == (deviceCount * streamProfileCount)):
haveAbnormalData = False
for info in listTmp:
if info.tspDiff >= tspRangeThreshold:
path = matchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + "_xxxxxx" + info.fileExt
shutil.copy(info.picturePath, path)
haveAbnormalData = True
else:
path = matchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + info.fileExt
shutil.copy(info.picturePath, path)
if haveAbnormalData:
safe_make_dir(abnormalPath)
for info in listTmp:
if info.tspDiff >= tspRangeThreshold:
path = abnormalPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + "_xxxxxx" + info.fileExt
shutil.copy(info.picturePath, path)
else:
path = abnormalPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + info.fileExt
shutil.copy(info.picturePath, path)
else:
safe_make_dir(notMatchPath)
for info in listTmp:
newFilePath = notMatchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + info.fileExt
shutil.copy(info.picturePath, newFilePath)
def main():
if not initPrimaryId():
print("Initialize primaryId failed. exit.")
return
if not initSyncConfigParams():
print("Initialized Sync config parameter failed. exit.")
return
initResultDir()
print(f"PrimaryId={primaryId}, frameRate={frameRate}, tspRangeThreshold={tspRangeThreshold}")
handleSyncFrames()
return
if __name__ == '__main__':
parser = argparse.ArgumentParser(description="Synchronize frames support for 'Orbbec Devices'")
parser.add_argument('frames_dir', type=str, help="Frames directory")
parser.add_argument('main_script_root_dir', type=str, help="SyncFramesMain.py working directory")
args = parser.parse_args()
sourceRootPath = args.frames_dir
sourceFramesPath = f"{args.frames_dir}/TotalModeFrames"
mainPythonWorkPath = args.main_script_root_dir
print(f"Start of CommonFrameMatch synchronize frame. sourceRootPath={sourceRootPath}")
main()
print("Finish of CommonFrameMatch synchronize frame.")
@@ -1,408 +0,0 @@
import os.path
import argparse
import sys
import json
import shutil
import configparser
from pathlib import Path
from datetime import datetime
## Config.ini中配置
# 单位:FPS,请依据数据集实际帧率填写,否则会导致匹配不准确
frameRate = -1
# 单位:ms,当匹配后某组数据帧的时间戳极差大于等于tspRangeThreshold,文件名会增加标注
tspRangeThreshold = -1
## Python脚本自动解析, 不要修改
primaryId = '-1' #主机ID
mainPythonWorkPath = "" # SyncFramesMain.py的工作目录
sourceFramesPath = "" # 请勿修改,固定值,TotalMode目录路径
sourceRootPath = "" # 存放TotalMode的根目录
resultPath = "" # 保存sync分析结果
streamProfileDict = dict() # 保存Python结果
class PictureInfo(object):
class Struct(object):
def __init__(self, deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt):
self.deviceId = deviceId
self.sensorType = sensorType
self.syncTimeStamp = syncTimeStamp
self.picturePath = picturePath
self.deviceIdFull = deviceIdFull
self.fileExt = fileExt
def make_struct(self, deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt):
return self.Struct(deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt)
class StreamProfileInfo:
def __init__(self, sensorType, width, height, format, fps):
self.sensorType = sensorType
self.width = width
self.height = height
self.format = format
self.fps = fps
def initPrimaryId():
global primaryId
deviceInfoPath = f"{sourceRootPath}/DevicesInfo.txt"
if not os.path.exists(deviceInfoPath):
print(f"Initialize primaryId failed. {deviceInfoPath} not exists")
return False
with open(deviceInfoPath, 'r') as f:
data = json.load(f)
if not 'devices' in data:
print(f"Initialize primaryId failed. {deviceInfoPath} not contain item 'devices'")
return False
for item in data['devices']:
if 'isPrimaryDevice' in item and 'index' in item and item['isPrimaryDevice']:
primaryId = str(item['index'])
return True
return False
def initSyncConfigParams():
global frameRate, tspRangeThreshold
configPath = f"{mainPythonWorkPath}/Config.ini"
if not os.path.exists(configPath):
print(f"Initliaze synchronized config parameter failed. {configPath} not exists.")
return False
# 创建ConfigParser对象
config = configparser.ConfigParser()
# 读取ini文件
config.read(configPath, 'utf-8')
if not config.has_option('Parameter', 'frameRate'):
print(f"Initliaze synchronized config parameter failed. Not define 'frameRate' in ${configPath}")
return False
if not config.has_option('Parameter', 'tspRangeThreshold'):
print(f"Initliaze synchronized config parameter failed. Not define 'tspRangeThreshold' in ${configPath}")
return False
frameRate = config.getfloat('Parameter', 'frameRate')
if frameRate <= 0 or frameRate >= 1000:
print(f"Initliaze synchronized config parameter failed. Invalid frameRate={frameRate}")
return False
tspRangeThreshold = config.getfloat('Parameter', 'tspRangeThreshold')
if tspRangeThreshold <= 0:
print(f"Initliaze synchronized config parameter failed. Invalid tspRangeThreshold={tspRangeThreshold}")
return False
return True
def getDeviceCount():
deviceInfoPath = f"{sourceRootPath}/DevicesInfo.txt"
if not os.path.exists(deviceInfoPath):
print(f"Get device count failed. {deviceInfoPath} not exists")
return 0
with open(deviceInfoPath, 'r') as f:
data = json.load(f)
if not 'devices' in data:
print(f"Get device count failed. {deviceInfoPath} not contain item 'devices'")
return 0
return len(data['devices'])
def initProfileInfoDict():
global streamProfileDict
streamProfileDict = dict()
profilePath = f"{sourceRootPath}/StreamProfileInfo.txt"
if not os.path.exists(profilePath):
print(f"Initialize profile information dictionary failed. {profilePath} not exists")
return False
with open(profilePath, 'r') as f:
data = json.load(f)
if not 'streamProfiles' in data:
print(f"Initialize profile information dictionary failed. {profilePath} not contain item 'streamProfiles'")
return False
for item in data['streamProfiles']:
if 'sensorType' in item and 'width' in item and 'height' in item and 'format' in item and 'fps' in item:
profileInfo = StreamProfileInfo(item['sensorType'], item['width'], item['height'], item['format'], item['fps'])
streamProfileDict.setdefault(item['sensorType'], profileInfo)
else:
print(f"Initialize profile information dictionary. Error invalid StreamProfile, {item}")
return len(streamProfileDict.items()) > 0
def initResultDir():
global resultPath
timeText = datetime.now().strftime("%Y-%m-%d_%H%M%S")
resultPath = f"{sourceRootPath}/results-{timeText}"
if not os.path.exists(resultPath):
os.makedirs(resultPath)
def isFrameFile(fileName):
fileExt = os.path.splitext(fileName)
if len(fileExt) < 2:
return False
frameExts = {".jpeg", ".jpg", ".png", ".raw", "bmp"}
return fileExt[1] in frameExts
def initPictureInfoDictionary(rootFilePath, pictureInfoDict):
frameFileCount = 0
for dirpath, dirnames, filenames in os.walk(rootFilePath):
# print(f"dirpath={dirpath}, dirpath.basename=" + os.path.basename(dirpath))
for fileName in filenames:
filePath = os.path.join(dirpath, fileName)
if not isFrameFile(fileName):
continue
frameFileCount += 1
fileNameNoExt = os.path.splitext(fileName)[0]
pictureNameList = fileNameNoExt.split('_')
deviceId = pictureNameList[2][5:]
sensorType = pictureNameList[0].replace('#', '_')
syncTimeStamp = int(pictureNameList[3][1:])
# 创建结构体
pictureInfo = PictureInfo()
info = pictureInfo.make_struct(deviceId, sensorType, syncTimeStamp, filePath, os.path.basename(dirpath), os.path.splitext(fileName)[1])
# 格式化字典一个key对应一个数组
pictureInfoDict.setdefault(deviceId, []).append(info)
if 0 == frameFileCount:
print("initialize pictureInfoDict failed. Not found frame file")
def matchFrame(pictureInfoDict):
global primaryId, frameRate
global streamProfileDict
# 获取比较图像数组,取第一个设备的Color数组来进行比较
compareList = []
for key in pictureInfoDict:
listTmp = list(pictureInfoDict[key])
for info in listTmp:
if info.deviceId == primaryId and info.sensorType == 'color':
compareList.append(info)
# 根据开流情况动态分析,减少循环次数
hasColorProfile = 'OB_SENSOR_COLOR' in streamProfileDict
hasDepthProfile = 'OB_SENSOR_DEPTH' in streamProfileDict
hasIRProfile = 'OB_SENSOR_IR' in streamProfileDict
hasIRLeftProfile = 'OB_SENSOR_IR_LEFT' in streamProfileDict
hasIRRightProfile = 'OB_SENSOR_IR_RIGHT' in streamProfileDict
# 匹配相邻帧
resultDict = {}
consumedList = []
dictIndex = 0
frameTspHalfGap = int(1000.0/frameRate/2.0+0.5)
for comparePic in compareList:
resultDict.setdefault(dictIndex, []).append(comparePic)
for key in pictureInfoDict:
listTmp = list(pictureInfoDict[key])
# 对比彩色
if hasColorProfile:
for info in listTmp:
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
continue
if info in consumedList:
continue
if info.sensorType == 'color' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
resultDict.setdefault(dictIndex, []).append(info)
consumedList.append(info)
break
# 对Depth
if hasDepthProfile:
for info in listTmp:
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
continue
if info in consumedList:
continue
if info.sensorType == 'depth' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
resultDict.setdefault(dictIndex, []).append(info)
consumedList.append(info)
break
# IR
if hasIRProfile:
for info in listTmp:
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
continue
if info in consumedList:
continue
if info.sensorType == 'ir' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
resultDict.setdefault(dictIndex, []).append(info)
consumedList.append(info)
break
# 对左IR
if hasIRLeftProfile:
for info in listTmp:
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
continue
if info in consumedList:
continue
if info.sensorType == 'ir_left' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
resultDict.setdefault(dictIndex, []).append(info)
consumedList.append(info)
break
# 对右IR
if hasIRRightProfile:
for info in listTmp:
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
continue
if info in consumedList:
continue
if info.sensorType == 'ir_right' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
resultDict.setdefault(dictIndex, []).append(info)
consumedList.append(info)
break
# 计算偏差
minTsp = min(resultDict[dictIndex], key=lambda x: x.syncTimeStamp)
for info in resultDict[dictIndex]:
info.tspDiff = info.syncTimeStamp - minTsp.syncTimeStamp
dictIndex += 1
return resultDict
def safe_make_dir(path):
if not os.path.exists(path):
os.makedirs(path)
def handleSyncFrames():
global resultPath
global sourceFramesPath
global streamProfileDict
fp = open(f"{resultPath}/frameMatchLog.txt", "w")
if not initProfileInfoDict():
print("Initialize stream profile dictionary failed. exit")
return
print(f"Stream profiles: {streamProfileDict}")
streamProfileCount = len(streamProfileDict.items())
pictureInfoDict = {}
initPictureInfoDictionary(Path(sourceFramesPath), pictureInfoDict)
if len(pictureInfoDict) <= 0:
print("init pictureInfoDict failed. pictureInfoDict.len = 0")
return
# # Dump pictureInfoDict
# for key in pictureInfoDict:
# print("===================key:%s" % key)
# listTmp = list(pictureInfoDict[key])
# for info in listTmp:
# print("=====================value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s" % (info.deviceId,info.sensorType,info.syncTimeStamp,info.picturePath))
deviceCount = getDeviceCount()
print("=================device count:%d" % deviceCount)
resultDict = {}
resultDict = matchFrame(pictureInfoDict)
for key in resultDict:
fp.write("===================result key:%s\n" % key)
print("===================result key:%s" % key)
listTmp = list(resultDict[key])
for info in listTmp:
fp.write("=====================result value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s\n" % (
info.deviceId, info.sensorType, info.syncTimeStamp, info.picturePath))
print("=====================result value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s" % (
info.deviceId, info.sensorType, info.syncTimeStamp, info.picturePath))
matchPath = f"{resultPath}/matchFrames/"
safe_make_dir(matchPath)
notMatchPath = f"{resultPath}/notMatchFrames/"
abnormalPath = f"{resultPath}/abnormal/"
for key in resultDict:
listTmp = list(resultDict[key])
if (len(listTmp) == (deviceCount * streamProfileCount)):
haveAbnormalData = False
for info in listTmp:
if info.tspDiff >= tspRangeThreshold:
path = matchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + "_xxxxxx" + info.fileExt
shutil.copy(info.picturePath, path)
haveAbnormalData = True
else:
path = matchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + info.fileExt
shutil.copy(info.picturePath, path)
if haveAbnormalData:
safe_make_dir(abnormalPath)
for info in listTmp:
if info.tspDiff >= tspRangeThreshold:
path = abnormalPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + "_xxxxxx" + info.fileExt
shutil.copy(info.picturePath, path)
else:
path = abnormalPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + info.fileExt
shutil.copy(info.picturePath, path)
else:
safe_make_dir(notMatchPath)
for info in listTmp:
newFilePath = notMatchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + info.fileExt
shutil.copy(info.picturePath, newFilePath)
def main():
if not initPrimaryId():
print("Initialize primaryId failed. exit.")
return
if not initSyncConfigParams():
print("Initialized Sync config parameter failed. exit.")
return
initResultDir()
print(f"PrimaryId={primaryId}, frameRate={frameRate}, tspRangeThreshold={tspRangeThreshold}")
handleSyncFrames()
return
if __name__ == '__main__':
parser = argparse.ArgumentParser(description="Synchronize frames support for 'Orbbec Gemini 2 VL'")
parser.add_argument('frames_dir', type=str, help="Frames directory")
parser.add_argument('main_script_root_dir', type=str, help="SyncFramesMain.py working directory")
args = parser.parse_args()
sourceRootPath = args.frames_dir
sourceFramesPath = f"{args.frames_dir}/TotalModeFrames"
mainPythonWorkPath = args.main_script_root_dir
print(f"Start of Gemini2VL synchronize frame. sourceRootPath={sourceRootPath}")
main()
print("Finish of Gemini2VL synchronize frame.")
@@ -1,427 +0,0 @@
import os.path
import argparse
import sys
import json
import shutil
import configparser
from pathlib import Path
from datetime import datetime
import os
import re
## Config.ini中配置
# 单位:FPS,请依据数据集实际帧率填写,否则会导致匹配不准确
frameRate = -1
# 单位:ms,当匹配后某组数据帧的时间戳极差大于等于tspRangeThreshold,文件名会增加标注
tspRangeThreshold = -1
## Python脚本自动解析, 不要修改
primaryId = '-1' #主机ID
mainPythonWorkPath = "" # SyncFramesMain.py的工作目录
sourceFramesPath = "" # 请勿修改,固定值,TotalMode目录路径
sourceRootPath = "" # 存放TotalMode的根目录
resultPath = "" # 保存sync分析结果
streamProfileDict = dict() # 保存Python结果
class PictureInfo(object):
class Struct(object):
def __init__(self, deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt, exp, gain):
self.deviceId = deviceId
self.sensorType = sensorType
self.syncTimeStamp = syncTimeStamp
self.picturePath = picturePath
self.deviceIdFull = deviceIdFull
self.fileExt = fileExt
self.exp = exp
self.gain = gain
def make_struct(self, deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt, exp, gain):
return self.Struct(deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt, exp, gain)
class StreamProfileInfo:
def __init__(self, sensorType, width, height, format, fps):
self.sensorType = sensorType
self.width = width
self.height = height
self.format = format
self.fps = fps
def initPrimaryId():
global primaryId
deviceInfoPath = f"{sourceRootPath}/DevicesInfo.txt"
if not os.path.exists(deviceInfoPath):
print(f"Initialize primaryId failed. {deviceInfoPath} not exists")
return False
with open(deviceInfoPath, 'r') as f:
data = json.load(f)
if not 'devices' in data:
print(f"Initialize primaryId failed. {deviceInfoPath} not contain item 'devices'")
return False
for item in data['devices']:
if 'isPrimaryDevice' in item and 'index' in item and item['isPrimaryDevice']:
primaryId = str(item['index'])
return True
return False
def initSyncConfigParams():
global frameRate, tspRangeThreshold
configPath = f"{mainPythonWorkPath}/Config.ini"
if not os.path.exists(configPath):
print(f"Initliaze synchronized config parameter failed. {configPath} not exists.")
return False
# 创建ConfigParser对象
config = configparser.ConfigParser()
# 读取ini文件
config.read(configPath, 'utf-8')
if not config.has_option('Parameter', 'frameRate'):
print(f"Initliaze synchronized config parameter failed. Not define 'frameRate' in ${configPath}")
return False
if not config.has_option('Parameter', 'tspRangeThreshold'):
print(f"Initliaze synchronized config parameter failed. Not define 'tspRangeThreshold' in ${configPath}")
return False
frameRate = config.getfloat('Parameter', 'frameRate')
if frameRate <= 0 or frameRate >= 1000:
print(f"Initliaze synchronized config parameter failed. Invalid frameRate={frameRate}")
return False
tspRangeThreshold = config.getfloat('Parameter', 'tspRangeThreshold')
if tspRangeThreshold <= 0:
print(f"Initliaze synchronized config parameter failed. Invalid tspRangeThreshold={tspRangeThreshold}")
return False
return True
def getDeviceCount():
deviceInfoPath = f"{sourceRootPath}/DevicesInfo.txt"
if not os.path.exists(deviceInfoPath):
print(f"Get device count failed. {deviceInfoPath} not exists")
return 0
with open(deviceInfoPath, 'r') as f:
data = json.load(f)
if not 'devices' in data:
print(f"Get device count failed. {deviceInfoPath} not contain item 'devices'")
return 0
return len(data['devices'])
def initProfileInfoDict():
global streamProfileDict
streamProfileDict = dict()
profilePath = f"{sourceRootPath}/StreamProfileInfo.txt"
if not os.path.exists(profilePath):
print(f"Initialize profile information dictionary failed. {profilePath} not exists")
return False
with open(profilePath, 'r') as f:
data = json.load(f)
if not 'streamProfiles' in data:
print(f"Initialize profile information dictionary failed. {profilePath} not contain item 'streamProfiles'")
return False
for item in data['streamProfiles']:
if 'sensorType' in item and 'width' in item and 'height' in item and 'format' in item and 'fps' in item:
profileInfo = StreamProfileInfo(item['sensorType'], item['width'], item['height'], item['format'], item['fps'])
streamProfileDict.setdefault(item['sensorType'], profileInfo)
else:
print(f"Initialize profile information dictionary. Error invalid StreamProfile, {item}")
return len(streamProfileDict.items()) > 0
def initResultDir():
global resultPath
timeText = datetime.now().strftime("%Y-%m-%d_%H%M%S")
resultPath = f"{sourceRootPath}/results-{timeText}"
if not os.path.exists(resultPath):
os.makedirs(resultPath)
def isFrameFile(fileName):
fileExt = os.path.splitext(fileName)
if len(fileExt) < 2:
return False
frameExts = {".jpeg", ".jpg", ".png", ".raw", "bmp"}
return fileExt[1] in frameExts
def extract_number(filename):
match_d = re.search(r'_d(\d+)', filename)
if match_d:
return int(match_d.group(1))
match_g = re.search(r'_g(\d+)', filename)
if match_g:
return int(match_g.group(1))
return float('inf')
def initPictureInfoDictionary(rootFilePath, pictureInfoDict):
frameFileCount = 0
for dirpath, dirnames, filenames in os.walk(rootFilePath):
filenames.sort(key=extract_number) # 排序,按文件名中的'd'和'g'后面的数字从小到大排序
# print(f"dirpath={dirpath}, dirpath.basename=" + os.path.basename(dirpath))
for fileName in filenames:
filePath = os.path.join(dirpath, fileName)
if not isFrameFile(fileName):
continue
frameFileCount += 1
fileNameNoExt = os.path.splitext(fileName)[0]
pictureNameList = fileNameNoExt.split('_')
deviceId = pictureNameList[2][5:]
sensorType = pictureNameList[0].replace('#', '_')
syncTimeStamp = int(pictureNameList[3][1:])
exp = str(pictureNameList[6][0:])
gain = str(pictureNameList[7][0:])
# 创建结构体
pictureInfo = PictureInfo()
info = pictureInfo.make_struct(deviceId, sensorType, syncTimeStamp, filePath, os.path.basename(dirpath), os.path.splitext(fileName)[1],exp,gain)
# 格式化字典一个key对应一个数组
pictureInfoDict.setdefault(deviceId, []).append(info)
if 0 == frameFileCount:
print("initialize pictureInfoDict failed. Not found frame file")
def matchFrame(pictureInfoDict):
global primaryId, frameRate
global streamProfileDict
# 获取比较图像数组,取第一个设备的Color数组来进行比较
compareList = []
for key in pictureInfoDict:
listTmp = list(pictureInfoDict[key])
for info in listTmp:
if info.deviceId == primaryId and info.sensorType == 'color':
compareList.append(info)
# 根据开流情况动态分析,减少循环次数
hasColorProfile = 'OB_SENSOR_COLOR' in streamProfileDict
hasDepthProfile = 'OB_SENSOR_DEPTH' in streamProfileDict
hasIRProfile = 'OB_SENSOR_IR' in streamProfileDict
hasIRLeftProfile = 'OB_SENSOR_IR_LEFT' in streamProfileDict
hasIRRightProfile = 'OB_SENSOR_IR_RIGHT' in streamProfileDict
# 匹配相邻帧
resultDict = {}
consumedList = []
dictIndex = 0
frameTspHalfGap = int(1000.0/frameRate/2.0+0.5)
for comparePic in compareList:
resultDict.setdefault(dictIndex, []).append(comparePic)
for key in pictureInfoDict:
listTmp = list(pictureInfoDict[key])
# 对比彩色
if hasColorProfile:
for info in listTmp:
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
continue
if info in consumedList:
continue
if info.sensorType == 'color' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
resultDict.setdefault(dictIndex, []).append(info)
consumedList.append(info)
break
# 对Depth
if hasDepthProfile:
for info in listTmp:
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
continue
if info in consumedList:
continue
if info.sensorType == 'depth' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
resultDict.setdefault(dictIndex, []).append(info)
consumedList.append(info)
break
# IR
if hasIRProfile:
for info in listTmp:
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
continue
if info in consumedList:
continue
if info.sensorType == 'ir' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
resultDict.setdefault(dictIndex, []).append(info)
consumedList.append(info)
break
# 对左IR
if hasIRLeftProfile:
for info in listTmp:
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
continue
if info in consumedList:
continue
if info.sensorType == 'ir_left' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
resultDict.setdefault(dictIndex, []).append(info)
consumedList.append(info)
break
# 对右IR
if hasIRRightProfile:
for info in listTmp:
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
continue
if info in consumedList:
continue
if info.sensorType == 'ir_right' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
resultDict.setdefault(dictIndex, []).append(info)
consumedList.append(info)
break
# 计算偏差
minTsp = min(resultDict[dictIndex], key=lambda x: x.syncTimeStamp)
for info in resultDict[dictIndex]:
info.tspDiff = info.syncTimeStamp - minTsp.syncTimeStamp
dictIndex += 1
return resultDict
def safe_make_dir(path):
if not os.path.exists(path):
os.makedirs(path)
def handleSyncFrames():
global resultPath
global sourceFramesPath
global streamProfileDict
fp = open(f"{resultPath}/frameMatchLog.txt", "w")
if not initProfileInfoDict():
print("Initialize stream profile dictionary failed. exit")
return
print(f"Stream profiles: {streamProfileDict}")
streamProfileCount = len(streamProfileDict.items())
pictureInfoDict = {}
initPictureInfoDictionary(Path(sourceFramesPath), pictureInfoDict)
if len(pictureInfoDict) <= 0:
print("init pictureInfoDict failed. pictureInfoDict.len = 0")
return
# # Dump pictureInfoDict
# for key in pictureInfoDict:
# print("===================key:%s" % key)
# listTmp = list(pictureInfoDict[key])
# for info in listTmp:
# print("=====================value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s" % (info.deviceId,info.sensorType,info.syncTimeStamp,info.picturePath))
deviceCount = getDeviceCount()
print("=================device count:%d" % deviceCount)
resultDict = {}
resultDict = matchFrame(pictureInfoDict)
for key in resultDict:
fp.write("===================result key:%s\n" % key)
print("===================result key:%s" % key)
listTmp = list(resultDict[key])
for info in listTmp:
fp.write("=====================result value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s\n" % (
info.deviceId, info.sensorType, info.syncTimeStamp, info.picturePath))
print("=====================result value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s" % (
info.deviceId, info.sensorType, info.syncTimeStamp, info.picturePath))
matchPath = f"{resultPath}/matchFrames/"
safe_make_dir(matchPath)
notMatchPath = f"{resultPath}/notMatchFrames/"
abnormalPath = f"{resultPath}/abnormal/"
for key in resultDict:
listTmp = list(resultDict[key])
if (len(listTmp) == (deviceCount * streamProfileCount)):
haveAbnormalData = False
for info in listTmp:
if info.tspDiff >= tspRangeThreshold:
path = matchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + "_xxxxxx" + "_"+ str(info.exp) + "_"+ str(info.gain) + info.fileExt
shutil.copy(info.picturePath, path)
haveAbnormalData = True
else:
path = matchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + "_"+ str(info.exp) + "_"+ str(info.gain) + info.fileExt
shutil.copy(info.picturePath, path)
if haveAbnormalData:
safe_make_dir(abnormalPath)
for info in listTmp:
if info.tspDiff >= tspRangeThreshold:
path = abnormalPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + "_xxxxxx" + "_"+ str(info.exp) + "_"+ str(info.gain) + info.fileExt
shutil.copy(info.picturePath, path)
else:
path = abnormalPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + "_"+ str(info.exp) + "_"+ str(info.gain) + info.fileExt
shutil.copy(info.picturePath, path)
else:
safe_make_dir(notMatchPath)
for info in listTmp:
newFilePath = notMatchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + "_"+ str(info.exp) + "_"+ str(info.gain) + info.fileExt
shutil.copy(info.picturePath, newFilePath)
def main():
if not initPrimaryId():
print("Initialize primaryId failed. exit.")
return
if not initSyncConfigParams():
print("Initialized Sync config parameter failed. exit.")
return
initResultDir()
print(f"PrimaryId={primaryId}, frameRate={frameRate}, tspRangeThreshold={tspRangeThreshold}")
handleSyncFrames()
return
if __name__ == '__main__':
parser = argparse.ArgumentParser(description="Synchronize frames support for 'Orbbec Devices'")
parser.add_argument('frames_dir', type=str, help="Frames directory")
parser.add_argument('main_script_root_dir', type=str, help="SyncFramesMain.py working directory")
args = parser.parse_args()
sourceRootPath = args.frames_dir
sourceFramesPath = f"{args.frames_dir}/TotalModeFrames"
mainPythonWorkPath = args.main_script_root_dir
print(f"Start of CommonFrameMatch synchronize frame. sourceRootPath={sourceRootPath}")
main()
print("Finish of CommonFrameMatch synchronize frame.")
@@ -1,16 +0,0 @@
{
"D2CAlignMode": "ALIGN_D2C_SW_MODE",
"streamProfiles": [{
"sensorType": "OB_SENSOR_COLOR",
"width": 640,
"height": 480,
"fps": 30,
"format": "MJPEG"
}, {
"sensorType": "OB_SENSOR_IR_LEFT",
"width": 640,
"height": 480,
"fps": 30,
"format": "Y8"
}]
}