mirror of
https://github.com/orbbec/OrbbecSDK_ROS2.git
synced 2026-10-12 15:29:49 +08:00
fix: normalize line endings to LF (#118)
This commit is contained in:
+103
-103
@@ -1,104 +1,104 @@
|
|||||||
# -----------------------------
|
# -----------------------------
|
||||||
# Options affecting formatting.
|
# Options affecting formatting.
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
with section("format"):
|
with section("format"):
|
||||||
|
|
||||||
# Disable formatting entirely, making cmake-format a no-op
|
# Disable formatting entirely, making cmake-format a no-op
|
||||||
disable = False
|
disable = False
|
||||||
|
|
||||||
# How wide to allow formatted cmake files
|
# How wide to allow formatted cmake files
|
||||||
line_width = 120
|
line_width = 120
|
||||||
|
|
||||||
# How many spaces to tab for indent
|
# How many spaces to tab for indent
|
||||||
tab_size = 4
|
tab_size = 4
|
||||||
|
|
||||||
# If true, lines are indented using tab characters (utf-8 0x09) instead of
|
# If true, lines are indented using tab characters (utf-8 0x09) instead of
|
||||||
# <tab_size> space characters (utf-8 0x20). In cases where the layout would
|
# <tab_size> space characters (utf-8 0x20). In cases where the layout would
|
||||||
# require a fractional tab character, the behavior of the fractional
|
# require a fractional tab character, the behavior of the fractional
|
||||||
# indentation is governed by <fractional_tab_policy>
|
# indentation is governed by <fractional_tab_policy>
|
||||||
use_tabchars = False
|
use_tabchars = False
|
||||||
|
|
||||||
# If <use_tabchars> is True, then the value of this variable indicates how
|
# If <use_tabchars> is True, then the value of this variable indicates how
|
||||||
# fractional indentions are handled during whitespace replacement. If set to
|
# fractional indentions are handled during whitespace replacement. If set to
|
||||||
# 'use-space', fractional indentation is left as spaces (utf-8 0x20). If set
|
# 'use-space', fractional indentation is left as spaces (utf-8 0x20). If set
|
||||||
# to `round-up` fractional indentation is replaced with a single tab character
|
# to `round-up` fractional indentation is replaced with a single tab character
|
||||||
# (utf-8 0x09) effectively shifting the column to the next tabstop
|
# (utf-8 0x09) effectively shifting the column to the next tabstop
|
||||||
fractional_tab_policy = 'use-space'
|
fractional_tab_policy = 'use-space'
|
||||||
|
|
||||||
# If an argument group contains more than this many sub-groups (parg or kwarg
|
# If an argument group contains more than this many sub-groups (parg or kwarg
|
||||||
# groups) then force it to a vertical layout.
|
# groups) then force it to a vertical layout.
|
||||||
max_subgroups_hwrap = 4
|
max_subgroups_hwrap = 4
|
||||||
|
|
||||||
# If a positional argument group contains more than this many arguments, then
|
# If a positional argument group contains more than this many arguments, then
|
||||||
# force it to a vertical layout.
|
# force it to a vertical layout.
|
||||||
max_pargs_hwrap = 6
|
max_pargs_hwrap = 6
|
||||||
|
|
||||||
# If a cmdline positional group consumes more than this many lines without
|
# If a cmdline positional group consumes more than this many lines without
|
||||||
# nesting, then invalidate the layout (and nest)
|
# nesting, then invalidate the layout (and nest)
|
||||||
max_rows_cmdline = 2
|
max_rows_cmdline = 2
|
||||||
|
|
||||||
# If true, separate flow control names from their parentheses with a space
|
# If true, separate flow control names from their parentheses with a space
|
||||||
separate_ctrl_name_with_space = False
|
separate_ctrl_name_with_space = False
|
||||||
|
|
||||||
# If true, separate function names from parentheses with a space
|
# If true, separate function names from parentheses with a space
|
||||||
separate_fn_name_with_space = False
|
separate_fn_name_with_space = False
|
||||||
|
|
||||||
# If a statement is wrapped to more than one line, than dangle the closing
|
# If a statement is wrapped to more than one line, than dangle the closing
|
||||||
# parenthesis on its own line.
|
# parenthesis on its own line.
|
||||||
dangle_parens = True
|
dangle_parens = True
|
||||||
|
|
||||||
# If the trailing parenthesis must be 'dangled' on its on line, then align it
|
# If the trailing parenthesis must be 'dangled' on its on line, then align it
|
||||||
# to this reference: `prefix`: the start of the statement, `prefix-indent`:
|
# to this reference: `prefix`: the start of the statement, `prefix-indent`:
|
||||||
# the start of the statement, plus one indentation level, `child`: align to
|
# the start of the statement, plus one indentation level, `child`: align to
|
||||||
# the column of the arguments
|
# the column of the arguments
|
||||||
dangle_align = 'prefix'
|
dangle_align = 'prefix'
|
||||||
|
|
||||||
# If the statement spelling length (including space and parenthesis) is
|
# If the statement spelling length (including space and parenthesis) is
|
||||||
# smaller than this amount, then force reject nested layouts.
|
# smaller than this amount, then force reject nested layouts.
|
||||||
min_prefix_chars = 4
|
min_prefix_chars = 4
|
||||||
|
|
||||||
# If the statement spelling length (including space and parenthesis) is larger
|
# If the statement spelling length (including space and parenthesis) is larger
|
||||||
# than the tab width by more than this amount, then force reject un-nested
|
# than the tab width by more than this amount, then force reject un-nested
|
||||||
# layouts.
|
# layouts.
|
||||||
max_prefix_chars = 10
|
max_prefix_chars = 10
|
||||||
|
|
||||||
# If a candidate layout is wrapped horizontally but it exceeds this many
|
# If a candidate layout is wrapped horizontally but it exceeds this many
|
||||||
# lines, then reject the layout.
|
# lines, then reject the layout.
|
||||||
max_lines_hwrap = 2
|
max_lines_hwrap = 2
|
||||||
|
|
||||||
# What style line endings to use in the output.
|
# What style line endings to use in the output.
|
||||||
line_ending = 'unix'
|
line_ending = 'unix'
|
||||||
|
|
||||||
# Format command names consistently as 'lower' or 'upper' case
|
# Format command names consistently as 'lower' or 'upper' case
|
||||||
command_case = 'canonical'
|
command_case = 'canonical'
|
||||||
|
|
||||||
# Format keywords consistently as 'lower' or 'upper' case
|
# Format keywords consistently as 'lower' or 'upper' case
|
||||||
keyword_case = 'unchanged'
|
keyword_case = 'unchanged'
|
||||||
|
|
||||||
# A list of command names which should always be wrapped
|
# A list of command names which should always be wrapped
|
||||||
always_wrap = []
|
always_wrap = []
|
||||||
|
|
||||||
# If true, the argument lists which are known to be sortable will be sorted
|
# If true, the argument lists which are known to be sortable will be sorted
|
||||||
# lexicographicall
|
# lexicographicall
|
||||||
enable_sort = True
|
enable_sort = True
|
||||||
|
|
||||||
# If true, the parsers may infer whether or not an argument list is sortable
|
# If true, the parsers may infer whether or not an argument list is sortable
|
||||||
# (without annotation).
|
# (without annotation).
|
||||||
autosort = False
|
autosort = False
|
||||||
|
|
||||||
# By default, if cmake-format cannot successfully fit everything into the
|
# By default, if cmake-format cannot successfully fit everything into the
|
||||||
# desired linewidth it will apply the last, most agressive attempt that it
|
# desired linewidth it will apply the last, most agressive attempt that it
|
||||||
# made. If this flag is True, however, cmake-format will print error, exit
|
# made. If this flag is True, however, cmake-format will print error, exit
|
||||||
# with non-zero status code, and write-out nothing
|
# with non-zero status code, and write-out nothing
|
||||||
require_valid_layout = False
|
require_valid_layout = False
|
||||||
|
|
||||||
# A dictionary mapping layout nodes to a list of wrap decisions. See the
|
# A dictionary mapping layout nodes to a list of wrap decisions. See the
|
||||||
# documentation for more information.
|
# documentation for more information.
|
||||||
layout_passes = {}
|
layout_passes = {}
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
# Options affecting comment formatting (indirectly).
|
# Options affecting comment formatting (indirectly).
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
with section("markup"):
|
with section("markup"):
|
||||||
# Disabling markup avoids merging consecutive comment lines
|
# Disabling markup avoids merging consecutive comment lines
|
||||||
enable_markup = False
|
enable_markup = False
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
# Normalize text files to LF in both the repository and working tree.
|
||||||
|
* text=auto eol=lf
|
||||||
|
|
||||||
|
# Treat generated assets and bundled binaries as binary files.
|
||||||
|
*.stl binary
|
||||||
|
*.STL binary
|
||||||
|
*.so binary
|
||||||
|
*.so.* binary
|
||||||
|
*.png binary
|
||||||
|
*.jpg binary
|
||||||
|
*.jpeg binary
|
||||||
|
*.gif binary
|
||||||
|
*.pdf binary
|
||||||
|
*.zip binary
|
||||||
|
*.gz binary
|
||||||
|
|||||||
+8
-8
@@ -1,8 +1,8 @@
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
# Unit: FPS. Please fill in according to the actual dataset frame rate,
|
# Unit: FPS. Please fill in according to the actual dataset frame rate,
|
||||||
# otherwise the matching will be inaccurate.
|
# otherwise the matching will be inaccurate.
|
||||||
frameRate=30
|
frameRate=30
|
||||||
# Unit: ms. When the timestamp range difference of a matched frame group
|
# Unit: ms. When the timestamp range difference of a matched frame group
|
||||||
# is greater than or equal to tspRangeThreshold, the file name will be marked.
|
# is greater than or equal to tspRangeThreshold, the file name will be marked.
|
||||||
tspRangeThreshold=4
|
tspRangeThreshold=4
|
||||||
|
|
||||||
|
|||||||
+6
-6
@@ -1,7 +1,7 @@
|
|||||||
## config_frameMatch.py
|
## config_frameMatch.py
|
||||||
|
|
||||||
**Definition of the three folders:**
|
**Definition of the three folders:**
|
||||||
|
|
||||||
- **matchFrames**: Data constrained within a half-frame.
|
- **matchFrames**: Data constrained within a half-frame.
|
||||||
- **notMatchFrames**: Data not constrained within a half-frame, unmatched.
|
- **notMatchFrames**: Data not constrained within a half-frame, unmatched.
|
||||||
- **abnormal**: Data within the group that exceeds the `tspRangeThreshold` setting.
|
- **abnormal**: Data within the group that exceeds the `tspRangeThreshold` setting.
|
||||||
+90
-90
@@ -1,90 +1,90 @@
|
|||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import json
|
import json
|
||||||
import platform
|
import platform
|
||||||
|
|
||||||
def list_subdirectories(path):
|
def list_subdirectories(path):
|
||||||
for f in os.listdir(path):
|
for f in os.listdir(path):
|
||||||
if os.path.isdir(os.path.join(path, f)):
|
if os.path.isdir(os.path.join(path, f)):
|
||||||
yield f
|
yield f
|
||||||
|
|
||||||
def read_pid_from_device_json(frames_dir):
|
def read_pid_from_device_json(frames_dir):
|
||||||
file_path = frames_dir + "/DevicesInfo.txt"
|
file_path = frames_dir + "/DevicesInfo.txt"
|
||||||
if not os.path.exists(file_path):
|
if not os.path.exists(file_path):
|
||||||
print(file_path + " not exists. Please check it")
|
print(file_path + " not exists. Please check it")
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
with open(file_path, 'r') as f:
|
with open(file_path, 'r') as f:
|
||||||
data = json.load(f)
|
data = json.load(f)
|
||||||
|
|
||||||
if not 'devicePid' in data:
|
if not 'devicePid' in data:
|
||||||
print("Not found 'devicePid' in " + file_path)
|
print("Not found 'devicePid' in " + file_path)
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
return data['devicePid']
|
return data['devicePid']
|
||||||
|
|
||||||
def execute_sync_width_pid(frames_dir, pid):
|
def execute_sync_width_pid(frames_dir, pid):
|
||||||
sync_script_file=""
|
sync_script_file=""
|
||||||
if pid.lower() == "0x0675":
|
if pid.lower() == "0x0675":
|
||||||
sync_script_file="script/config_frameMatch_Gemini2VL.py"
|
sync_script_file="script/config_frameMatch_Gemini2VL.py"
|
||||||
elif pid.lower() == "0x0670" or pid.lower() == "0x0701":
|
elif pid.lower() == "0x0670" or pid.lower() == "0x0701":
|
||||||
sync_script_file="script/config_frameMatch-systemTimestamp.py"
|
sync_script_file="script/config_frameMatch-systemTimestamp.py"
|
||||||
elif pid.lower() == "0x0660":
|
elif pid.lower() == "0x0660":
|
||||||
sync_script_file="script/config_frameMatch-Astra2_new.py"
|
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":
|
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"
|
sync_script_file="script/config_frameMatch_g330.py"
|
||||||
else:
|
else:
|
||||||
sync_script_file="script/config_frameMatch.py"
|
sync_script_file="script/config_frameMatch.py"
|
||||||
|
|
||||||
if len(sync_script_file) > 0:
|
if len(sync_script_file) > 0:
|
||||||
print(f"execute synchronize frames. script_file={sync_script_file}, frames_dir={frames_dir}")
|
print(f"execute synchronize frames. script_file={sync_script_file}, frames_dir={frames_dir}")
|
||||||
if platform.system() == "Windows":
|
if platform.system() == "Windows":
|
||||||
output = subprocess.check_output(["python", sync_script_file, os.path.abspath(f"{frames_dir}"), os.getcwd()])
|
output = subprocess.check_output(["python", sync_script_file, os.path.abspath(f"{frames_dir}"), os.getcwd()])
|
||||||
print(output.decode("gbk"))
|
print(output.decode("gbk"))
|
||||||
else:
|
else:
|
||||||
output = subprocess.check_output(["python3", sync_script_file, os.path.abspath(f"{frames_dir}"), os.getcwd()])
|
output = subprocess.check_output(["python3", sync_script_file, os.path.abspath(f"{frames_dir}"), os.getcwd()])
|
||||||
print(output.decode("utf-8"))
|
print(output.decode("utf-8"))
|
||||||
else:
|
else:
|
||||||
print("Invalid pid=" + pid + ", not match sync frame script")
|
print("Invalid pid=" + pid + ", not match sync frame script")
|
||||||
|
|
||||||
def sync_frames(frames_dir):
|
def sync_frames(frames_dir):
|
||||||
pid = read_pid_from_device_json(frames_dir)
|
pid = read_pid_from_device_json(frames_dir)
|
||||||
if len(pid) <= 0:
|
if len(pid) <= 0:
|
||||||
print("Get pid failed.")
|
print("Get pid failed.")
|
||||||
return
|
return
|
||||||
|
|
||||||
execute_sync_width_pid(frames_dir, pid)
|
execute_sync_width_pid(frames_dir, pid)
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
frames_output_path = os.path.abspath("../output")
|
frames_output_path = os.path.abspath("../output")
|
||||||
|
|
||||||
subdirectories = list(list_subdirectories(frames_output_path))
|
subdirectories = list(list_subdirectories(frames_output_path))
|
||||||
|
|
||||||
if not subdirectories:
|
if not subdirectories:
|
||||||
print("No subdirectories found in the specified directory.")
|
print("No subdirectories found in the specified directory.")
|
||||||
|
|
||||||
for i, subdir in enumerate(subdirectories):
|
for i, subdir in enumerate(subdirectories):
|
||||||
print(f"{i + 1}. {subdir}")
|
print(f"{i + 1}. {subdir}")
|
||||||
|
|
||||||
choice = input("Please select a subdirectory by number (or 'q' to quit): ")
|
choice = input("Please select a subdirectory by number (or 'q' to quit): ")
|
||||||
|
|
||||||
if choice.lower() == 'q':
|
if choice.lower() == 'q':
|
||||||
return
|
return
|
||||||
|
|
||||||
is_index_valid = False
|
is_index_valid = False
|
||||||
try:
|
try:
|
||||||
index = int(choice) - 1
|
index = int(choice) - 1
|
||||||
if 0 <= index < len(subdirectories):
|
if 0 <= index < len(subdirectories):
|
||||||
is_index_valid = True
|
is_index_valid = True
|
||||||
else:
|
else:
|
||||||
print(f"Invalid choice. index={index}. Please enter a number between 1 and the total number of subdirectories.")
|
print(f"Invalid choice. index={index}. Please enter a number between 1 and the total number of subdirectories.")
|
||||||
except ValueError:
|
except ValueError:
|
||||||
print("Invalid choice(ValueException). Please enter a number between 1 and the total number of subdirectories")
|
print("Invalid choice(ValueException). Please enter a number between 1 and the total number of subdirectories")
|
||||||
if is_index_valid:
|
if is_index_valid:
|
||||||
selected_subdir = subdirectories[index]
|
selected_subdir = subdirectories[index]
|
||||||
print(f"You selected the subdirectory: {selected_subdir}")
|
print(f"You selected the subdirectory: {selected_subdir}")
|
||||||
sync_frames(f"{frames_output_path }/{selected_subdir}")
|
sync_frames(f"{frames_output_path }/{selected_subdir}")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|||||||
+392
-392
@@ -1,392 +1,392 @@
|
|||||||
import os.path
|
import os.path
|
||||||
import argparse
|
import argparse
|
||||||
import sys
|
import sys
|
||||||
import json
|
import json
|
||||||
import shutil
|
import shutil
|
||||||
import configparser
|
import configparser
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
## Config.ini configuration
|
## Config.ini configuration
|
||||||
# Unit: FPS. Please fill in according to the actual dataset frame rate,
|
# Unit: FPS. Please fill in according to the actual dataset frame rate,
|
||||||
# otherwise it will cause inaccurate matching.
|
# otherwise it will cause inaccurate matching.
|
||||||
frameRate = -1
|
frameRate = -1
|
||||||
# Unit: ms. When the timestamp range difference of a matched frame group
|
# Unit: ms. When the timestamp range difference of a matched frame group
|
||||||
# is greater than or equal to tspRangeThreshold, the file name will be marked.
|
# is greater than or equal to tspRangeThreshold, the file name will be marked.
|
||||||
tspRangeThreshold = -1
|
tspRangeThreshold = -1
|
||||||
|
|
||||||
## Parsed automatically by Python script, DO NOT modify
|
## Parsed automatically by Python script, DO NOT modify
|
||||||
primaryId = '-1' # Host ID
|
primaryId = '-1' # Host ID
|
||||||
mainPythonWorkPath = "" # Working directory of SyncFramesMain.py
|
mainPythonWorkPath = "" # Working directory of SyncFramesMain.py
|
||||||
sourceFramesPath = "" # DO NOT modify, fixed value, path to TotalMode directory
|
sourceFramesPath = "" # DO NOT modify, fixed value, path to TotalMode directory
|
||||||
sourceRootPath = "" # Root directory containing TotalMode
|
sourceRootPath = "" # Root directory containing TotalMode
|
||||||
resultPath = "" # Path to save sync analysis results
|
resultPath = "" # Path to save sync analysis results
|
||||||
streamProfileDict = dict() # Store Python results
|
streamProfileDict = dict() # Store Python results
|
||||||
|
|
||||||
|
|
||||||
class PictureInfo(object):
|
class PictureInfo(object):
|
||||||
class Struct(object):
|
class Struct(object):
|
||||||
def __init__(self, deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt):
|
def __init__(self, deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt):
|
||||||
self.deviceId = deviceId
|
self.deviceId = deviceId
|
||||||
self.sensorType = sensorType
|
self.sensorType = sensorType
|
||||||
self.syncTimeStamp = syncTimeStamp
|
self.syncTimeStamp = syncTimeStamp
|
||||||
self.picturePath = picturePath
|
self.picturePath = picturePath
|
||||||
self.deviceIdFull = deviceIdFull
|
self.deviceIdFull = deviceIdFull
|
||||||
self.fileExt = fileExt
|
self.fileExt = fileExt
|
||||||
|
|
||||||
def make_struct(self, deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt):
|
def make_struct(self, deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt):
|
||||||
return self.Struct(deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt)
|
return self.Struct(deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt)
|
||||||
|
|
||||||
|
|
||||||
class StreamProfileInfo:
|
class StreamProfileInfo:
|
||||||
def __init__(self, sensorType, width, height, format, fps):
|
def __init__(self, sensorType, width, height, format, fps):
|
||||||
self.sensorType = sensorType
|
self.sensorType = sensorType
|
||||||
self.width = width
|
self.width = width
|
||||||
self.height = height
|
self.height = height
|
||||||
self.format = format
|
self.format = format
|
||||||
self.fps = fps
|
self.fps = fps
|
||||||
|
|
||||||
|
|
||||||
def initPrimaryId():
|
def initPrimaryId():
|
||||||
global primaryId
|
global primaryId
|
||||||
|
|
||||||
deviceInfoPath = f"{sourceRootPath}/DevicesInfo.txt"
|
deviceInfoPath = f"{sourceRootPath}/DevicesInfo.txt"
|
||||||
if not os.path.exists(deviceInfoPath):
|
if not os.path.exists(deviceInfoPath):
|
||||||
print(f"Initialize primaryId failed. {deviceInfoPath} not exists")
|
print(f"Initialize primaryId failed. {deviceInfoPath} not exists")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
with open(deviceInfoPath, 'r') as f:
|
with open(deviceInfoPath, 'r') as f:
|
||||||
data = json.load(f)
|
data = json.load(f)
|
||||||
|
|
||||||
if not 'devices' in data:
|
if not 'devices' in data:
|
||||||
print(f"Initialize primaryId failed. {deviceInfoPath} not contain item 'devices'")
|
print(f"Initialize primaryId failed. {deviceInfoPath} not contain item 'devices'")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
for item in data['devices']:
|
for item in data['devices']:
|
||||||
if 'isPrimaryDevice' in item and 'index' in item and item['isPrimaryDevice']:
|
if 'isPrimaryDevice' in item and 'index' in item and item['isPrimaryDevice']:
|
||||||
primaryId = str(item['index'])
|
primaryId = str(item['index'])
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def initSyncConfigParams():
|
def initSyncConfigParams():
|
||||||
global frameRate, tspRangeThreshold
|
global frameRate, tspRangeThreshold
|
||||||
|
|
||||||
configPath = f"{mainPythonWorkPath}/Config.ini"
|
configPath = f"{mainPythonWorkPath}/Config.ini"
|
||||||
if not os.path.exists(configPath):
|
if not os.path.exists(configPath):
|
||||||
print(f"Initliaze synchronized config parameter failed. {configPath} not exists.")
|
print(f"Initliaze synchronized config parameter failed. {configPath} not exists.")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Create ConfigParser object
|
# Create ConfigParser object
|
||||||
config = configparser.ConfigParser()
|
config = configparser.ConfigParser()
|
||||||
|
|
||||||
# Read ini file
|
# Read ini file
|
||||||
config.read(configPath, 'utf-8')
|
config.read(configPath, 'utf-8')
|
||||||
|
|
||||||
if not config.has_option('Parameter', 'frameRate'):
|
if not config.has_option('Parameter', 'frameRate'):
|
||||||
print(f"Initliaze synchronized config parameter failed. Not define 'frameRate' in ${configPath}")
|
print(f"Initliaze synchronized config parameter failed. Not define 'frameRate' in ${configPath}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if not config.has_option('Parameter', 'tspRangeThreshold'):
|
if not config.has_option('Parameter', 'tspRangeThreshold'):
|
||||||
print(f"Initliaze synchronized config parameter failed. Not define 'tspRangeThreshold' in ${configPath}")
|
print(f"Initliaze synchronized config parameter failed. Not define 'tspRangeThreshold' in ${configPath}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
frameRate = config.getfloat('Parameter', 'frameRate')
|
frameRate = config.getfloat('Parameter', 'frameRate')
|
||||||
if frameRate <= 0 or frameRate >= 1000:
|
if frameRate <= 0 or frameRate >= 1000:
|
||||||
print(f"Initliaze synchronized config parameter failed. Invalid frameRate={frameRate}")
|
print(f"Initliaze synchronized config parameter failed. Invalid frameRate={frameRate}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
tspRangeThreshold = config.getfloat('Parameter', 'tspRangeThreshold')
|
tspRangeThreshold = config.getfloat('Parameter', 'tspRangeThreshold')
|
||||||
if tspRangeThreshold <= 0:
|
if tspRangeThreshold <= 0:
|
||||||
print(f"Initliaze synchronized config parameter failed. Invalid tspRangeThreshold={tspRangeThreshold}")
|
print(f"Initliaze synchronized config parameter failed. Invalid tspRangeThreshold={tspRangeThreshold}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def getDeviceCount():
|
def getDeviceCount():
|
||||||
deviceInfoPath = f"{sourceRootPath}/DevicesInfo.txt"
|
deviceInfoPath = f"{sourceRootPath}/DevicesInfo.txt"
|
||||||
if not os.path.exists(deviceInfoPath):
|
if not os.path.exists(deviceInfoPath):
|
||||||
print(f"Get device count failed. {deviceInfoPath} not exists")
|
print(f"Get device count failed. {deviceInfoPath} not exists")
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
with open(deviceInfoPath, 'r') as f:
|
with open(deviceInfoPath, 'r') as f:
|
||||||
data = json.load(f)
|
data = json.load(f)
|
||||||
|
|
||||||
if not 'devices' in data:
|
if not 'devices' in data:
|
||||||
print(f"Get device count failed. {deviceInfoPath} not contain item 'devices'")
|
print(f"Get device count failed. {deviceInfoPath} not contain item 'devices'")
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
return len(data['devices'])
|
return len(data['devices'])
|
||||||
|
|
||||||
|
|
||||||
def initProfileInfoDict():
|
def initProfileInfoDict():
|
||||||
global streamProfileDict
|
global streamProfileDict
|
||||||
|
|
||||||
streamProfileDict = dict()
|
streamProfileDict = dict()
|
||||||
profilePath = f"{sourceRootPath}/StreamProfileInfo.txt"
|
profilePath = f"{sourceRootPath}/StreamProfileInfo.txt"
|
||||||
if not os.path.exists(profilePath):
|
if not os.path.exists(profilePath):
|
||||||
print(f"Initialize profile information dictionary failed. {profilePath} not exists")
|
print(f"Initialize profile information dictionary failed. {profilePath} not exists")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
with open(profilePath, 'r') as f:
|
with open(profilePath, 'r') as f:
|
||||||
data = json.load(f)
|
data = json.load(f)
|
||||||
|
|
||||||
if not 'streamProfiles' in data:
|
if not 'streamProfiles' in data:
|
||||||
print(f"Initialize profile information dictionary failed. {profilePath} not contain item 'streamProfiles'")
|
print(f"Initialize profile information dictionary failed. {profilePath} not contain item 'streamProfiles'")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
for item in data['streamProfiles']:
|
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:
|
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'])
|
profileInfo = StreamProfileInfo(item['sensorType'], item['width'], item['height'], item['format'], item['fps'])
|
||||||
streamProfileDict.setdefault(item['sensorType'], profileInfo)
|
streamProfileDict.setdefault(item['sensorType'], profileInfo)
|
||||||
else:
|
else:
|
||||||
print(f"Initialize profile information dictionary. Error invalid StreamProfile, {item}")
|
print(f"Initialize profile information dictionary. Error invalid StreamProfile, {item}")
|
||||||
|
|
||||||
return len(streamProfileDict.items()) > 0
|
return len(streamProfileDict.items()) > 0
|
||||||
|
|
||||||
|
|
||||||
def initResultDir():
|
def initResultDir():
|
||||||
global resultPath
|
global resultPath
|
||||||
timeText = datetime.now().strftime("%Y-%m-%d_%H%M%S")
|
timeText = datetime.now().strftime("%Y-%m-%d_%H%M%S")
|
||||||
resultPath = f"{sourceRootPath}/results-{timeText}"
|
resultPath = f"{sourceRootPath}/results-{timeText}"
|
||||||
if not os.path.exists(resultPath):
|
if not os.path.exists(resultPath):
|
||||||
os.makedirs(resultPath)
|
os.makedirs(resultPath)
|
||||||
|
|
||||||
|
|
||||||
def isFrameFile(fileName):
|
def isFrameFile(fileName):
|
||||||
fileExt = os.path.splitext(fileName)
|
fileExt = os.path.splitext(fileName)
|
||||||
if len(fileExt) < 2:
|
if len(fileExt) < 2:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
frameExts = {".jpeg", ".jpg", ".png", ".raw", "bmp"}
|
frameExts = {".jpeg", ".jpg", ".png", ".raw", "bmp"}
|
||||||
return fileExt[1] in frameExts
|
return fileExt[1] in frameExts
|
||||||
|
|
||||||
|
|
||||||
def initPictureInfoDictionary(rootFilePath, pictureInfoDict):
|
def initPictureInfoDictionary(rootFilePath, pictureInfoDict):
|
||||||
frameFileCount = 0
|
frameFileCount = 0
|
||||||
for dirpath, dirnames, filenames in os.walk(rootFilePath):
|
for dirpath, dirnames, filenames in os.walk(rootFilePath):
|
||||||
# print(f"dirpath={dirpath}, dirpath.basename=" + os.path.basename(dirpath))
|
# print(f"dirpath={dirpath}, dirpath.basename=" + os.path.basename(dirpath))
|
||||||
for fileName in filenames:
|
for fileName in filenames:
|
||||||
filePath = os.path.join(dirpath, fileName)
|
filePath = os.path.join(dirpath, fileName)
|
||||||
if not isFrameFile(fileName):
|
if not isFrameFile(fileName):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
frameFileCount += 1
|
frameFileCount += 1
|
||||||
fileNameNoExt = os.path.splitext(fileName)[0]
|
fileNameNoExt = os.path.splitext(fileName)[0]
|
||||||
pictureNameList = fileNameNoExt.split('_')
|
pictureNameList = fileNameNoExt.split('_')
|
||||||
deviceId = pictureNameList[2][5:]
|
deviceId = pictureNameList[2][5:]
|
||||||
sensorType = pictureNameList[0].replace('#', '_')
|
sensorType = pictureNameList[0].replace('#', '_')
|
||||||
syncTimeStamp = int(pictureNameList[3][1:])
|
syncTimeStamp = int(pictureNameList[3][1:])
|
||||||
|
|
||||||
# Create struct
|
# Create struct
|
||||||
pictureInfo = PictureInfo()
|
pictureInfo = PictureInfo()
|
||||||
info = pictureInfo.make_struct(deviceId, sensorType, syncTimeStamp, filePath, os.path.basename(dirpath), os.path.splitext(fileName)[1])
|
info = pictureInfo.make_struct(deviceId, sensorType, syncTimeStamp, filePath, os.path.basename(dirpath), os.path.splitext(fileName)[1])
|
||||||
|
|
||||||
# Format dictionary: one key corresponds to one array
|
# Format dictionary: one key corresponds to one array
|
||||||
pictureInfoDict.setdefault(deviceId, []).append(info)
|
pictureInfoDict.setdefault(deviceId, []).append(info)
|
||||||
|
|
||||||
if 0 == frameFileCount:
|
if 0 == frameFileCount:
|
||||||
print("initialize pictureInfoDict failed. Not found frame file")
|
print("initialize pictureInfoDict failed. Not found frame file")
|
||||||
|
|
||||||
|
|
||||||
def matchFrame(pictureInfoDict):
|
def matchFrame(pictureInfoDict):
|
||||||
global primaryId, frameRate
|
global primaryId, frameRate
|
||||||
global streamProfileDict
|
global streamProfileDict
|
||||||
|
|
||||||
# Get comparison image array, take the Color array of the first device for comparison
|
# Get comparison image array, take the Color array of the first device for comparison
|
||||||
compareList = []
|
compareList = []
|
||||||
for key in pictureInfoDict:
|
for key in pictureInfoDict:
|
||||||
listTmp = list(pictureInfoDict[key])
|
listTmp = list(pictureInfoDict[key])
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
if info.deviceId == primaryId and info.sensorType == 'color':
|
if info.deviceId == primaryId and info.sensorType == 'color':
|
||||||
compareList.append(info)
|
compareList.append(info)
|
||||||
|
|
||||||
sorted_dict = dict(sorted(pictureInfoDict.items(), key=lambda x: x[1], reverse=False))
|
sorted_dict = dict(sorted(pictureInfoDict.items(), key=lambda x: x[1], reverse=False))
|
||||||
pictureInfoDict = sorted_dict
|
pictureInfoDict = sorted_dict
|
||||||
|
|
||||||
# Dynamically analyze based on stream opening status to reduce loop iterations
|
# Dynamically analyze based on stream opening status to reduce loop iterations
|
||||||
hasColorProfile = 'OB_SENSOR_COLOR' in streamProfileDict
|
hasColorProfile = 'OB_SENSOR_COLOR' in streamProfileDict
|
||||||
hasDepthProfile = 'OB_SENSOR_DEPTH' in streamProfileDict
|
hasDepthProfile = 'OB_SENSOR_DEPTH' in streamProfileDict
|
||||||
hasIRProfile = 'OB_SENSOR_IR' in streamProfileDict
|
hasIRProfile = 'OB_SENSOR_IR' in streamProfileDict
|
||||||
|
|
||||||
# Match adjacent frames
|
# Match adjacent frames
|
||||||
resultDict = {}
|
resultDict = {}
|
||||||
consumedList = []
|
consumedList = []
|
||||||
dictIndex = 0
|
dictIndex = 0
|
||||||
frameTspGap = int(1000.0/frameRate+0.5)
|
frameTspGap = int(1000.0/frameRate+0.5)
|
||||||
for comparePic in compareList:
|
for comparePic in compareList:
|
||||||
resultDict.setdefault(dictIndex, []).append(comparePic)
|
resultDict.setdefault(dictIndex, []).append(comparePic)
|
||||||
for key in pictureInfoDict:
|
for key in pictureInfoDict:
|
||||||
listTmp = list(pictureInfoDict[key])
|
listTmp = list(pictureInfoDict[key])
|
||||||
# Compare Color
|
# Compare Color
|
||||||
if hasColorProfile:
|
if hasColorProfile:
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info in consumedList:
|
if info in consumedList:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info.sensorType == 'color' and info.syncTimeStamp >= comparePic.syncTimeStamp and info.syncTimeStamp - comparePic.syncTimeStamp <= frameTspGap:
|
if info.sensorType == 'color' and info.syncTimeStamp >= comparePic.syncTimeStamp and info.syncTimeStamp - comparePic.syncTimeStamp <= frameTspGap:
|
||||||
resultDict.setdefault(dictIndex, []).append(info)
|
resultDict.setdefault(dictIndex, []).append(info)
|
||||||
consumedList.append(info)
|
consumedList.append(info)
|
||||||
break
|
break
|
||||||
|
|
||||||
# Compare Depth
|
# Compare Depth
|
||||||
if hasDepthProfile:
|
if hasDepthProfile:
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info in consumedList:
|
if info in consumedList:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info.sensorType == 'depth' and info.syncTimeStamp >= comparePic.syncTimeStamp and info.syncTimeStamp - comparePic.syncTimeStamp <= frameTspGap:
|
if info.sensorType == 'depth' and info.syncTimeStamp >= comparePic.syncTimeStamp and info.syncTimeStamp - comparePic.syncTimeStamp <= frameTspGap:
|
||||||
resultDict.setdefault(dictIndex, []).append(info)
|
resultDict.setdefault(dictIndex, []).append(info)
|
||||||
consumedList.append(info)
|
consumedList.append(info)
|
||||||
break
|
break
|
||||||
|
|
||||||
# Compare IR
|
# Compare IR
|
||||||
if hasIRProfile:
|
if hasIRProfile:
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info in consumedList:
|
if info in consumedList:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info.sensorType == 'ir' and info.syncTimeStamp >= comparePic.syncTimeStamp and info.syncTimeStamp - comparePic.syncTimeStamp <= frameTspGap:
|
if info.sensorType == 'ir' and info.syncTimeStamp >= comparePic.syncTimeStamp and info.syncTimeStamp - comparePic.syncTimeStamp <= frameTspGap:
|
||||||
resultDict.setdefault(dictIndex, []).append(info)
|
resultDict.setdefault(dictIndex, []).append(info)
|
||||||
consumedList.append(info)
|
consumedList.append(info)
|
||||||
break
|
break
|
||||||
|
|
||||||
# Calculate deviation
|
# Calculate deviation
|
||||||
for info in resultDict[dictIndex]:
|
for info in resultDict[dictIndex]:
|
||||||
info.tspDiff = info.syncTimeStamp - comparePic.syncTimeStamp
|
info.tspDiff = info.syncTimeStamp - comparePic.syncTimeStamp
|
||||||
|
|
||||||
dictIndex += 1
|
dictIndex += 1
|
||||||
|
|
||||||
return resultDict
|
return resultDict
|
||||||
|
|
||||||
|
|
||||||
def safe_make_dir(path):
|
def safe_make_dir(path):
|
||||||
if not os.path.exists(path):
|
if not os.path.exists(path):
|
||||||
os.makedirs(path)
|
os.makedirs(path)
|
||||||
|
|
||||||
|
|
||||||
def handleSyncFrames():
|
def handleSyncFrames():
|
||||||
global resultPath
|
global resultPath
|
||||||
global sourceFramesPath
|
global sourceFramesPath
|
||||||
global streamProfileDict
|
global streamProfileDict
|
||||||
|
|
||||||
fp = open(f"{resultPath}/frameMatchLog.txt", "w")
|
fp = open(f"{resultPath}/frameMatchLog.txt", "w")
|
||||||
|
|
||||||
if not initProfileInfoDict():
|
if not initProfileInfoDict():
|
||||||
print("Initialize stream profile dictionary failed. exit")
|
print("Initialize stream profile dictionary failed. exit")
|
||||||
return
|
return
|
||||||
print(f"Stream profiles: {streamProfileDict}")
|
print(f"Stream profiles: {streamProfileDict}")
|
||||||
streamProfileCount = len(streamProfileDict.items())
|
streamProfileCount = len(streamProfileDict.items())
|
||||||
|
|
||||||
pictureInfoDict = {}
|
pictureInfoDict = {}
|
||||||
|
|
||||||
initPictureInfoDictionary(Path(sourceFramesPath), pictureInfoDict)
|
initPictureInfoDictionary(Path(sourceFramesPath), pictureInfoDict)
|
||||||
if len(pictureInfoDict) <= 0:
|
if len(pictureInfoDict) <= 0:
|
||||||
print("init pictureInfoDict failed. pictureInfoDict.len = 0")
|
print("init pictureInfoDict failed. pictureInfoDict.len = 0")
|
||||||
return
|
return
|
||||||
|
|
||||||
# # Dump pictureInfoDict
|
# # Dump pictureInfoDict
|
||||||
# for key in pictureInfoDict:
|
# for key in pictureInfoDict:
|
||||||
# print("===================key:%s" % key)
|
# print("===================key:%s" % key)
|
||||||
# listTmp = list(pictureInfoDict[key])
|
# listTmp = list(pictureInfoDict[key])
|
||||||
# for info in listTmp:
|
# for info in listTmp:
|
||||||
# print("=====================value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s" % (info.deviceId,info.sensorType,info.syncTimeStamp,info.picturePath))
|
# print("=====================value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s" % (info.deviceId,info.sensorType,info.syncTimeStamp,info.picturePath))
|
||||||
|
|
||||||
deviceCount = getDeviceCount()
|
deviceCount = getDeviceCount()
|
||||||
print("=================device count:%d" % deviceCount)
|
print("=================device count:%d" % deviceCount)
|
||||||
|
|
||||||
resultDict = {}
|
resultDict = {}
|
||||||
resultDict = matchFrame(pictureInfoDict)
|
resultDict = matchFrame(pictureInfoDict)
|
||||||
|
|
||||||
for key in resultDict:
|
for key in resultDict:
|
||||||
fp.write("===================result key:%s\n" % key)
|
fp.write("===================result key:%s\n" % key)
|
||||||
print("===================result key:%s" % key)
|
print("===================result key:%s" % key)
|
||||||
listTmp = list(resultDict[key])
|
listTmp = list(resultDict[key])
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
fp.write("=====================result value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s\n" % (
|
fp.write("=====================result value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s\n" % (
|
||||||
info.deviceId, info.sensorType, info.syncTimeStamp, info.picturePath))
|
info.deviceId, info.sensorType, info.syncTimeStamp, info.picturePath))
|
||||||
print("=====================result value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s" % (
|
print("=====================result value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s" % (
|
||||||
info.deviceId, info.sensorType, info.syncTimeStamp, info.picturePath))
|
info.deviceId, info.sensorType, info.syncTimeStamp, info.picturePath))
|
||||||
|
|
||||||
matchPath = f"{resultPath}/matchFrames/"
|
matchPath = f"{resultPath}/matchFrames/"
|
||||||
safe_make_dir(matchPath)
|
safe_make_dir(matchPath)
|
||||||
notMatchPath = f"{resultPath}/notMatchFrames/"
|
notMatchPath = f"{resultPath}/notMatchFrames/"
|
||||||
abnormalPath = f"{resultPath}/abnormal/"
|
abnormalPath = f"{resultPath}/abnormal/"
|
||||||
|
|
||||||
for key in resultDict:
|
for key in resultDict:
|
||||||
listTmp = list(resultDict[key])
|
listTmp = list(resultDict[key])
|
||||||
if (len(listTmp) == (deviceCount * streamProfileCount)):
|
if (len(listTmp) == (deviceCount * streamProfileCount)):
|
||||||
haveAbnormalData = False
|
haveAbnormalData = False
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
if info.tspDiff >= tspRangeThreshold:
|
if info.tspDiff >= tspRangeThreshold:
|
||||||
path = matchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
path = matchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
||||||
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + "_xxxxxx" + info.fileExt
|
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + "_xxxxxx" + info.fileExt
|
||||||
shutil.copy(info.picturePath, path)
|
shutil.copy(info.picturePath, path)
|
||||||
haveAbnormalData = True
|
haveAbnormalData = True
|
||||||
else:
|
else:
|
||||||
path = matchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
path = matchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
||||||
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + info.fileExt
|
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + info.fileExt
|
||||||
shutil.copy(info.picturePath, path)
|
shutil.copy(info.picturePath, path)
|
||||||
|
|
||||||
if haveAbnormalData:
|
if haveAbnormalData:
|
||||||
safe_make_dir(abnormalPath)
|
safe_make_dir(abnormalPath)
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
if info.tspDiff >= tspRangeThreshold:
|
if info.tspDiff >= tspRangeThreshold:
|
||||||
path = abnormalPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
path = abnormalPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
||||||
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + "_xxxxxx" + info.fileExt
|
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + "_xxxxxx" + info.fileExt
|
||||||
shutil.copy(info.picturePath, path)
|
shutil.copy(info.picturePath, path)
|
||||||
else:
|
else:
|
||||||
path = abnormalPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
path = abnormalPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
||||||
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + info.fileExt
|
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + info.fileExt
|
||||||
shutil.copy(info.picturePath, path)
|
shutil.copy(info.picturePath, path)
|
||||||
else:
|
else:
|
||||||
safe_make_dir(notMatchPath)
|
safe_make_dir(notMatchPath)
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
newFilePath = notMatchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
newFilePath = notMatchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
||||||
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + info.fileExt
|
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + info.fileExt
|
||||||
shutil.copy(info.picturePath, newFilePath)
|
shutil.copy(info.picturePath, newFilePath)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
if not initPrimaryId():
|
if not initPrimaryId():
|
||||||
print("Initialize primaryId failed. exit.")
|
print("Initialize primaryId failed. exit.")
|
||||||
return
|
return
|
||||||
|
|
||||||
if not initSyncConfigParams():
|
if not initSyncConfigParams():
|
||||||
print("Initialized Sync config parameter failed. exit.")
|
print("Initialized Sync config parameter failed. exit.")
|
||||||
return
|
return
|
||||||
|
|
||||||
initResultDir()
|
initResultDir()
|
||||||
|
|
||||||
print(f"PrimaryId={primaryId}, frameRate={frameRate}, tspRangeThreshold={tspRangeThreshold}")
|
print(f"PrimaryId={primaryId}, frameRate={frameRate}, tspRangeThreshold={tspRangeThreshold}")
|
||||||
handleSyncFrames()
|
handleSyncFrames()
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
parser = argparse.ArgumentParser(description="Synchronize frames support for 'Orbbec Astra2'")
|
parser = argparse.ArgumentParser(description="Synchronize frames support for 'Orbbec Astra2'")
|
||||||
parser.add_argument('frames_dir', type=str, help="Frames directory")
|
parser.add_argument('frames_dir', type=str, help="Frames directory")
|
||||||
parser.add_argument('main_script_root_dir', type=str, help="SyncFramesMain.py working directory")
|
parser.add_argument('main_script_root_dir', type=str, help="SyncFramesMain.py working directory")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
sourceRootPath = args.frames_dir
|
sourceRootPath = args.frames_dir
|
||||||
sourceFramesPath = f"{args.frames_dir}/TotalModeFrames"
|
sourceFramesPath = f"{args.frames_dir}/TotalModeFrames"
|
||||||
mainPythonWorkPath = args.main_script_root_dir
|
mainPythonWorkPath = args.main_script_root_dir
|
||||||
print(f"Start of Astra2 synchronize frame. sourceRootPath={sourceRootPath}")
|
print(f"Start of Astra2 synchronize frame. sourceRootPath={sourceRootPath}")
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|
||||||
print("Finish of Astra2 synchronize frame.")
|
print("Finish of Astra2 synchronize frame.")
|
||||||
|
|||||||
+403
-403
@@ -1,403 +1,403 @@
|
|||||||
import os.path
|
import os.path
|
||||||
import argparse
|
import argparse
|
||||||
import sys
|
import sys
|
||||||
import json
|
import json
|
||||||
import shutil
|
import shutil
|
||||||
import configparser
|
import configparser
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
## Config.ini configuration
|
## Config.ini configuration
|
||||||
# Unit: FPS. Please fill in according to the actual dataset frame rate,
|
# Unit: FPS. Please fill in according to the actual dataset frame rate,
|
||||||
# otherwise it will cause inaccurate matching.
|
# otherwise it will cause inaccurate matching.
|
||||||
frameRate = -1
|
frameRate = -1
|
||||||
# Unit: ms. When the timestamp range difference of a matched frame group
|
# Unit: ms. When the timestamp range difference of a matched frame group
|
||||||
# is greater than or equal to tspRangeThreshold, the file name will be marked.
|
# is greater than or equal to tspRangeThreshold, the file name will be marked.
|
||||||
tspRangeThreshold = -1
|
tspRangeThreshold = -1
|
||||||
|
|
||||||
## Parsed automatically by Python script, DO NOT modify
|
## Parsed automatically by Python script, DO NOT modify
|
||||||
primaryId = '-1' # Host ID
|
primaryId = '-1' # Host ID
|
||||||
mainPythonWorkPath = "" # Working directory of SyncFramesMain.py
|
mainPythonWorkPath = "" # Working directory of SyncFramesMain.py
|
||||||
sourceFramesPath = "" # DO NOT modify, fixed value, path to TotalMode directory
|
sourceFramesPath = "" # DO NOT modify, fixed value, path to TotalMode directory
|
||||||
sourceRootPath = "" # Root directory containing TotalMode
|
sourceRootPath = "" # Root directory containing TotalMode
|
||||||
resultPath = "" # Path to save sync analysis results
|
resultPath = "" # Path to save sync analysis results
|
||||||
streamProfileDict = dict() # Store Python results
|
streamProfileDict = dict() # Store Python results
|
||||||
|
|
||||||
class PictureInfo(object):
|
class PictureInfo(object):
|
||||||
class Struct(object):
|
class Struct(object):
|
||||||
def __init__(self, deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt):
|
def __init__(self, deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt):
|
||||||
self.deviceId = deviceId
|
self.deviceId = deviceId
|
||||||
self.sensorType = sensorType
|
self.sensorType = sensorType
|
||||||
self.syncTimeStamp = syncTimeStamp
|
self.syncTimeStamp = syncTimeStamp
|
||||||
self.picturePath = picturePath
|
self.picturePath = picturePath
|
||||||
self.deviceIdFull = deviceIdFull
|
self.deviceIdFull = deviceIdFull
|
||||||
self.fileExt = fileExt
|
self.fileExt = fileExt
|
||||||
|
|
||||||
def make_struct(self, deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt):
|
def make_struct(self, deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt):
|
||||||
return self.Struct(deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt)
|
return self.Struct(deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt)
|
||||||
|
|
||||||
class StreamProfileInfo:
|
class StreamProfileInfo:
|
||||||
def __init__(self, sensorType, width, height, format, fps):
|
def __init__(self, sensorType, width, height, format, fps):
|
||||||
self.sensorType = sensorType
|
self.sensorType = sensorType
|
||||||
self.width = width
|
self.width = width
|
||||||
self.height = height
|
self.height = height
|
||||||
self.format = format
|
self.format = format
|
||||||
self.fps = fps
|
self.fps = fps
|
||||||
|
|
||||||
def initPrimaryId():
|
def initPrimaryId():
|
||||||
global primaryId
|
global primaryId
|
||||||
|
|
||||||
deviceInfoPath = f"{sourceRootPath}/DevicesInfo.txt"
|
deviceInfoPath = f"{sourceRootPath}/DevicesInfo.txt"
|
||||||
if not os.path.exists(deviceInfoPath):
|
if not os.path.exists(deviceInfoPath):
|
||||||
print(f"Initialize primaryId failed. {deviceInfoPath} not exists")
|
print(f"Initialize primaryId failed. {deviceInfoPath} not exists")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
with open(deviceInfoPath, 'r') as f:
|
with open(deviceInfoPath, 'r') as f:
|
||||||
data = json.load(f)
|
data = json.load(f)
|
||||||
|
|
||||||
if not 'devices' in data:
|
if not 'devices' in data:
|
||||||
print(f"Initialize primaryId failed. {deviceInfoPath} not contain item 'devices'")
|
print(f"Initialize primaryId failed. {deviceInfoPath} not contain item 'devices'")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
for item in data['devices']:
|
for item in data['devices']:
|
||||||
if 'isPrimaryDevice' in item and 'index' in item and item['isPrimaryDevice']:
|
if 'isPrimaryDevice' in item and 'index' in item and item['isPrimaryDevice']:
|
||||||
primaryId = str(item['index'])
|
primaryId = str(item['index'])
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def initSyncConfigParams():
|
def initSyncConfigParams():
|
||||||
global frameRate, tspRangeThreshold
|
global frameRate, tspRangeThreshold
|
||||||
|
|
||||||
configPath = f"{mainPythonWorkPath}/Config.ini"
|
configPath = f"{mainPythonWorkPath}/Config.ini"
|
||||||
if not os.path.exists(configPath):
|
if not os.path.exists(configPath):
|
||||||
print(f"Initliaze synchronized config parameter failed. {configPath} not exists.")
|
print(f"Initliaze synchronized config parameter failed. {configPath} not exists.")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Create ConfigParser object
|
# Create ConfigParser object
|
||||||
config = configparser.ConfigParser()
|
config = configparser.ConfigParser()
|
||||||
|
|
||||||
# Read ini file
|
# Read ini file
|
||||||
config.read(configPath, 'utf-8')
|
config.read(configPath, 'utf-8')
|
||||||
|
|
||||||
if not config.has_option('Parameter', 'frameRate'):
|
if not config.has_option('Parameter', 'frameRate'):
|
||||||
print(f"Initliaze synchronized config parameter failed. Not define 'frameRate' in ${configPath}")
|
print(f"Initliaze synchronized config parameter failed. Not define 'frameRate' in ${configPath}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if not config.has_option('Parameter', 'tspRangeThreshold'):
|
if not config.has_option('Parameter', 'tspRangeThreshold'):
|
||||||
print(f"Initliaze synchronized config parameter failed. Not define 'tspRangeThreshold' in ${configPath}")
|
print(f"Initliaze synchronized config parameter failed. Not define 'tspRangeThreshold' in ${configPath}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
frameRate = config.getfloat('Parameter', 'frameRate')
|
frameRate = config.getfloat('Parameter', 'frameRate')
|
||||||
if frameRate <= 0 or frameRate >= 1000:
|
if frameRate <= 0 or frameRate >= 1000:
|
||||||
print(f"Initliaze synchronized config parameter failed. Invalid frameRate={frameRate}")
|
print(f"Initliaze synchronized config parameter failed. Invalid frameRate={frameRate}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
tspRangeThreshold = config.getfloat('Parameter', 'tspRangeThreshold')
|
tspRangeThreshold = config.getfloat('Parameter', 'tspRangeThreshold')
|
||||||
if tspRangeThreshold <= 0:
|
if tspRangeThreshold <= 0:
|
||||||
print(f"Initliaze synchronized config parameter failed. Invalid tspRangeThreshold={tspRangeThreshold}")
|
print(f"Initliaze synchronized config parameter failed. Invalid tspRangeThreshold={tspRangeThreshold}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def getDeviceCount():
|
def getDeviceCount():
|
||||||
deviceInfoPath = f"{sourceRootPath}/DevicesInfo.txt"
|
deviceInfoPath = f"{sourceRootPath}/DevicesInfo.txt"
|
||||||
if not os.path.exists(deviceInfoPath):
|
if not os.path.exists(deviceInfoPath):
|
||||||
print(f"Get device count failed. {deviceInfoPath} not exists")
|
print(f"Get device count failed. {deviceInfoPath} not exists")
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
with open(deviceInfoPath, 'r') as f:
|
with open(deviceInfoPath, 'r') as f:
|
||||||
data = json.load(f)
|
data = json.load(f)
|
||||||
|
|
||||||
if not 'devices' in data:
|
if not 'devices' in data:
|
||||||
print(f"Get device count failed. {deviceInfoPath} not contain item 'devices'")
|
print(f"Get device count failed. {deviceInfoPath} not contain item 'devices'")
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
return len(data['devices'])
|
return len(data['devices'])
|
||||||
|
|
||||||
def initProfileInfoDict():
|
def initProfileInfoDict():
|
||||||
global streamProfileDict
|
global streamProfileDict
|
||||||
|
|
||||||
streamProfileDict = dict()
|
streamProfileDict = dict()
|
||||||
profilePath = f"{sourceRootPath}/StreamProfileInfo.txt"
|
profilePath = f"{sourceRootPath}/StreamProfileInfo.txt"
|
||||||
if not os.path.exists(profilePath):
|
if not os.path.exists(profilePath):
|
||||||
print(f"Initialize profile information dictionary failed. {profilePath} not exists")
|
print(f"Initialize profile information dictionary failed. {profilePath} not exists")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
with open(profilePath, 'r') as f:
|
with open(profilePath, 'r') as f:
|
||||||
data = json.load(f)
|
data = json.load(f)
|
||||||
|
|
||||||
if not 'streamProfiles' in data:
|
if not 'streamProfiles' in data:
|
||||||
print(f"Initialize profile information dictionary failed. {profilePath} not contain item 'streamProfiles'")
|
print(f"Initialize profile information dictionary failed. {profilePath} not contain item 'streamProfiles'")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
for item in data['streamProfiles']:
|
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:
|
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'])
|
profileInfo = StreamProfileInfo(item['sensorType'], item['width'], item['height'], item['format'], item['fps'])
|
||||||
streamProfileDict.setdefault(item['sensorType'], profileInfo)
|
streamProfileDict.setdefault(item['sensorType'], profileInfo)
|
||||||
else:
|
else:
|
||||||
print(f"Initialize profile information dictionary. Error invalid StreamProfile, {item}")
|
print(f"Initialize profile information dictionary. Error invalid StreamProfile, {item}")
|
||||||
|
|
||||||
return len(streamProfileDict.items()) > 0
|
return len(streamProfileDict.items()) > 0
|
||||||
|
|
||||||
def initResultDir():
|
def initResultDir():
|
||||||
global resultPath
|
global resultPath
|
||||||
timeText = datetime.now().strftime("%Y-%m-%d_%H%M%S")
|
timeText = datetime.now().strftime("%Y-%m-%d_%H%M%S")
|
||||||
resultPath = f"{sourceRootPath}/results-{timeText}"
|
resultPath = f"{sourceRootPath}/results-{timeText}"
|
||||||
if not os.path.exists(resultPath):
|
if not os.path.exists(resultPath):
|
||||||
os.makedirs(resultPath)
|
os.makedirs(resultPath)
|
||||||
|
|
||||||
def isFrameFile(fileName):
|
def isFrameFile(fileName):
|
||||||
fileExt = os.path.splitext(fileName)
|
fileExt = os.path.splitext(fileName)
|
||||||
if len(fileExt) < 2:
|
if len(fileExt) < 2:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
frameExts = {".jpeg", ".jpg", ".png", ".raw", "bmp"}
|
frameExts = {".jpeg", ".jpg", ".png", ".raw", "bmp"}
|
||||||
return fileExt[1] in frameExts
|
return fileExt[1] in frameExts
|
||||||
|
|
||||||
def initPictureInfoDictionary(rootFilePath, pictureInfoDict):
|
def initPictureInfoDictionary(rootFilePath, pictureInfoDict):
|
||||||
frameFileCount = 0
|
frameFileCount = 0
|
||||||
for dirpath, dirnames, filenames in os.walk(rootFilePath):
|
for dirpath, dirnames, filenames in os.walk(rootFilePath):
|
||||||
# print(f"dirpath={dirpath}, dirpath.basename=" + os.path.basename(dirpath))
|
# print(f"dirpath={dirpath}, dirpath.basename=" + os.path.basename(dirpath))
|
||||||
for fileName in filenames:
|
for fileName in filenames:
|
||||||
filePath = os.path.join(dirpath, fileName)
|
filePath = os.path.join(dirpath, fileName)
|
||||||
if not isFrameFile(fileName):
|
if not isFrameFile(fileName):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
frameFileCount += 1
|
frameFileCount += 1
|
||||||
fileNameNoExt = os.path.splitext(fileName)[0]
|
fileNameNoExt = os.path.splitext(fileName)[0]
|
||||||
pictureNameList = fileNameNoExt.split('_')
|
pictureNameList = fileNameNoExt.split('_')
|
||||||
deviceId = pictureNameList[2][5:]
|
deviceId = pictureNameList[2][5:]
|
||||||
sensorType = pictureNameList[0].replace('#', '_')
|
sensorType = pictureNameList[0].replace('#', '_')
|
||||||
syncTimeStamp = int(pictureNameList[5][1:])
|
syncTimeStamp = int(pictureNameList[5][1:])
|
||||||
|
|
||||||
# Create struct
|
# Create struct
|
||||||
pictureInfo = PictureInfo()
|
pictureInfo = PictureInfo()
|
||||||
info = pictureInfo.make_struct(deviceId, sensorType, syncTimeStamp, filePath, os.path.basename(dirpath), os.path.splitext(fileName)[1])
|
info = pictureInfo.make_struct(deviceId, sensorType, syncTimeStamp, filePath, os.path.basename(dirpath), os.path.splitext(fileName)[1])
|
||||||
|
|
||||||
# Format dictionary: one key corresponds to one array
|
# Format dictionary: one key corresponds to one array
|
||||||
pictureInfoDict.setdefault(deviceId, []).append(info)
|
pictureInfoDict.setdefault(deviceId, []).append(info)
|
||||||
|
|
||||||
if 0 == frameFileCount:
|
if 0 == frameFileCount:
|
||||||
print("initialize pictureInfoDict failed. Not found frame file")
|
print("initialize pictureInfoDict failed. Not found frame file")
|
||||||
|
|
||||||
|
|
||||||
def matchFrame(pictureInfoDict):
|
def matchFrame(pictureInfoDict):
|
||||||
global primaryId, frameRate
|
global primaryId, frameRate
|
||||||
global streamProfileDict
|
global streamProfileDict
|
||||||
|
|
||||||
# Get comparison image array, take the Color array of the first device for comparison
|
# Get comparison image array, take the Color array of the first device for comparison
|
||||||
compareList = []
|
compareList = []
|
||||||
for key in pictureInfoDict:
|
for key in pictureInfoDict:
|
||||||
listTmp = list(pictureInfoDict[key])
|
listTmp = list(pictureInfoDict[key])
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
if info.deviceId == primaryId and info.sensorType == 'color':
|
if info.deviceId == primaryId and info.sensorType == 'color':
|
||||||
compareList.append(info)
|
compareList.append(info)
|
||||||
|
|
||||||
# Dynamically analyze based on stream opening status to reduce loop iterations
|
# Dynamically analyze based on stream opening status to reduce loop iterations
|
||||||
hasColorProfile = 'OB_SENSOR_COLOR' in streamProfileDict
|
hasColorProfile = 'OB_SENSOR_COLOR' in streamProfileDict
|
||||||
hasDepthProfile = 'OB_SENSOR_DEPTH' in streamProfileDict
|
hasDepthProfile = 'OB_SENSOR_DEPTH' in streamProfileDict
|
||||||
hasIRProfile = 'OB_SENSOR_IR' in streamProfileDict
|
hasIRProfile = 'OB_SENSOR_IR' in streamProfileDict
|
||||||
hasIRLeftProfile = 'OB_SENSOR_IR_LEFT' in streamProfileDict
|
hasIRLeftProfile = 'OB_SENSOR_IR_LEFT' in streamProfileDict
|
||||||
hasIRRightProfile = 'OB_SENSOR_IR_RIGHT' in streamProfileDict
|
hasIRRightProfile = 'OB_SENSOR_IR_RIGHT' in streamProfileDict
|
||||||
|
|
||||||
# Match adjacent frames
|
# Match adjacent frames
|
||||||
resultDict = {}
|
resultDict = {}
|
||||||
consumedList = []
|
consumedList = []
|
||||||
dictIndex = 0
|
dictIndex = 0
|
||||||
frameTspHalfGap = int(1000.0/frameRate/2.0+0.5)
|
frameTspHalfGap = int(1000.0/frameRate/2.0+0.5)
|
||||||
for comparePic in compareList:
|
for comparePic in compareList:
|
||||||
resultDict.setdefault(dictIndex, []).append(comparePic)
|
resultDict.setdefault(dictIndex, []).append(comparePic)
|
||||||
for key in pictureInfoDict:
|
for key in pictureInfoDict:
|
||||||
listTmp = list(pictureInfoDict[key])
|
listTmp = list(pictureInfoDict[key])
|
||||||
# Compare Color
|
# Compare Color
|
||||||
if hasColorProfile:
|
if hasColorProfile:
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info in consumedList:
|
if info in consumedList:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info.sensorType == 'color' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
|
if info.sensorType == 'color' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
|
||||||
resultDict.setdefault(dictIndex, []).append(info)
|
resultDict.setdefault(dictIndex, []).append(info)
|
||||||
consumedList.append(info)
|
consumedList.append(info)
|
||||||
break
|
break
|
||||||
|
|
||||||
# Compare Depth
|
# Compare Depth
|
||||||
if hasDepthProfile:
|
if hasDepthProfile:
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info in consumedList:
|
if info in consumedList:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info.sensorType == 'depth' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
|
if info.sensorType == 'depth' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
|
||||||
resultDict.setdefault(dictIndex, []).append(info)
|
resultDict.setdefault(dictIndex, []).append(info)
|
||||||
consumedList.append(info)
|
consumedList.append(info)
|
||||||
break
|
break
|
||||||
|
|
||||||
# IR
|
# IR
|
||||||
if hasIRProfile:
|
if hasIRProfile:
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info in consumedList:
|
if info in consumedList:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info.sensorType == 'ir' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
|
if info.sensorType == 'ir' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
|
||||||
resultDict.setdefault(dictIndex, []).append(info)
|
resultDict.setdefault(dictIndex, []).append(info)
|
||||||
consumedList.append(info)
|
consumedList.append(info)
|
||||||
break
|
break
|
||||||
|
|
||||||
# Left IR
|
# Left IR
|
||||||
if hasIRLeftProfile:
|
if hasIRLeftProfile:
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info in consumedList:
|
if info in consumedList:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info.sensorType == 'ir_left' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
|
if info.sensorType == 'ir_left' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
|
||||||
resultDict.setdefault(dictIndex, []).append(info)
|
resultDict.setdefault(dictIndex, []).append(info)
|
||||||
consumedList.append(info)
|
consumedList.append(info)
|
||||||
break
|
break
|
||||||
|
|
||||||
# Right IR
|
# Right IR
|
||||||
if hasIRRightProfile:
|
if hasIRRightProfile:
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info in consumedList:
|
if info in consumedList:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info.sensorType == 'ir_right' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
|
if info.sensorType == 'ir_right' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
|
||||||
resultDict.setdefault(dictIndex, []).append(info)
|
resultDict.setdefault(dictIndex, []).append(info)
|
||||||
consumedList.append(info)
|
consumedList.append(info)
|
||||||
break
|
break
|
||||||
|
|
||||||
# Calculate deviation
|
# Calculate deviation
|
||||||
minTsp = min(resultDict[dictIndex], key=lambda x: x.syncTimeStamp)
|
minTsp = min(resultDict[dictIndex], key=lambda x: x.syncTimeStamp)
|
||||||
for info in resultDict[dictIndex]:
|
for info in resultDict[dictIndex]:
|
||||||
info.tspDiff = info.syncTimeStamp - minTsp.syncTimeStamp
|
info.tspDiff = info.syncTimeStamp - minTsp.syncTimeStamp
|
||||||
|
|
||||||
dictIndex += 1
|
dictIndex += 1
|
||||||
|
|
||||||
return resultDict
|
return resultDict
|
||||||
|
|
||||||
|
|
||||||
def safe_make_dir(path):
|
def safe_make_dir(path):
|
||||||
if not os.path.exists(path):
|
if not os.path.exists(path):
|
||||||
os.makedirs(path)
|
os.makedirs(path)
|
||||||
|
|
||||||
|
|
||||||
def handleSyncFrames():
|
def handleSyncFrames():
|
||||||
global resultPath
|
global resultPath
|
||||||
global sourceFramesPath
|
global sourceFramesPath
|
||||||
global streamProfileDict
|
global streamProfileDict
|
||||||
|
|
||||||
fp = open(f"{resultPath}/frameMatchLog.txt", "w")
|
fp = open(f"{resultPath}/frameMatchLog.txt", "w")
|
||||||
|
|
||||||
if not initProfileInfoDict():
|
if not initProfileInfoDict():
|
||||||
print("Initialize stream profile dictionary failed. exit")
|
print("Initialize stream profile dictionary failed. exit")
|
||||||
return
|
return
|
||||||
print(f"Stream profiles: {streamProfileDict}")
|
print(f"Stream profiles: {streamProfileDict}")
|
||||||
streamProfileCount = len(streamProfileDict.items())
|
streamProfileCount = len(streamProfileDict.items())
|
||||||
|
|
||||||
pictureInfoDict = {}
|
pictureInfoDict = {}
|
||||||
|
|
||||||
initPictureInfoDictionary(Path(sourceFramesPath), pictureInfoDict)
|
initPictureInfoDictionary(Path(sourceFramesPath), pictureInfoDict)
|
||||||
if len(pictureInfoDict) <= 0:
|
if len(pictureInfoDict) <= 0:
|
||||||
print("init pictureInfoDict failed. pictureInfoDict.len = 0")
|
print("init pictureInfoDict failed. pictureInfoDict.len = 0")
|
||||||
return
|
return
|
||||||
|
|
||||||
deviceCount = getDeviceCount()
|
deviceCount = getDeviceCount()
|
||||||
print("=================device count:%d" % deviceCount)
|
print("=================device count:%d" % deviceCount)
|
||||||
|
|
||||||
resultDict = {}
|
resultDict = {}
|
||||||
resultDict = matchFrame(pictureInfoDict)
|
resultDict = matchFrame(pictureInfoDict)
|
||||||
|
|
||||||
for key in resultDict:
|
for key in resultDict:
|
||||||
fp.write("===================result key:%s\n" % key)
|
fp.write("===================result key:%s\n" % key)
|
||||||
print("===================result key:%s" % key)
|
print("===================result key:%s" % key)
|
||||||
listTmp = list(resultDict[key])
|
listTmp = list(resultDict[key])
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
fp.write("=====================result value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s\n" % (
|
fp.write("=====================result value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s\n" % (
|
||||||
info.deviceId, info.sensorType, info.syncTimeStamp, info.picturePath))
|
info.deviceId, info.sensorType, info.syncTimeStamp, info.picturePath))
|
||||||
print("=====================result value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s" % (
|
print("=====================result value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s" % (
|
||||||
info.deviceId, info.sensorType, info.syncTimeStamp, info.picturePath))
|
info.deviceId, info.sensorType, info.syncTimeStamp, info.picturePath))
|
||||||
|
|
||||||
matchPath = f"{resultPath}/matchFrames/"
|
matchPath = f"{resultPath}/matchFrames/"
|
||||||
safe_make_dir(matchPath)
|
safe_make_dir(matchPath)
|
||||||
notMatchPath = f"{resultPath}/notMatchFrames/"
|
notMatchPath = f"{resultPath}/notMatchFrames/"
|
||||||
abnormalPath = f"{resultPath}/abnormal/"
|
abnormalPath = f"{resultPath}/abnormal/"
|
||||||
|
|
||||||
for key in resultDict:
|
for key in resultDict:
|
||||||
listTmp = list(resultDict[key])
|
listTmp = list(resultDict[key])
|
||||||
if (len(listTmp) == (deviceCount * streamProfileCount)):
|
if (len(listTmp) == (deviceCount * streamProfileCount)):
|
||||||
haveAbnormalData = False
|
haveAbnormalData = False
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
if info.tspDiff >= tspRangeThreshold:
|
if info.tspDiff >= tspRangeThreshold:
|
||||||
path = matchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
path = matchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
||||||
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + "_xxxxxx" + info.fileExt
|
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + "_xxxxxx" + info.fileExt
|
||||||
shutil.copy(info.picturePath, path)
|
shutil.copy(info.picturePath, path)
|
||||||
haveAbnormalData = True
|
haveAbnormalData = True
|
||||||
else:
|
else:
|
||||||
path = matchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
path = matchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
||||||
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + info.fileExt
|
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + info.fileExt
|
||||||
shutil.copy(info.picturePath, path)
|
shutil.copy(info.picturePath, path)
|
||||||
|
|
||||||
if haveAbnormalData:
|
if haveAbnormalData:
|
||||||
safe_make_dir(abnormalPath)
|
safe_make_dir(abnormalPath)
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
if info.tspDiff >= tspRangeThreshold:
|
if info.tspDiff >= tspRangeThreshold:
|
||||||
path = abnormalPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
path = abnormalPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
||||||
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + "_xxxxxx" + info.fileExt
|
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + "_xxxxxx" + info.fileExt
|
||||||
shutil.copy(info.picturePath, path)
|
shutil.copy(info.picturePath, path)
|
||||||
else:
|
else:
|
||||||
path = abnormalPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
path = abnormalPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
||||||
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + info.fileExt
|
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + info.fileExt
|
||||||
shutil.copy(info.picturePath, path)
|
shutil.copy(info.picturePath, path)
|
||||||
else:
|
else:
|
||||||
safe_make_dir(notMatchPath)
|
safe_make_dir(notMatchPath)
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
newFilePath = notMatchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
newFilePath = notMatchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
||||||
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + info.fileExt
|
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + info.fileExt
|
||||||
shutil.copy(info.picturePath, newFilePath)
|
shutil.copy(info.picturePath, newFilePath)
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
if not initPrimaryId():
|
if not initPrimaryId():
|
||||||
print("Initialize primaryId failed. exit.")
|
print("Initialize primaryId failed. exit.")
|
||||||
return
|
return
|
||||||
|
|
||||||
if not initSyncConfigParams():
|
if not initSyncConfigParams():
|
||||||
print("Initialized Sync config parameter failed. exit.")
|
print("Initialized Sync config parameter failed. exit.")
|
||||||
return
|
return
|
||||||
|
|
||||||
initResultDir()
|
initResultDir()
|
||||||
|
|
||||||
print(f"PrimaryId={primaryId}, frameRate={frameRate}, tspRangeThreshold={tspRangeThreshold}")
|
print(f"PrimaryId={primaryId}, frameRate={frameRate}, tspRangeThreshold={tspRangeThreshold}")
|
||||||
handleSyncFrames()
|
handleSyncFrames()
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
parser = argparse.ArgumentParser(description="Synchronize frames support for 'Orbbec Gemini 2'")
|
parser = argparse.ArgumentParser(description="Synchronize frames support for 'Orbbec Gemini 2'")
|
||||||
parser.add_argument('frames_dir', type=str, help="Frames directory")
|
parser.add_argument('frames_dir', type=str, help="Frames directory")
|
||||||
parser.add_argument('main_script_root_dir', type=str, help="SyncFramesMain.py working directory")
|
parser.add_argument('main_script_root_dir', type=str, help="SyncFramesMain.py working directory")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
sourceRootPath = args.frames_dir
|
sourceRootPath = args.frames_dir
|
||||||
sourceFramesPath = f"{args.frames_dir}/TotalModeFrames"
|
sourceFramesPath = f"{args.frames_dir}/TotalModeFrames"
|
||||||
mainPythonWorkPath = args.main_script_root_dir
|
mainPythonWorkPath = args.main_script_root_dir
|
||||||
print(f"Start of Gemini2 synchronize frame. sourceRootPath={sourceRootPath}")
|
print(f"Start of Gemini2 synchronize frame. sourceRootPath={sourceRootPath}")
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|
||||||
print("Finish of Gemini2 synchronize frame.")
|
print("Finish of Gemini2 synchronize frame.")
|
||||||
|
|||||||
+425
-425
@@ -1,425 +1,425 @@
|
|||||||
import os.path
|
import os.path
|
||||||
import argparse
|
import argparse
|
||||||
import sys
|
import sys
|
||||||
import json
|
import json
|
||||||
import shutil
|
import shutil
|
||||||
import configparser
|
import configparser
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
|
||||||
## Config.ini configuration
|
## Config.ini configuration
|
||||||
# Unit: FPS. Please fill in according to the actual dataset frame rate,
|
# Unit: FPS. Please fill in according to the actual dataset frame rate,
|
||||||
# otherwise it will cause inaccurate matching.
|
# otherwise it will cause inaccurate matching.
|
||||||
frameRate = -1
|
frameRate = -1
|
||||||
# Unit: ms. When the timestamp range difference of a matched frame group
|
# Unit: ms. When the timestamp range difference of a matched frame group
|
||||||
# is greater than or equal to tspRangeThreshold, the file name will be marked.
|
# is greater than or equal to tspRangeThreshold, the file name will be marked.
|
||||||
tspRangeThreshold = -1
|
tspRangeThreshold = -1
|
||||||
|
|
||||||
## Parsed automatically by Python script, DO NOT modify
|
## Parsed automatically by Python script, DO NOT modify
|
||||||
primaryId = '-1' # Host ID
|
primaryId = '-1' # Host ID
|
||||||
mainPythonWorkPath = "" # Working directory of SyncFramesMain.py
|
mainPythonWorkPath = "" # Working directory of SyncFramesMain.py
|
||||||
sourceFramesPath = "" # DO NOT modify, fixed value, path to TotalMode directory
|
sourceFramesPath = "" # DO NOT modify, fixed value, path to TotalMode directory
|
||||||
sourceRootPath = "" # Root directory containing TotalMode
|
sourceRootPath = "" # Root directory containing TotalMode
|
||||||
resultPath = "" # Path to save sync analysis results
|
resultPath = "" # Path to save sync analysis results
|
||||||
streamProfileDict = dict() # Store Python results
|
streamProfileDict = dict() # Store Python results
|
||||||
|
|
||||||
class PictureInfo(object):
|
class PictureInfo(object):
|
||||||
class Struct(object):
|
class Struct(object):
|
||||||
def __init__(self, deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt):
|
def __init__(self, deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt):
|
||||||
self.deviceId = deviceId
|
self.deviceId = deviceId
|
||||||
self.sensorType = sensorType
|
self.sensorType = sensorType
|
||||||
self.syncTimeStamp = syncTimeStamp
|
self.syncTimeStamp = syncTimeStamp
|
||||||
self.picturePath = picturePath
|
self.picturePath = picturePath
|
||||||
self.deviceIdFull = deviceIdFull
|
self.deviceIdFull = deviceIdFull
|
||||||
self.fileExt = fileExt
|
self.fileExt = fileExt
|
||||||
|
|
||||||
def make_struct(self, deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt):
|
def make_struct(self, deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt):
|
||||||
return self.Struct(deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt)
|
return self.Struct(deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt)
|
||||||
|
|
||||||
class StreamProfileInfo:
|
class StreamProfileInfo:
|
||||||
def __init__(self, sensorType, width, height, format, fps):
|
def __init__(self, sensorType, width, height, format, fps):
|
||||||
self.sensorType = sensorType
|
self.sensorType = sensorType
|
||||||
self.width = width
|
self.width = width
|
||||||
self.height = height
|
self.height = height
|
||||||
self.format = format
|
self.format = format
|
||||||
self.fps = fps
|
self.fps = fps
|
||||||
|
|
||||||
def initPrimaryId():
|
def initPrimaryId():
|
||||||
global primaryId
|
global primaryId
|
||||||
|
|
||||||
deviceInfoPath = f"{sourceRootPath}/DevicesInfo.txt"
|
deviceInfoPath = f"{sourceRootPath}/DevicesInfo.txt"
|
||||||
if not os.path.exists(deviceInfoPath):
|
if not os.path.exists(deviceInfoPath):
|
||||||
print(f"Initialize primaryId failed. {deviceInfoPath} not exists")
|
print(f"Initialize primaryId failed. {deviceInfoPath} not exists")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
with open(deviceInfoPath, 'r') as f:
|
with open(deviceInfoPath, 'r') as f:
|
||||||
data = json.load(f)
|
data = json.load(f)
|
||||||
|
|
||||||
if not 'devices' in data:
|
if not 'devices' in data:
|
||||||
print(f"Initialize primaryId failed. {deviceInfoPath} not contain item 'devices'")
|
print(f"Initialize primaryId failed. {deviceInfoPath} not contain item 'devices'")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
for item in data['devices']:
|
for item in data['devices']:
|
||||||
if 'isPrimaryDevice' in item and 'index' in item and item['isPrimaryDevice']:
|
if 'isPrimaryDevice' in item and 'index' in item and item['isPrimaryDevice']:
|
||||||
primaryId = str(item['index'])
|
primaryId = str(item['index'])
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def initSyncConfigParams():
|
def initSyncConfigParams():
|
||||||
global frameRate, tspRangeThreshold
|
global frameRate, tspRangeThreshold
|
||||||
|
|
||||||
configPath = f"{mainPythonWorkPath}/Config.ini"
|
configPath = f"{mainPythonWorkPath}/Config.ini"
|
||||||
if not os.path.exists(configPath):
|
if not os.path.exists(configPath):
|
||||||
print(f"Initliaze synchronized config parameter failed. {configPath} not exists.")
|
print(f"Initliaze synchronized config parameter failed. {configPath} not exists.")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Create ConfigParser object
|
# Create ConfigParser object
|
||||||
config = configparser.ConfigParser()
|
config = configparser.ConfigParser()
|
||||||
|
|
||||||
# Read ini file
|
# Read ini file
|
||||||
config.read(configPath, 'utf-8')
|
config.read(configPath, 'utf-8')
|
||||||
|
|
||||||
if not config.has_option('Parameter', 'frameRate'):
|
if not config.has_option('Parameter', 'frameRate'):
|
||||||
print(f"Initliaze synchronized config parameter failed. Not define 'frameRate' in ${configPath}")
|
print(f"Initliaze synchronized config parameter failed. Not define 'frameRate' in ${configPath}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if not config.has_option('Parameter', 'tspRangeThreshold'):
|
if not config.has_option('Parameter', 'tspRangeThreshold'):
|
||||||
print(f"Initliaze synchronized config parameter failed. Not define 'tspRangeThreshold' in ${configPath}")
|
print(f"Initliaze synchronized config parameter failed. Not define 'tspRangeThreshold' in ${configPath}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
frameRate = config.getfloat('Parameter', 'frameRate')
|
frameRate = config.getfloat('Parameter', 'frameRate')
|
||||||
if frameRate <= 0 or frameRate >= 1000:
|
if frameRate <= 0 or frameRate >= 1000:
|
||||||
print(f"Initliaze synchronized config parameter failed. Invalid frameRate={frameRate}")
|
print(f"Initliaze synchronized config parameter failed. Invalid frameRate={frameRate}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
tspRangeThreshold = config.getfloat('Parameter', 'tspRangeThreshold')
|
tspRangeThreshold = config.getfloat('Parameter', 'tspRangeThreshold')
|
||||||
if tspRangeThreshold <= 0:
|
if tspRangeThreshold <= 0:
|
||||||
print(f"Initliaze synchronized config parameter failed. Invalid tspRangeThreshold={tspRangeThreshold}")
|
print(f"Initliaze synchronized config parameter failed. Invalid tspRangeThreshold={tspRangeThreshold}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def getDeviceCount():
|
def getDeviceCount():
|
||||||
deviceInfoPath = f"{sourceRootPath}/DevicesInfo.txt"
|
deviceInfoPath = f"{sourceRootPath}/DevicesInfo.txt"
|
||||||
if not os.path.exists(deviceInfoPath):
|
if not os.path.exists(deviceInfoPath):
|
||||||
print(f"Get device count failed. {deviceInfoPath} not exists")
|
print(f"Get device count failed. {deviceInfoPath} not exists")
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
with open(deviceInfoPath, 'r') as f:
|
with open(deviceInfoPath, 'r') as f:
|
||||||
data = json.load(f)
|
data = json.load(f)
|
||||||
|
|
||||||
if not 'devices' in data:
|
if not 'devices' in data:
|
||||||
print(f"Get device count failed. {deviceInfoPath} not contain item 'devices'")
|
print(f"Get device count failed. {deviceInfoPath} not contain item 'devices'")
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
return len(data['devices'])
|
return len(data['devices'])
|
||||||
|
|
||||||
def initProfileInfoDict():
|
def initProfileInfoDict():
|
||||||
global streamProfileDict
|
global streamProfileDict
|
||||||
|
|
||||||
streamProfileDict = dict()
|
streamProfileDict = dict()
|
||||||
profilePath = f"{sourceRootPath}/StreamProfileInfo.txt"
|
profilePath = f"{sourceRootPath}/StreamProfileInfo.txt"
|
||||||
if not os.path.exists(profilePath):
|
if not os.path.exists(profilePath):
|
||||||
print(f"Initialize profile information dictionary failed. {profilePath} not exists")
|
print(f"Initialize profile information dictionary failed. {profilePath} not exists")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
with open(profilePath, 'r') as f:
|
with open(profilePath, 'r') as f:
|
||||||
data = json.load(f)
|
data = json.load(f)
|
||||||
|
|
||||||
if not 'streamProfiles' in data:
|
if not 'streamProfiles' in data:
|
||||||
print(f"Initialize profile information dictionary failed. {profilePath} not contain item 'streamProfiles'")
|
print(f"Initialize profile information dictionary failed. {profilePath} not contain item 'streamProfiles'")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
for item in data['streamProfiles']:
|
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:
|
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'])
|
profileInfo = StreamProfileInfo(item['sensorType'], item['width'], item['height'], item['format'], item['fps'])
|
||||||
streamProfileDict.setdefault(item['sensorType'], profileInfo)
|
streamProfileDict.setdefault(item['sensorType'], profileInfo)
|
||||||
else:
|
else:
|
||||||
print(f"Initialize profile information dictionary. Error invalid StreamProfile, {item}")
|
print(f"Initialize profile information dictionary. Error invalid StreamProfile, {item}")
|
||||||
|
|
||||||
return len(streamProfileDict.items()) > 0
|
return len(streamProfileDict.items()) > 0
|
||||||
|
|
||||||
def initResultDir():
|
def initResultDir():
|
||||||
global resultPath
|
global resultPath
|
||||||
timeText = datetime.now().strftime("%Y-%m-%d_%H%M%S")
|
timeText = datetime.now().strftime("%Y-%m-%d_%H%M%S")
|
||||||
resultPath = f"{sourceRootPath}/results-{timeText}"
|
resultPath = f"{sourceRootPath}/results-{timeText}"
|
||||||
if not os.path.exists(resultPath):
|
if not os.path.exists(resultPath):
|
||||||
os.makedirs(resultPath)
|
os.makedirs(resultPath)
|
||||||
|
|
||||||
def isFrameFile(fileName):
|
def isFrameFile(fileName):
|
||||||
fileExt = os.path.splitext(fileName)
|
fileExt = os.path.splitext(fileName)
|
||||||
if len(fileExt) < 2:
|
if len(fileExt) < 2:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
frameExts = {".jpeg", ".jpg", ".png", ".raw", "bmp"}
|
frameExts = {".jpeg", ".jpg", ".png", ".raw", "bmp"}
|
||||||
return fileExt[1] in frameExts
|
return fileExt[1] in frameExts
|
||||||
|
|
||||||
def extract_number(filename):
|
def extract_number(filename):
|
||||||
"""Extract the numeric part after 'g' in the filename"""
|
"""Extract the numeric part after 'g' in the filename"""
|
||||||
match_g = re.search(r'g(\d+)', filename)
|
match_g = re.search(r'g(\d+)', filename)
|
||||||
if match_g:
|
if match_g:
|
||||||
return int(match_g.group(1))
|
return int(match_g.group(1))
|
||||||
|
|
||||||
"""Extract the numeric part after 'd' in the filename"""
|
"""Extract the numeric part after 'd' in the filename"""
|
||||||
match_d = re.search(r'd(\d+)', filename)
|
match_d = re.search(r'd(\d+)', filename)
|
||||||
if match_d:
|
if match_d:
|
||||||
return int(match_d.group(1))
|
return int(match_d.group(1))
|
||||||
return float('inf')
|
return float('inf')
|
||||||
|
|
||||||
def initPictureInfoDictionary(rootFilePath, pictureInfoDict):
|
def initPictureInfoDictionary(rootFilePath, pictureInfoDict):
|
||||||
frameFileCount = 0
|
frameFileCount = 0
|
||||||
for dirpath, dirnames, filenames in os.walk(rootFilePath):
|
for dirpath, dirnames, filenames in os.walk(rootFilePath):
|
||||||
filenames.sort(key=extract_number) # Sort filenames by the numeric part after 'd' and 'g'
|
filenames.sort(key=extract_number) # Sort filenames by the numeric part after 'd' and 'g'
|
||||||
for fileName in filenames:
|
for fileName in filenames:
|
||||||
filePath = os.path.join(dirpath, fileName)
|
filePath = os.path.join(dirpath, fileName)
|
||||||
if not isFrameFile(fileName):
|
if not isFrameFile(fileName):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
frameFileCount += 1
|
frameFileCount += 1
|
||||||
fileNameNoExt = os.path.splitext(fileName)[0]
|
fileNameNoExt = os.path.splitext(fileName)[0]
|
||||||
pictureNameList = fileNameNoExt.split('_')
|
pictureNameList = fileNameNoExt.split('_')
|
||||||
deviceId = pictureNameList[2][5:]
|
deviceId = pictureNameList[2][5:]
|
||||||
sensorType = pictureNameList[0].replace('#', '_')
|
sensorType = pictureNameList[0].replace('#', '_')
|
||||||
syncTimeStamp = int(pictureNameList[3][1:])
|
syncTimeStamp = int(pictureNameList[3][1:])
|
||||||
|
|
||||||
# Create struct
|
# Create struct
|
||||||
pictureInfo = PictureInfo()
|
pictureInfo = PictureInfo()
|
||||||
info = pictureInfo.make_struct(deviceId, sensorType, syncTimeStamp, filePath, os.path.basename(dirpath), os.path.splitext(fileName)[1])
|
info = pictureInfo.make_struct(deviceId, sensorType, syncTimeStamp, filePath, os.path.basename(dirpath), os.path.splitext(fileName)[1])
|
||||||
|
|
||||||
# Format dictionary: one key corresponds to one array
|
# Format dictionary: one key corresponds to one array
|
||||||
pictureInfoDict.setdefault(deviceId, []).append(info)
|
pictureInfoDict.setdefault(deviceId, []).append(info)
|
||||||
|
|
||||||
if 0 == frameFileCount:
|
if 0 == frameFileCount:
|
||||||
print("initialize pictureInfoDict failed. Not found frame file")
|
print("initialize pictureInfoDict failed. Not found frame file")
|
||||||
|
|
||||||
|
|
||||||
def matchFrame(pictureInfoDict):
|
def matchFrame(pictureInfoDict):
|
||||||
global primaryId, frameRate
|
global primaryId, frameRate
|
||||||
global streamProfileDict
|
global streamProfileDict
|
||||||
|
|
||||||
# Get comparison image array, use the Color array of the first device for comparison
|
# Get comparison image array, use the Color array of the first device for comparison
|
||||||
compareList = []
|
compareList = []
|
||||||
for key in pictureInfoDict:
|
for key in pictureInfoDict:
|
||||||
listTmp = list(pictureInfoDict[key])
|
listTmp = list(pictureInfoDict[key])
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
if info.deviceId == primaryId and info.sensorType == 'color':
|
if info.deviceId == primaryId and info.sensorType == 'color':
|
||||||
compareList.append(info)
|
compareList.append(info)
|
||||||
|
|
||||||
# Dynamically analyze based on stream opening status to reduce loop iterations
|
# Dynamically analyze based on stream opening status to reduce loop iterations
|
||||||
hasColorProfile = 'OB_SENSOR_COLOR' in streamProfileDict
|
hasColorProfile = 'OB_SENSOR_COLOR' in streamProfileDict
|
||||||
hasDepthProfile = 'OB_SENSOR_DEPTH' in streamProfileDict
|
hasDepthProfile = 'OB_SENSOR_DEPTH' in streamProfileDict
|
||||||
hasIRProfile = 'OB_SENSOR_IR' in streamProfileDict
|
hasIRProfile = 'OB_SENSOR_IR' in streamProfileDict
|
||||||
hasIRLeftProfile = 'OB_SENSOR_IR_LEFT' in streamProfileDict
|
hasIRLeftProfile = 'OB_SENSOR_IR_LEFT' in streamProfileDict
|
||||||
hasIRRightProfile = 'OB_SENSOR_IR_RIGHT' in streamProfileDict
|
hasIRRightProfile = 'OB_SENSOR_IR_RIGHT' in streamProfileDict
|
||||||
|
|
||||||
# Match adjacent frames
|
# Match adjacent frames
|
||||||
resultDict = {}
|
resultDict = {}
|
||||||
consumedList = []
|
consumedList = []
|
||||||
dictIndex = 0
|
dictIndex = 0
|
||||||
frameTspHalfGap = int(1000.0/frameRate/2.0+0.5)
|
frameTspHalfGap = int(1000.0/frameRate/2.0+0.5)
|
||||||
for comparePic in compareList:
|
for comparePic in compareList:
|
||||||
resultDict.setdefault(dictIndex, []).append(comparePic)
|
resultDict.setdefault(dictIndex, []).append(comparePic)
|
||||||
for key in pictureInfoDict:
|
for key in pictureInfoDict:
|
||||||
listTmp = list(pictureInfoDict[key])
|
listTmp = list(pictureInfoDict[key])
|
||||||
# Compare color
|
# Compare color
|
||||||
if hasColorProfile:
|
if hasColorProfile:
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info in consumedList:
|
if info in consumedList:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info.sensorType == 'color' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
|
if info.sensorType == 'color' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
|
||||||
resultDict.setdefault(dictIndex, []).append(info)
|
resultDict.setdefault(dictIndex, []).append(info)
|
||||||
consumedList.append(info)
|
consumedList.append(info)
|
||||||
break
|
break
|
||||||
|
|
||||||
# Compare depth
|
# Compare depth
|
||||||
if hasDepthProfile:
|
if hasDepthProfile:
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info in consumedList:
|
if info in consumedList:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info.sensorType == 'depth' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
|
if info.sensorType == 'depth' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
|
||||||
resultDict.setdefault(dictIndex, []).append(info)
|
resultDict.setdefault(dictIndex, []).append(info)
|
||||||
consumedList.append(info)
|
consumedList.append(info)
|
||||||
break
|
break
|
||||||
|
|
||||||
# Compare IR
|
# Compare IR
|
||||||
if hasIRProfile:
|
if hasIRProfile:
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info in consumedList:
|
if info in consumedList:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info.sensorType == 'ir' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
|
if info.sensorType == 'ir' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
|
||||||
resultDict.setdefault(dictIndex, []).append(info)
|
resultDict.setdefault(dictIndex, []).append(info)
|
||||||
consumedList.append(info)
|
consumedList.append(info)
|
||||||
break
|
break
|
||||||
|
|
||||||
# Compare left IR
|
# Compare left IR
|
||||||
if hasIRLeftProfile:
|
if hasIRLeftProfile:
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info in consumedList:
|
if info in consumedList:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info.sensorType == 'ir_left' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
|
if info.sensorType == 'ir_left' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
|
||||||
resultDict.setdefault(dictIndex, []).append(info)
|
resultDict.setdefault(dictIndex, []).append(info)
|
||||||
consumedList.append(info)
|
consumedList.append(info)
|
||||||
break
|
break
|
||||||
|
|
||||||
# Compare right IR
|
# Compare right IR
|
||||||
if hasIRRightProfile:
|
if hasIRRightProfile:
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info in consumedList:
|
if info in consumedList:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info.sensorType == 'ir_right' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
|
if info.sensorType == 'ir_right' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
|
||||||
resultDict.setdefault(dictIndex, []).append(info)
|
resultDict.setdefault(dictIndex, []).append(info)
|
||||||
consumedList.append(info)
|
consumedList.append(info)
|
||||||
break
|
break
|
||||||
|
|
||||||
# Calculate deviation
|
# Calculate deviation
|
||||||
minTsp = min(resultDict[dictIndex], key=lambda x: x.syncTimeStamp)
|
minTsp = min(resultDict[dictIndex], key=lambda x: x.syncTimeStamp)
|
||||||
for info in resultDict[dictIndex]:
|
for info in resultDict[dictIndex]:
|
||||||
info.tspDiff = info.syncTimeStamp - minTsp.syncTimeStamp
|
info.tspDiff = info.syncTimeStamp - minTsp.syncTimeStamp
|
||||||
|
|
||||||
dictIndex += 1
|
dictIndex += 1
|
||||||
|
|
||||||
return resultDict
|
return resultDict
|
||||||
|
|
||||||
|
|
||||||
def safe_make_dir(path):
|
def safe_make_dir(path):
|
||||||
if not os.path.exists(path):
|
if not os.path.exists(path):
|
||||||
os.makedirs(path)
|
os.makedirs(path)
|
||||||
|
|
||||||
|
|
||||||
def handleSyncFrames():
|
def handleSyncFrames():
|
||||||
global resultPath
|
global resultPath
|
||||||
global sourceFramesPath
|
global sourceFramesPath
|
||||||
global streamProfileDict
|
global streamProfileDict
|
||||||
|
|
||||||
fp = open(f"{resultPath}/frameMatchLog.txt", "w")
|
fp = open(f"{resultPath}/frameMatchLog.txt", "w")
|
||||||
|
|
||||||
if not initProfileInfoDict():
|
if not initProfileInfoDict():
|
||||||
print("Initialize stream profile dictionary failed. exit")
|
print("Initialize stream profile dictionary failed. exit")
|
||||||
return
|
return
|
||||||
print(f"Stream profiles: {streamProfileDict}")
|
print(f"Stream profiles: {streamProfileDict}")
|
||||||
streamProfileCount = len(streamProfileDict.items())
|
streamProfileCount = len(streamProfileDict.items())
|
||||||
|
|
||||||
pictureInfoDict = {}
|
pictureInfoDict = {}
|
||||||
|
|
||||||
initPictureInfoDictionary(Path(sourceFramesPath), pictureInfoDict)
|
initPictureInfoDictionary(Path(sourceFramesPath), pictureInfoDict)
|
||||||
if len(pictureInfoDict) <= 0:
|
if len(pictureInfoDict) <= 0:
|
||||||
print("init pictureInfoDict failed. pictureInfoDict.len = 0")
|
print("init pictureInfoDict failed. pictureInfoDict.len = 0")
|
||||||
return
|
return
|
||||||
|
|
||||||
# # Dump pictureInfoDict
|
# # Dump pictureInfoDict
|
||||||
# for key in pictureInfoDict:
|
# for key in pictureInfoDict:
|
||||||
# print("===================key:%s" % key)
|
# print("===================key:%s" % key)
|
||||||
# listTmp = list(pictureInfoDict[key])
|
# listTmp = list(pictureInfoDict[key])
|
||||||
# for info in listTmp:
|
# for info in listTmp:
|
||||||
# print("=====================value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s" % (info.deviceId,info.sensorType,info.syncTimeStamp,info.picturePath))
|
# print("=====================value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s" % (info.deviceId,info.sensorType,info.syncTimeStamp,info.picturePath))
|
||||||
|
|
||||||
deviceCount = getDeviceCount()
|
deviceCount = getDeviceCount()
|
||||||
print("=================device count:%d" % deviceCount)
|
print("=================device count:%d" % deviceCount)
|
||||||
|
|
||||||
resultDict = {}
|
resultDict = {}
|
||||||
resultDict = matchFrame(pictureInfoDict)
|
resultDict = matchFrame(pictureInfoDict)
|
||||||
|
|
||||||
for key in resultDict:
|
for key in resultDict:
|
||||||
fp.write("===================result key:%s\n" % key)
|
fp.write("===================result key:%s\n" % key)
|
||||||
print("===================result key:%s" % key)
|
print("===================result key:%s" % key)
|
||||||
listTmp = list(resultDict[key])
|
listTmp = list(resultDict[key])
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
fp.write("=====================result value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s\n" % (
|
fp.write("=====================result value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s\n" % (
|
||||||
info.deviceId, info.sensorType, info.syncTimeStamp, info.picturePath))
|
info.deviceId, info.sensorType, info.syncTimeStamp, info.picturePath))
|
||||||
print("=====================result value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s" % (
|
print("=====================result value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s" % (
|
||||||
info.deviceId, info.sensorType, info.syncTimeStamp, info.picturePath))
|
info.deviceId, info.sensorType, info.syncTimeStamp, info.picturePath))
|
||||||
|
|
||||||
matchPath = f"{resultPath}/matchFrames/"
|
matchPath = f"{resultPath}/matchFrames/"
|
||||||
safe_make_dir(matchPath)
|
safe_make_dir(matchPath)
|
||||||
notMatchPath = f"{resultPath}/notMatchFrames/"
|
notMatchPath = f"{resultPath}/notMatchFrames/"
|
||||||
abnormalPath = f"{resultPath}/abnormal/"
|
abnormalPath = f"{resultPath}/abnormal/"
|
||||||
|
|
||||||
for key in resultDict:
|
for key in resultDict:
|
||||||
listTmp = list(resultDict[key])
|
listTmp = list(resultDict[key])
|
||||||
if (len(listTmp) == (deviceCount * streamProfileCount)):
|
if (len(listTmp) == (deviceCount * streamProfileCount)):
|
||||||
haveAbnormalData = False
|
haveAbnormalData = False
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
if info.tspDiff >= tspRangeThreshold:
|
if info.tspDiff >= tspRangeThreshold:
|
||||||
path = matchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
path = matchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
||||||
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + "_xxxxxx" + info.fileExt
|
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + "_xxxxxx" + info.fileExt
|
||||||
shutil.copy(info.picturePath, path)
|
shutil.copy(info.picturePath, path)
|
||||||
haveAbnormalData = True
|
haveAbnormalData = True
|
||||||
else:
|
else:
|
||||||
path = matchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
path = matchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
||||||
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + info.fileExt
|
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + info.fileExt
|
||||||
shutil.copy(info.picturePath, path)
|
shutil.copy(info.picturePath, path)
|
||||||
|
|
||||||
if haveAbnormalData:
|
if haveAbnormalData:
|
||||||
safe_make_dir(abnormalPath)
|
safe_make_dir(abnormalPath)
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
if info.tspDiff >= tspRangeThreshold:
|
if info.tspDiff >= tspRangeThreshold:
|
||||||
path = abnormalPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
path = abnormalPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
||||||
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + "_xxxxxx" + info.fileExt
|
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + "_xxxxxx" + info.fileExt
|
||||||
shutil.copy(info.picturePath, path)
|
shutil.copy(info.picturePath, path)
|
||||||
else:
|
else:
|
||||||
path = abnormalPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
path = abnormalPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
||||||
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + info.fileExt
|
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + info.fileExt
|
||||||
shutil.copy(info.picturePath, path)
|
shutil.copy(info.picturePath, path)
|
||||||
else:
|
else:
|
||||||
safe_make_dir(notMatchPath)
|
safe_make_dir(notMatchPath)
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
newFilePath = notMatchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
newFilePath = notMatchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
||||||
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + info.fileExt
|
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + info.fileExt
|
||||||
shutil.copy(info.picturePath, newFilePath)
|
shutil.copy(info.picturePath, newFilePath)
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
if not initPrimaryId():
|
if not initPrimaryId():
|
||||||
print("Initialize primaryId failed. exit.")
|
print("Initialize primaryId failed. exit.")
|
||||||
return
|
return
|
||||||
|
|
||||||
if not initSyncConfigParams():
|
if not initSyncConfigParams():
|
||||||
print("Initialized Sync config parameter failed. exit.")
|
print("Initialized Sync config parameter failed. exit.")
|
||||||
return
|
return
|
||||||
|
|
||||||
initResultDir()
|
initResultDir()
|
||||||
|
|
||||||
print(f"PrimaryId={primaryId}, frameRate={frameRate}, tspRangeThreshold={tspRangeThreshold}")
|
print(f"PrimaryId={primaryId}, frameRate={frameRate}, tspRangeThreshold={tspRangeThreshold}")
|
||||||
handleSyncFrames()
|
handleSyncFrames()
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
parser = argparse.ArgumentParser(description="Synchronize frames support for 'Orbbec Devices'")
|
parser = argparse.ArgumentParser(description="Synchronize frames support for 'Orbbec Devices'")
|
||||||
parser.add_argument('frames_dir', type=str, help="Frames directory")
|
parser.add_argument('frames_dir', type=str, help="Frames directory")
|
||||||
parser.add_argument('main_script_root_dir', type=str, help="SyncFramesMain.py working directory")
|
parser.add_argument('main_script_root_dir', type=str, help="SyncFramesMain.py working directory")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
sourceRootPath = args.frames_dir
|
sourceRootPath = args.frames_dir
|
||||||
sourceFramesPath = f"{args.frames_dir}/TotalModeFrames"
|
sourceFramesPath = f"{args.frames_dir}/TotalModeFrames"
|
||||||
mainPythonWorkPath = args.main_script_root_dir
|
mainPythonWorkPath = args.main_script_root_dir
|
||||||
print(f"Start of CommonFrameMatch synchronize frame. sourceRootPath={sourceRootPath}")
|
print(f"Start of CommonFrameMatch synchronize frame. sourceRootPath={sourceRootPath}")
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|
||||||
print("Finish of CommonFrameMatch synchronize frame.")
|
print("Finish of CommonFrameMatch synchronize frame.")
|
||||||
|
|||||||
+410
-410
@@ -1,410 +1,410 @@
|
|||||||
import os.path
|
import os.path
|
||||||
import argparse
|
import argparse
|
||||||
import sys
|
import sys
|
||||||
import json
|
import json
|
||||||
import shutil
|
import shutil
|
||||||
import configparser
|
import configparser
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
## Config.ini configuration
|
## Config.ini configuration
|
||||||
# Unit: FPS. Please fill in according to the actual dataset frame rate,
|
# Unit: FPS. Please fill in according to the actual dataset frame rate,
|
||||||
# otherwise it will cause inaccurate matching.
|
# otherwise it will cause inaccurate matching.
|
||||||
frameRate = -1
|
frameRate = -1
|
||||||
# Unit: ms. When the timestamp range difference of a matched frame group
|
# Unit: ms. When the timestamp range difference of a matched frame group
|
||||||
# is greater than or equal to tspRangeThreshold, the file name will be marked.
|
# is greater than or equal to tspRangeThreshold, the file name will be marked.
|
||||||
tspRangeThreshold = -1
|
tspRangeThreshold = -1
|
||||||
|
|
||||||
## Parsed automatically by Python script, DO NOT modify
|
## Parsed automatically by Python script, DO NOT modify
|
||||||
primaryId = '-1' # Host ID
|
primaryId = '-1' # Host ID
|
||||||
mainPythonWorkPath = "" # Working directory of SyncFramesMain.py
|
mainPythonWorkPath = "" # Working directory of SyncFramesMain.py
|
||||||
sourceFramesPath = "" # DO NOT modify, fixed value, path to TotalMode directory
|
sourceFramesPath = "" # DO NOT modify, fixed value, path to TotalMode directory
|
||||||
sourceRootPath = "" # Root directory containing TotalMode
|
sourceRootPath = "" # Root directory containing TotalMode
|
||||||
resultPath = "" # Path to save sync analysis results
|
resultPath = "" # Path to save sync analysis results
|
||||||
streamProfileDict = dict() # Store Python results
|
streamProfileDict = dict() # Store Python results
|
||||||
|
|
||||||
class PictureInfo(object):
|
class PictureInfo(object):
|
||||||
class Struct(object):
|
class Struct(object):
|
||||||
def __init__(self, deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt):
|
def __init__(self, deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt):
|
||||||
self.deviceId = deviceId
|
self.deviceId = deviceId
|
||||||
self.sensorType = sensorType
|
self.sensorType = sensorType
|
||||||
self.syncTimeStamp = syncTimeStamp
|
self.syncTimeStamp = syncTimeStamp
|
||||||
self.picturePath = picturePath
|
self.picturePath = picturePath
|
||||||
self.deviceIdFull = deviceIdFull
|
self.deviceIdFull = deviceIdFull
|
||||||
self.fileExt = fileExt
|
self.fileExt = fileExt
|
||||||
|
|
||||||
def make_struct(self, deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt):
|
def make_struct(self, deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt):
|
||||||
return self.Struct(deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt)
|
return self.Struct(deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt)
|
||||||
|
|
||||||
class StreamProfileInfo:
|
class StreamProfileInfo:
|
||||||
def __init__(self, sensorType, width, height, format, fps):
|
def __init__(self, sensorType, width, height, format, fps):
|
||||||
self.sensorType = sensorType
|
self.sensorType = sensorType
|
||||||
self.width = width
|
self.width = width
|
||||||
self.height = height
|
self.height = height
|
||||||
self.format = format
|
self.format = format
|
||||||
self.fps = fps
|
self.fps = fps
|
||||||
|
|
||||||
def initPrimaryId():
|
def initPrimaryId():
|
||||||
global primaryId
|
global primaryId
|
||||||
|
|
||||||
deviceInfoPath = f"{sourceRootPath}/DevicesInfo.txt"
|
deviceInfoPath = f"{sourceRootPath}/DevicesInfo.txt"
|
||||||
if not os.path.exists(deviceInfoPath):
|
if not os.path.exists(deviceInfoPath):
|
||||||
print(f"Initialize primaryId failed. {deviceInfoPath} not exists")
|
print(f"Initialize primaryId failed. {deviceInfoPath} not exists")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
with open(deviceInfoPath, 'r') as f:
|
with open(deviceInfoPath, 'r') as f:
|
||||||
data = json.load(f)
|
data = json.load(f)
|
||||||
|
|
||||||
if not 'devices' in data:
|
if not 'devices' in data:
|
||||||
print(f"Initialize primaryId failed. {deviceInfoPath} not contain item 'devices'")
|
print(f"Initialize primaryId failed. {deviceInfoPath} not contain item 'devices'")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
for item in data['devices']:
|
for item in data['devices']:
|
||||||
if 'isPrimaryDevice' in item and 'index' in item and item['isPrimaryDevice']:
|
if 'isPrimaryDevice' in item and 'index' in item and item['isPrimaryDevice']:
|
||||||
primaryId = str(item['index'])
|
primaryId = str(item['index'])
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def initSyncConfigParams():
|
def initSyncConfigParams():
|
||||||
global frameRate, tspRangeThreshold
|
global frameRate, tspRangeThreshold
|
||||||
|
|
||||||
configPath = f"{mainPythonWorkPath}/Config.ini"
|
configPath = f"{mainPythonWorkPath}/Config.ini"
|
||||||
if not os.path.exists(configPath):
|
if not os.path.exists(configPath):
|
||||||
print(f"Initliaze synchronized config parameter failed. {configPath} not exists.")
|
print(f"Initliaze synchronized config parameter failed. {configPath} not exists.")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Create ConfigParser object
|
# Create ConfigParser object
|
||||||
config = configparser.ConfigParser()
|
config = configparser.ConfigParser()
|
||||||
|
|
||||||
# Read ini file
|
# Read ini file
|
||||||
config.read(configPath, 'utf-8')
|
config.read(configPath, 'utf-8')
|
||||||
|
|
||||||
if not config.has_option('Parameter', 'frameRate'):
|
if not config.has_option('Parameter', 'frameRate'):
|
||||||
print(f"Initliaze synchronized config parameter failed. Not define 'frameRate' in ${configPath}")
|
print(f"Initliaze synchronized config parameter failed. Not define 'frameRate' in ${configPath}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if not config.has_option('Parameter', 'tspRangeThreshold'):
|
if not config.has_option('Parameter', 'tspRangeThreshold'):
|
||||||
print(f"Initliaze synchronized config parameter failed. Not define 'tspRangeThreshold' in ${configPath}")
|
print(f"Initliaze synchronized config parameter failed. Not define 'tspRangeThreshold' in ${configPath}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
frameRate = config.getfloat('Parameter', 'frameRate')
|
frameRate = config.getfloat('Parameter', 'frameRate')
|
||||||
if frameRate <= 0 or frameRate >= 1000:
|
if frameRate <= 0 or frameRate >= 1000:
|
||||||
print(f"Initliaze synchronized config parameter failed. Invalid frameRate={frameRate}")
|
print(f"Initliaze synchronized config parameter failed. Invalid frameRate={frameRate}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
tspRangeThreshold = config.getfloat('Parameter', 'tspRangeThreshold')
|
tspRangeThreshold = config.getfloat('Parameter', 'tspRangeThreshold')
|
||||||
if tspRangeThreshold <= 0:
|
if tspRangeThreshold <= 0:
|
||||||
print(f"Initliaze synchronized config parameter failed. Invalid tspRangeThreshold={tspRangeThreshold}")
|
print(f"Initliaze synchronized config parameter failed. Invalid tspRangeThreshold={tspRangeThreshold}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def getDeviceCount():
|
def getDeviceCount():
|
||||||
deviceInfoPath = f"{sourceRootPath}/DevicesInfo.txt"
|
deviceInfoPath = f"{sourceRootPath}/DevicesInfo.txt"
|
||||||
if not os.path.exists(deviceInfoPath):
|
if not os.path.exists(deviceInfoPath):
|
||||||
print(f"Get device count failed. {deviceInfoPath} not exists")
|
print(f"Get device count failed. {deviceInfoPath} not exists")
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
with open(deviceInfoPath, 'r') as f:
|
with open(deviceInfoPath, 'r') as f:
|
||||||
data = json.load(f)
|
data = json.load(f)
|
||||||
|
|
||||||
if not 'devices' in data:
|
if not 'devices' in data:
|
||||||
print(f"Get device count failed. {deviceInfoPath} not contain item 'devices'")
|
print(f"Get device count failed. {deviceInfoPath} not contain item 'devices'")
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
return len(data['devices'])
|
return len(data['devices'])
|
||||||
|
|
||||||
def initProfileInfoDict():
|
def initProfileInfoDict():
|
||||||
global streamProfileDict
|
global streamProfileDict
|
||||||
|
|
||||||
streamProfileDict = dict()
|
streamProfileDict = dict()
|
||||||
profilePath = f"{sourceRootPath}/StreamProfileInfo.txt"
|
profilePath = f"{sourceRootPath}/StreamProfileInfo.txt"
|
||||||
if not os.path.exists(profilePath):
|
if not os.path.exists(profilePath):
|
||||||
print(f"Initialize profile information dictionary failed. {profilePath} not exists")
|
print(f"Initialize profile information dictionary failed. {profilePath} not exists")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
with open(profilePath, 'r') as f:
|
with open(profilePath, 'r') as f:
|
||||||
data = json.load(f)
|
data = json.load(f)
|
||||||
|
|
||||||
if not 'streamProfiles' in data:
|
if not 'streamProfiles' in data:
|
||||||
print(f"Initialize profile information dictionary failed. {profilePath} not contain item 'streamProfiles'")
|
print(f"Initialize profile information dictionary failed. {profilePath} not contain item 'streamProfiles'")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
for item in data['streamProfiles']:
|
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:
|
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'])
|
profileInfo = StreamProfileInfo(item['sensorType'], item['width'], item['height'], item['format'], item['fps'])
|
||||||
streamProfileDict.setdefault(item['sensorType'], profileInfo)
|
streamProfileDict.setdefault(item['sensorType'], profileInfo)
|
||||||
else:
|
else:
|
||||||
print(f"Initialize profile information dictionary. Error invalid StreamProfile, {item}")
|
print(f"Initialize profile information dictionary. Error invalid StreamProfile, {item}")
|
||||||
|
|
||||||
return len(streamProfileDict.items()) > 0
|
return len(streamProfileDict.items()) > 0
|
||||||
|
|
||||||
def initResultDir():
|
def initResultDir():
|
||||||
global resultPath
|
global resultPath
|
||||||
timeText = datetime.now().strftime("%Y-%m-%d_%H%M%S")
|
timeText = datetime.now().strftime("%Y-%m-%d_%H%M%S")
|
||||||
resultPath = f"{sourceRootPath}/results-{timeText}"
|
resultPath = f"{sourceRootPath}/results-{timeText}"
|
||||||
if not os.path.exists(resultPath):
|
if not os.path.exists(resultPath):
|
||||||
os.makedirs(resultPath)
|
os.makedirs(resultPath)
|
||||||
|
|
||||||
def isFrameFile(fileName):
|
def isFrameFile(fileName):
|
||||||
fileExt = os.path.splitext(fileName)
|
fileExt = os.path.splitext(fileName)
|
||||||
if len(fileExt) < 2:
|
if len(fileExt) < 2:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
frameExts = {".jpeg", ".jpg", ".png", ".raw", "bmp"}
|
frameExts = {".jpeg", ".jpg", ".png", ".raw", "bmp"}
|
||||||
return fileExt[1] in frameExts
|
return fileExt[1] in frameExts
|
||||||
|
|
||||||
def initPictureInfoDictionary(rootFilePath, pictureInfoDict):
|
def initPictureInfoDictionary(rootFilePath, pictureInfoDict):
|
||||||
frameFileCount = 0
|
frameFileCount = 0
|
||||||
for dirpath, dirnames, filenames in os.walk(rootFilePath):
|
for dirpath, dirnames, filenames in os.walk(rootFilePath):
|
||||||
# print(f"dirpath={dirpath}, dirpath.basename=" + os.path.basename(dirpath))
|
# print(f"dirpath={dirpath}, dirpath.basename=" + os.path.basename(dirpath))
|
||||||
for fileName in filenames:
|
for fileName in filenames:
|
||||||
filePath = os.path.join(dirpath, fileName)
|
filePath = os.path.join(dirpath, fileName)
|
||||||
if not isFrameFile(fileName):
|
if not isFrameFile(fileName):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
frameFileCount += 1
|
frameFileCount += 1
|
||||||
fileNameNoExt = os.path.splitext(fileName)[0]
|
fileNameNoExt = os.path.splitext(fileName)[0]
|
||||||
pictureNameList = fileNameNoExt.split('_')
|
pictureNameList = fileNameNoExt.split('_')
|
||||||
deviceId = pictureNameList[2][5:]
|
deviceId = pictureNameList[2][5:]
|
||||||
sensorType = pictureNameList[0].replace('#', '_')
|
sensorType = pictureNameList[0].replace('#', '_')
|
||||||
syncTimeStamp = int(pictureNameList[3][1:])
|
syncTimeStamp = int(pictureNameList[3][1:])
|
||||||
|
|
||||||
# Create structure
|
# Create structure
|
||||||
pictureInfo = PictureInfo()
|
pictureInfo = PictureInfo()
|
||||||
info = pictureInfo.make_struct(deviceId, sensorType, syncTimeStamp, filePath, os.path.basename(dirpath), os.path.splitext(fileName)[1])
|
info = pictureInfo.make_struct(deviceId, sensorType, syncTimeStamp, filePath, os.path.basename(dirpath), os.path.splitext(fileName)[1])
|
||||||
|
|
||||||
# Format dictionary: one key corresponds to one array
|
# Format dictionary: one key corresponds to one array
|
||||||
pictureInfoDict.setdefault(deviceId, []).append(info)
|
pictureInfoDict.setdefault(deviceId, []).append(info)
|
||||||
|
|
||||||
if 0 == frameFileCount:
|
if 0 == frameFileCount:
|
||||||
print("initialize pictureInfoDict failed. Not found frame file")
|
print("initialize pictureInfoDict failed. Not found frame file")
|
||||||
|
|
||||||
|
|
||||||
def matchFrame(pictureInfoDict):
|
def matchFrame(pictureInfoDict):
|
||||||
global primaryId, frameRate
|
global primaryId, frameRate
|
||||||
global streamProfileDict
|
global streamProfileDict
|
||||||
|
|
||||||
# Get comparison image array, take the Color array of the first device for comparison
|
# Get comparison image array, take the Color array of the first device for comparison
|
||||||
compareList = []
|
compareList = []
|
||||||
for key in pictureInfoDict:
|
for key in pictureInfoDict:
|
||||||
listTmp = list(pictureInfoDict[key])
|
listTmp = list(pictureInfoDict[key])
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
if info.deviceId == primaryId and info.sensorType == 'color':
|
if info.deviceId == primaryId and info.sensorType == 'color':
|
||||||
compareList.append(info)
|
compareList.append(info)
|
||||||
|
|
||||||
# Dynamically analyze based on stream status to reduce loop iterations
|
# Dynamically analyze based on stream status to reduce loop iterations
|
||||||
hasColorProfile = 'OB_SENSOR_COLOR' in streamProfileDict
|
hasColorProfile = 'OB_SENSOR_COLOR' in streamProfileDict
|
||||||
hasDepthProfile = 'OB_SENSOR_DEPTH' in streamProfileDict
|
hasDepthProfile = 'OB_SENSOR_DEPTH' in streamProfileDict
|
||||||
hasIRProfile = 'OB_SENSOR_IR' in streamProfileDict
|
hasIRProfile = 'OB_SENSOR_IR' in streamProfileDict
|
||||||
hasIRLeftProfile = 'OB_SENSOR_IR_LEFT' in streamProfileDict
|
hasIRLeftProfile = 'OB_SENSOR_IR_LEFT' in streamProfileDict
|
||||||
hasIRRightProfile = 'OB_SENSOR_IR_RIGHT' in streamProfileDict
|
hasIRRightProfile = 'OB_SENSOR_IR_RIGHT' in streamProfileDict
|
||||||
|
|
||||||
# Match adjacent frames
|
# Match adjacent frames
|
||||||
resultDict = {}
|
resultDict = {}
|
||||||
consumedList = []
|
consumedList = []
|
||||||
dictIndex = 0
|
dictIndex = 0
|
||||||
frameTspHalfGap = int(1000.0/frameRate/2.0+0.5)
|
frameTspHalfGap = int(1000.0/frameRate/2.0+0.5)
|
||||||
for comparePic in compareList:
|
for comparePic in compareList:
|
||||||
resultDict.setdefault(dictIndex, []).append(comparePic)
|
resultDict.setdefault(dictIndex, []).append(comparePic)
|
||||||
for key in pictureInfoDict:
|
for key in pictureInfoDict:
|
||||||
listTmp = list(pictureInfoDict[key])
|
listTmp = list(pictureInfoDict[key])
|
||||||
# Compare color
|
# Compare color
|
||||||
if hasColorProfile:
|
if hasColorProfile:
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info in consumedList:
|
if info in consumedList:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info.sensorType == 'color' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
|
if info.sensorType == 'color' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
|
||||||
resultDict.setdefault(dictIndex, []).append(info)
|
resultDict.setdefault(dictIndex, []).append(info)
|
||||||
consumedList.append(info)
|
consumedList.append(info)
|
||||||
break
|
break
|
||||||
|
|
||||||
# Compare depth
|
# Compare depth
|
||||||
if hasDepthProfile:
|
if hasDepthProfile:
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info in consumedList:
|
if info in consumedList:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info.sensorType == 'depth' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
|
if info.sensorType == 'depth' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
|
||||||
resultDict.setdefault(dictIndex, []).append(info)
|
resultDict.setdefault(dictIndex, []).append(info)
|
||||||
consumedList.append(info)
|
consumedList.append(info)
|
||||||
break
|
break
|
||||||
|
|
||||||
# Compare IR
|
# Compare IR
|
||||||
if hasIRProfile:
|
if hasIRProfile:
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info in consumedList:
|
if info in consumedList:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info.sensorType == 'ir' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
|
if info.sensorType == 'ir' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
|
||||||
resultDict.setdefault(dictIndex, []).append(info)
|
resultDict.setdefault(dictIndex, []).append(info)
|
||||||
consumedList.append(info)
|
consumedList.append(info)
|
||||||
break
|
break
|
||||||
|
|
||||||
# Compare left IR
|
# Compare left IR
|
||||||
if hasIRLeftProfile:
|
if hasIRLeftProfile:
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info in consumedList:
|
if info in consumedList:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info.sensorType == 'ir_left' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
|
if info.sensorType == 'ir_left' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
|
||||||
resultDict.setdefault(dictIndex, []).append(info)
|
resultDict.setdefault(dictIndex, []).append(info)
|
||||||
consumedList.append(info)
|
consumedList.append(info)
|
||||||
break
|
break
|
||||||
|
|
||||||
# Compare right IR
|
# Compare right IR
|
||||||
if hasIRRightProfile:
|
if hasIRRightProfile:
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info in consumedList:
|
if info in consumedList:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info.sensorType == 'ir_right' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
|
if info.sensorType == 'ir_right' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
|
||||||
resultDict.setdefault(dictIndex, []).append(info)
|
resultDict.setdefault(dictIndex, []).append(info)
|
||||||
consumedList.append(info)
|
consumedList.append(info)
|
||||||
break
|
break
|
||||||
|
|
||||||
# Calculate deviation
|
# Calculate deviation
|
||||||
minTsp = min(resultDict[dictIndex], key=lambda x: x.syncTimeStamp)
|
minTsp = min(resultDict[dictIndex], key=lambda x: x.syncTimeStamp)
|
||||||
for info in resultDict[dictIndex]:
|
for info in resultDict[dictIndex]:
|
||||||
info.tspDiff = info.syncTimeStamp - minTsp.syncTimeStamp
|
info.tspDiff = info.syncTimeStamp - minTsp.syncTimeStamp
|
||||||
|
|
||||||
dictIndex += 1
|
dictIndex += 1
|
||||||
|
|
||||||
return resultDict
|
return resultDict
|
||||||
|
|
||||||
|
|
||||||
def safe_make_dir(path):
|
def safe_make_dir(path):
|
||||||
if not os.path.exists(path):
|
if not os.path.exists(path):
|
||||||
os.makedirs(path)
|
os.makedirs(path)
|
||||||
|
|
||||||
|
|
||||||
def handleSyncFrames():
|
def handleSyncFrames():
|
||||||
global resultPath
|
global resultPath
|
||||||
global sourceFramesPath
|
global sourceFramesPath
|
||||||
global streamProfileDict
|
global streamProfileDict
|
||||||
|
|
||||||
fp = open(f"{resultPath}/frameMatchLog.txt", "w")
|
fp = open(f"{resultPath}/frameMatchLog.txt", "w")
|
||||||
|
|
||||||
if not initProfileInfoDict():
|
if not initProfileInfoDict():
|
||||||
print("Initialize stream profile dictionary failed. exit")
|
print("Initialize stream profile dictionary failed. exit")
|
||||||
return
|
return
|
||||||
print(f"Stream profiles: {streamProfileDict}")
|
print(f"Stream profiles: {streamProfileDict}")
|
||||||
streamProfileCount = len(streamProfileDict.items())
|
streamProfileCount = len(streamProfileDict.items())
|
||||||
|
|
||||||
pictureInfoDict = {}
|
pictureInfoDict = {}
|
||||||
|
|
||||||
initPictureInfoDictionary(Path(sourceFramesPath), pictureInfoDict)
|
initPictureInfoDictionary(Path(sourceFramesPath), pictureInfoDict)
|
||||||
if len(pictureInfoDict) <= 0:
|
if len(pictureInfoDict) <= 0:
|
||||||
print("init pictureInfoDict failed. pictureInfoDict.len = 0")
|
print("init pictureInfoDict failed. pictureInfoDict.len = 0")
|
||||||
return
|
return
|
||||||
|
|
||||||
# # Dump pictureInfoDict
|
# # Dump pictureInfoDict
|
||||||
# for key in pictureInfoDict:
|
# for key in pictureInfoDict:
|
||||||
# print("===================key:%s" % key)
|
# print("===================key:%s" % key)
|
||||||
# listTmp = list(pictureInfoDict[key])
|
# listTmp = list(pictureInfoDict[key])
|
||||||
# for info in listTmp:
|
# for info in listTmp:
|
||||||
# print("=====================value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s" % (info.deviceId,info.sensorType,info.syncTimeStamp,info.picturePath))
|
# print("=====================value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s" % (info.deviceId,info.sensorType,info.syncTimeStamp,info.picturePath))
|
||||||
|
|
||||||
deviceCount = getDeviceCount()
|
deviceCount = getDeviceCount()
|
||||||
print("=================device count:%d" % deviceCount)
|
print("=================device count:%d" % deviceCount)
|
||||||
|
|
||||||
resultDict = {}
|
resultDict = {}
|
||||||
resultDict = matchFrame(pictureInfoDict)
|
resultDict = matchFrame(pictureInfoDict)
|
||||||
|
|
||||||
for key in resultDict:
|
for key in resultDict:
|
||||||
fp.write("===================result key:%s\n" % key)
|
fp.write("===================result key:%s\n" % key)
|
||||||
print("===================result key:%s" % key)
|
print("===================result key:%s" % key)
|
||||||
listTmp = list(resultDict[key])
|
listTmp = list(resultDict[key])
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
fp.write("=====================result value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s\n" % (
|
fp.write("=====================result value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s\n" % (
|
||||||
info.deviceId, info.sensorType, info.syncTimeStamp, info.picturePath))
|
info.deviceId, info.sensorType, info.syncTimeStamp, info.picturePath))
|
||||||
print("=====================result value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s" % (
|
print("=====================result value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s" % (
|
||||||
info.deviceId, info.sensorType, info.syncTimeStamp, info.picturePath))
|
info.deviceId, info.sensorType, info.syncTimeStamp, info.picturePath))
|
||||||
|
|
||||||
matchPath = f"{resultPath}/matchFrames/"
|
matchPath = f"{resultPath}/matchFrames/"
|
||||||
safe_make_dir(matchPath)
|
safe_make_dir(matchPath)
|
||||||
notMatchPath = f"{resultPath}/notMatchFrames/"
|
notMatchPath = f"{resultPath}/notMatchFrames/"
|
||||||
abnormalPath = f"{resultPath}/abnormal/"
|
abnormalPath = f"{resultPath}/abnormal/"
|
||||||
|
|
||||||
for key in resultDict:
|
for key in resultDict:
|
||||||
listTmp = list(resultDict[key])
|
listTmp = list(resultDict[key])
|
||||||
if (len(listTmp) == (deviceCount * streamProfileCount)):
|
if (len(listTmp) == (deviceCount * streamProfileCount)):
|
||||||
haveAbnormalData = False
|
haveAbnormalData = False
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
if info.tspDiff >= tspRangeThreshold:
|
if info.tspDiff >= tspRangeThreshold:
|
||||||
path = matchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
path = matchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
||||||
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + "_xxxxxx" + info.fileExt
|
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + "_xxxxxx" + info.fileExt
|
||||||
shutil.copy(info.picturePath, path)
|
shutil.copy(info.picturePath, path)
|
||||||
haveAbnormalData = True
|
haveAbnormalData = True
|
||||||
else:
|
else:
|
||||||
path = matchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
path = matchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
||||||
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + info.fileExt
|
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + info.fileExt
|
||||||
shutil.copy(info.picturePath, path)
|
shutil.copy(info.picturePath, path)
|
||||||
|
|
||||||
if haveAbnormalData:
|
if haveAbnormalData:
|
||||||
safe_make_dir(abnormalPath)
|
safe_make_dir(abnormalPath)
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
if info.tspDiff >= tspRangeThreshold:
|
if info.tspDiff >= tspRangeThreshold:
|
||||||
path = abnormalPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
path = abnormalPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
||||||
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + "_xxxxxx" + info.fileExt
|
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + "_xxxxxx" + info.fileExt
|
||||||
shutil.copy(info.picturePath, path)
|
shutil.copy(info.picturePath, path)
|
||||||
else:
|
else:
|
||||||
path = abnormalPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
path = abnormalPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
||||||
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + info.fileExt
|
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + info.fileExt
|
||||||
shutil.copy(info.picturePath, path)
|
shutil.copy(info.picturePath, path)
|
||||||
else:
|
else:
|
||||||
safe_make_dir(notMatchPath)
|
safe_make_dir(notMatchPath)
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
newFilePath = notMatchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
newFilePath = notMatchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
||||||
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + info.fileExt
|
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + info.fileExt
|
||||||
shutil.copy(info.picturePath, newFilePath)
|
shutil.copy(info.picturePath, newFilePath)
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
if not initPrimaryId():
|
if not initPrimaryId():
|
||||||
print("Initialize primaryId failed. exit.")
|
print("Initialize primaryId failed. exit.")
|
||||||
return
|
return
|
||||||
|
|
||||||
if not initSyncConfigParams():
|
if not initSyncConfigParams():
|
||||||
print("Initialized Sync config parameter failed. exit.")
|
print("Initialized Sync config parameter failed. exit.")
|
||||||
return
|
return
|
||||||
|
|
||||||
initResultDir()
|
initResultDir()
|
||||||
|
|
||||||
print(f"PrimaryId={primaryId}, frameRate={frameRate}, tspRangeThreshold={tspRangeThreshold}")
|
print(f"PrimaryId={primaryId}, frameRate={frameRate}, tspRangeThreshold={tspRangeThreshold}")
|
||||||
handleSyncFrames()
|
handleSyncFrames()
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
parser = argparse.ArgumentParser(description="Synchronize frames support for 'Orbbec Gemini 2 VL'")
|
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('frames_dir', type=str, help="Frames directory")
|
||||||
parser.add_argument('main_script_root_dir', type=str, help="SyncFramesMain.py working directory")
|
parser.add_argument('main_script_root_dir', type=str, help="SyncFramesMain.py working directory")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
sourceRootPath = args.frames_dir
|
sourceRootPath = args.frames_dir
|
||||||
sourceFramesPath = f"{args.frames_dir}/TotalModeFrames"
|
sourceFramesPath = f"{args.frames_dir}/TotalModeFrames"
|
||||||
mainPythonWorkPath = args.main_script_root_dir
|
mainPythonWorkPath = args.main_script_root_dir
|
||||||
print(f"Start of Gemini2VL synchronize frame. sourceRootPath={sourceRootPath}")
|
print(f"Start of Gemini2VL synchronize frame. sourceRootPath={sourceRootPath}")
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|
||||||
print("Finish of Gemini2VL synchronize frame.")
|
print("Finish of Gemini2VL synchronize frame.")
|
||||||
|
|||||||
+426
-426
@@ -1,426 +1,426 @@
|
|||||||
import os.path
|
import os.path
|
||||||
import argparse
|
import argparse
|
||||||
import sys
|
import sys
|
||||||
import json
|
import json
|
||||||
import shutil
|
import shutil
|
||||||
import configparser
|
import configparser
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
|
||||||
## Config.ini configuration
|
## Config.ini configuration
|
||||||
# Unit: FPS. Please fill in according to the actual frame rate of the dataset, otherwise the matching will be inaccurate.
|
# Unit: FPS. Please fill in according to the actual frame rate of the dataset, otherwise the matching will be inaccurate.
|
||||||
frameRate = -1
|
frameRate = -1
|
||||||
# Unit: ms. When the timestamp range of a matched group of data frames is greater than or equal to tspRangeThreshold, the filename will be marked.
|
# Unit: ms. When the timestamp range of a matched group of data frames is greater than or equal to tspRangeThreshold, the filename will be marked.
|
||||||
tspRangeThreshold = -1
|
tspRangeThreshold = -1
|
||||||
|
|
||||||
## Automatically parsed by Python script, do not modify
|
## Automatically parsed by Python script, do not modify
|
||||||
primaryId = '-1' # Primary device ID
|
primaryId = '-1' # Primary device ID
|
||||||
mainPythonWorkPath = "" # Working directory of SyncFramesMain.py
|
mainPythonWorkPath = "" # Working directory of SyncFramesMain.py
|
||||||
sourceFramesPath = "" # Do not modify, fixed value, path to TotalMode directory
|
sourceFramesPath = "" # Do not modify, fixed value, path to TotalMode directory
|
||||||
sourceRootPath = "" # Root directory where TotalMode is stored
|
sourceRootPath = "" # Root directory where TotalMode is stored
|
||||||
resultPath = "" # Save sync analysis results
|
resultPath = "" # Save sync analysis results
|
||||||
streamProfileDict = dict() # Save Python results
|
streamProfileDict = dict() # Save Python results
|
||||||
|
|
||||||
class PictureInfo(object):
|
class PictureInfo(object):
|
||||||
class Struct(object):
|
class Struct(object):
|
||||||
def __init__(self, deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt, exp, gain):
|
def __init__(self, deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt, exp, gain):
|
||||||
self.deviceId = deviceId
|
self.deviceId = deviceId
|
||||||
self.sensorType = sensorType
|
self.sensorType = sensorType
|
||||||
self.syncTimeStamp = syncTimeStamp
|
self.syncTimeStamp = syncTimeStamp
|
||||||
self.picturePath = picturePath
|
self.picturePath = picturePath
|
||||||
self.deviceIdFull = deviceIdFull
|
self.deviceIdFull = deviceIdFull
|
||||||
self.fileExt = fileExt
|
self.fileExt = fileExt
|
||||||
self.exp = exp
|
self.exp = exp
|
||||||
self.gain = gain
|
self.gain = gain
|
||||||
|
|
||||||
def make_struct(self, deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt, exp, gain):
|
def make_struct(self, deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt, exp, gain):
|
||||||
return self.Struct(deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt, exp, gain)
|
return self.Struct(deviceId, sensorType, syncTimeStamp, picturePath, deviceIdFull, fileExt, exp, gain)
|
||||||
|
|
||||||
class StreamProfileInfo:
|
class StreamProfileInfo:
|
||||||
def __init__(self, sensorType, width, height, format, fps):
|
def __init__(self, sensorType, width, height, format, fps):
|
||||||
self.sensorType = sensorType
|
self.sensorType = sensorType
|
||||||
self.width = width
|
self.width = width
|
||||||
self.height = height
|
self.height = height
|
||||||
self.format = format
|
self.format = format
|
||||||
self.fps = fps
|
self.fps = fps
|
||||||
|
|
||||||
def initPrimaryId():
|
def initPrimaryId():
|
||||||
global primaryId
|
global primaryId
|
||||||
|
|
||||||
deviceInfoPath = f"{sourceRootPath}/DevicesInfo.txt"
|
deviceInfoPath = f"{sourceRootPath}/DevicesInfo.txt"
|
||||||
if not os.path.exists(deviceInfoPath):
|
if not os.path.exists(deviceInfoPath):
|
||||||
print(f"Initialize primaryId failed. {deviceInfoPath} not exists")
|
print(f"Initialize primaryId failed. {deviceInfoPath} not exists")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
with open(deviceInfoPath, 'r') as f:
|
with open(deviceInfoPath, 'r') as f:
|
||||||
data = json.load(f)
|
data = json.load(f)
|
||||||
|
|
||||||
if not 'devices' in data:
|
if not 'devices' in data:
|
||||||
print(f"Initialize primaryId failed. {deviceInfoPath} not contain item 'devices'")
|
print(f"Initialize primaryId failed. {deviceInfoPath} not contain item 'devices'")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
for item in data['devices']:
|
for item in data['devices']:
|
||||||
if 'isPrimaryDevice' in item and 'index' in item and item['isPrimaryDevice']:
|
if 'isPrimaryDevice' in item and 'index' in item and item['isPrimaryDevice']:
|
||||||
primaryId = str(item['index'])
|
primaryId = str(item['index'])
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def initSyncConfigParams():
|
def initSyncConfigParams():
|
||||||
global frameRate, tspRangeThreshold
|
global frameRate, tspRangeThreshold
|
||||||
|
|
||||||
configPath = f"{mainPythonWorkPath}/Config.ini"
|
configPath = f"{mainPythonWorkPath}/Config.ini"
|
||||||
if not os.path.exists(configPath):
|
if not os.path.exists(configPath):
|
||||||
print(f"Initliaze synchronized config parameter failed. {configPath} not exists.")
|
print(f"Initliaze synchronized config parameter failed. {configPath} not exists.")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Create ConfigParser object
|
# Create ConfigParser object
|
||||||
config = configparser.ConfigParser()
|
config = configparser.ConfigParser()
|
||||||
|
|
||||||
# Read ini file
|
# Read ini file
|
||||||
config.read(configPath, 'utf-8')
|
config.read(configPath, 'utf-8')
|
||||||
|
|
||||||
if not config.has_option('Parameter', 'frameRate'):
|
if not config.has_option('Parameter', 'frameRate'):
|
||||||
print(f"Initliaze synchronized config parameter failed. Not define 'frameRate' in ${configPath}")
|
print(f"Initliaze synchronized config parameter failed. Not define 'frameRate' in ${configPath}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if not config.has_option('Parameter', 'tspRangeThreshold'):
|
if not config.has_option('Parameter', 'tspRangeThreshold'):
|
||||||
print(f"Initliaze synchronized config parameter failed. Not define 'tspRangeThreshold' in ${configPath}")
|
print(f"Initliaze synchronized config parameter failed. Not define 'tspRangeThreshold' in ${configPath}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
frameRate = config.getfloat('Parameter', 'frameRate')
|
frameRate = config.getfloat('Parameter', 'frameRate')
|
||||||
if frameRate <= 0 or frameRate >= 1000:
|
if frameRate <= 0 or frameRate >= 1000:
|
||||||
print(f"Initliaze synchronized config parameter failed. Invalid frameRate={frameRate}")
|
print(f"Initliaze synchronized config parameter failed. Invalid frameRate={frameRate}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
tspRangeThreshold = config.getfloat('Parameter', 'tspRangeThreshold')
|
tspRangeThreshold = config.getfloat('Parameter', 'tspRangeThreshold')
|
||||||
if tspRangeThreshold <= 0:
|
if tspRangeThreshold <= 0:
|
||||||
print(f"Initliaze synchronized config parameter failed. Invalid tspRangeThreshold={tspRangeThreshold}")
|
print(f"Initliaze synchronized config parameter failed. Invalid tspRangeThreshold={tspRangeThreshold}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def getDeviceCount():
|
def getDeviceCount():
|
||||||
deviceInfoPath = f"{sourceRootPath}/DevicesInfo.txt"
|
deviceInfoPath = f"{sourceRootPath}/DevicesInfo.txt"
|
||||||
if not os.path.exists(deviceInfoPath):
|
if not os.path.exists(deviceInfoPath):
|
||||||
print(f"Get device count failed. {deviceInfoPath} not exists")
|
print(f"Get device count failed. {deviceInfoPath} not exists")
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
with open(deviceInfoPath, 'r') as f:
|
with open(deviceInfoPath, 'r') as f:
|
||||||
data = json.load(f)
|
data = json.load(f)
|
||||||
|
|
||||||
if not 'devices' in data:
|
if not 'devices' in data:
|
||||||
print(f"Get device count failed. {deviceInfoPath} not contain item 'devices'")
|
print(f"Get device count failed. {deviceInfoPath} not contain item 'devices'")
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
return len(data['devices'])
|
return len(data['devices'])
|
||||||
|
|
||||||
def initProfileInfoDict():
|
def initProfileInfoDict():
|
||||||
global streamProfileDict
|
global streamProfileDict
|
||||||
|
|
||||||
streamProfileDict = dict()
|
streamProfileDict = dict()
|
||||||
profilePath = f"{sourceRootPath}/StreamProfileInfo.txt"
|
profilePath = f"{sourceRootPath}/StreamProfileInfo.txt"
|
||||||
if not os.path.exists(profilePath):
|
if not os.path.exists(profilePath):
|
||||||
print(f"Initialize profile information dictionary failed. {profilePath} not exists")
|
print(f"Initialize profile information dictionary failed. {profilePath} not exists")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
with open(profilePath, 'r') as f:
|
with open(profilePath, 'r') as f:
|
||||||
data = json.load(f)
|
data = json.load(f)
|
||||||
|
|
||||||
if not 'streamProfiles' in data:
|
if not 'streamProfiles' in data:
|
||||||
print(f"Initialize profile information dictionary failed. {profilePath} not contain item 'streamProfiles'")
|
print(f"Initialize profile information dictionary failed. {profilePath} not contain item 'streamProfiles'")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
for item in data['streamProfiles']:
|
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:
|
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'])
|
profileInfo = StreamProfileInfo(item['sensorType'], item['width'], item['height'], item['format'], item['fps'])
|
||||||
streamProfileDict.setdefault(item['sensorType'], profileInfo)
|
streamProfileDict.setdefault(item['sensorType'], profileInfo)
|
||||||
else:
|
else:
|
||||||
print(f"Initialize profile information dictionary. Error invalid StreamProfile, {item}")
|
print(f"Initialize profile information dictionary. Error invalid StreamProfile, {item}")
|
||||||
|
|
||||||
return len(streamProfileDict.items()) > 0
|
return len(streamProfileDict.items()) > 0
|
||||||
|
|
||||||
def initResultDir():
|
def initResultDir():
|
||||||
global resultPath
|
global resultPath
|
||||||
timeText = datetime.now().strftime("%Y-%m-%d_%H%M%S")
|
timeText = datetime.now().strftime("%Y-%m-%d_%H%M%S")
|
||||||
resultPath = f"{sourceRootPath}/results-{timeText}"
|
resultPath = f"{sourceRootPath}/results-{timeText}"
|
||||||
if not os.path.exists(resultPath):
|
if not os.path.exists(resultPath):
|
||||||
os.makedirs(resultPath)
|
os.makedirs(resultPath)
|
||||||
|
|
||||||
def isFrameFile(fileName):
|
def isFrameFile(fileName):
|
||||||
fileExt = os.path.splitext(fileName)
|
fileExt = os.path.splitext(fileName)
|
||||||
if len(fileExt) < 2:
|
if len(fileExt) < 2:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
frameExts = {".jpeg", ".jpg", ".png", ".raw", "bmp"}
|
frameExts = {".jpeg", ".jpg", ".png", ".raw", "bmp"}
|
||||||
return fileExt[1] in frameExts
|
return fileExt[1] in frameExts
|
||||||
|
|
||||||
def extract_number(filename):
|
def extract_number(filename):
|
||||||
match_d = re.search(r'_d(\d+)', filename)
|
match_d = re.search(r'_d(\d+)', filename)
|
||||||
if match_d:
|
if match_d:
|
||||||
return int(match_d.group(1))
|
return int(match_d.group(1))
|
||||||
|
|
||||||
match_g = re.search(r'_g(\d+)', filename)
|
match_g = re.search(r'_g(\d+)', filename)
|
||||||
if match_g:
|
if match_g:
|
||||||
return int(match_g.group(1))
|
return int(match_g.group(1))
|
||||||
|
|
||||||
return float('inf')
|
return float('inf')
|
||||||
|
|
||||||
def initPictureInfoDictionary(rootFilePath, pictureInfoDict):
|
def initPictureInfoDictionary(rootFilePath, pictureInfoDict):
|
||||||
frameFileCount = 0
|
frameFileCount = 0
|
||||||
for dirpath, dirnames, filenames in os.walk(rootFilePath):
|
for dirpath, dirnames, filenames in os.walk(rootFilePath):
|
||||||
filenames.sort(key=extract_number) # Sort files by numbers following '_d' and '_g' in filename, ascending
|
filenames.sort(key=extract_number) # Sort files by numbers following '_d' and '_g' in filename, ascending
|
||||||
for fileName in filenames:
|
for fileName in filenames:
|
||||||
filePath = os.path.join(dirpath, fileName)
|
filePath = os.path.join(dirpath, fileName)
|
||||||
if not isFrameFile(fileName):
|
if not isFrameFile(fileName):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
frameFileCount += 1
|
frameFileCount += 1
|
||||||
fileNameNoExt = os.path.splitext(fileName)[0]
|
fileNameNoExt = os.path.splitext(fileName)[0]
|
||||||
pictureNameList = fileNameNoExt.split('_')
|
pictureNameList = fileNameNoExt.split('_')
|
||||||
deviceId = pictureNameList[2][5:]
|
deviceId = pictureNameList[2][5:]
|
||||||
sensorType = pictureNameList[0].replace('#', '_')
|
sensorType = pictureNameList[0].replace('#', '_')
|
||||||
syncTimeStamp = int(pictureNameList[3][1:])
|
syncTimeStamp = int(pictureNameList[3][1:])
|
||||||
exp = str(pictureNameList[6][0:])
|
exp = str(pictureNameList[6][0:])
|
||||||
gain = str(pictureNameList[7][0:])
|
gain = str(pictureNameList[7][0:])
|
||||||
|
|
||||||
# Create structure
|
# Create structure
|
||||||
pictureInfo = PictureInfo()
|
pictureInfo = PictureInfo()
|
||||||
info = pictureInfo.make_struct(deviceId, sensorType, syncTimeStamp, filePath, os.path.basename(dirpath), os.path.splitext(fileName)[1],exp,gain)
|
info = pictureInfo.make_struct(deviceId, sensorType, syncTimeStamp, filePath, os.path.basename(dirpath), os.path.splitext(fileName)[1],exp,gain)
|
||||||
|
|
||||||
# Format dictionary: one key corresponds to one array
|
# Format dictionary: one key corresponds to one array
|
||||||
pictureInfoDict.setdefault(deviceId, []).append(info)
|
pictureInfoDict.setdefault(deviceId, []).append(info)
|
||||||
|
|
||||||
if 0 == frameFileCount:
|
if 0 == frameFileCount:
|
||||||
print("initialize pictureInfoDict failed. Not found frame file")
|
print("initialize pictureInfoDict failed. Not found frame file")
|
||||||
|
|
||||||
|
|
||||||
def matchFrame(pictureInfoDict):
|
def matchFrame(pictureInfoDict):
|
||||||
global primaryId, frameRate
|
global primaryId, frameRate
|
||||||
global streamProfileDict
|
global streamProfileDict
|
||||||
|
|
||||||
# Get comparison image array, use Color array of the first device for comparison
|
# Get comparison image array, use Color array of the first device for comparison
|
||||||
compareList = []
|
compareList = []
|
||||||
for key in pictureInfoDict:
|
for key in pictureInfoDict:
|
||||||
listTmp = list(pictureInfoDict[key])
|
listTmp = list(pictureInfoDict[key])
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
if info.deviceId == primaryId and info.sensorType == 'color':
|
if info.deviceId == primaryId and info.sensorType == 'color':
|
||||||
compareList.append(info)
|
compareList.append(info)
|
||||||
|
|
||||||
# Dynamically analyze according to stream situation to reduce loop count
|
# Dynamically analyze according to stream situation to reduce loop count
|
||||||
hasColorProfile = 'OB_SENSOR_COLOR' in streamProfileDict
|
hasColorProfile = 'OB_SENSOR_COLOR' in streamProfileDict
|
||||||
hasDepthProfile = 'OB_SENSOR_DEPTH' in streamProfileDict
|
hasDepthProfile = 'OB_SENSOR_DEPTH' in streamProfileDict
|
||||||
hasIRProfile = 'OB_SENSOR_IR' in streamProfileDict
|
hasIRProfile = 'OB_SENSOR_IR' in streamProfileDict
|
||||||
hasIRLeftProfile = 'OB_SENSOR_IR_LEFT' in streamProfileDict
|
hasIRLeftProfile = 'OB_SENSOR_IR_LEFT' in streamProfileDict
|
||||||
hasIRRightProfile = 'OB_SENSOR_IR_RIGHT' in streamProfileDict
|
hasIRRightProfile = 'OB_SENSOR_IR_RIGHT' in streamProfileDict
|
||||||
|
|
||||||
# Match adjacent frames
|
# Match adjacent frames
|
||||||
resultDict = {}
|
resultDict = {}
|
||||||
consumedList = []
|
consumedList = []
|
||||||
dictIndex = 0
|
dictIndex = 0
|
||||||
frameTspHalfGap = int(1000.0/frameRate/2.0+0.5)
|
frameTspHalfGap = int(1000.0/frameRate/2.0+0.5)
|
||||||
for comparePic in compareList:
|
for comparePic in compareList:
|
||||||
resultDict.setdefault(dictIndex, []).append(comparePic)
|
resultDict.setdefault(dictIndex, []).append(comparePic)
|
||||||
for key in pictureInfoDict:
|
for key in pictureInfoDict:
|
||||||
listTmp = list(pictureInfoDict[key])
|
listTmp = list(pictureInfoDict[key])
|
||||||
# Compare color
|
# Compare color
|
||||||
if hasColorProfile:
|
if hasColorProfile:
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info in consumedList:
|
if info in consumedList:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info.sensorType == 'color' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
|
if info.sensorType == 'color' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
|
||||||
resultDict.setdefault(dictIndex, []).append(info)
|
resultDict.setdefault(dictIndex, []).append(info)
|
||||||
consumedList.append(info)
|
consumedList.append(info)
|
||||||
break
|
break
|
||||||
|
|
||||||
# Compare depth
|
# Compare depth
|
||||||
if hasDepthProfile:
|
if hasDepthProfile:
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info in consumedList:
|
if info in consumedList:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info.sensorType == 'depth' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
|
if info.sensorType == 'depth' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
|
||||||
resultDict.setdefault(dictIndex, []).append(info)
|
resultDict.setdefault(dictIndex, []).append(info)
|
||||||
consumedList.append(info)
|
consumedList.append(info)
|
||||||
break
|
break
|
||||||
|
|
||||||
# Compare IR
|
# Compare IR
|
||||||
if hasIRProfile:
|
if hasIRProfile:
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info in consumedList:
|
if info in consumedList:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info.sensorType == 'ir' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
|
if info.sensorType == 'ir' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
|
||||||
resultDict.setdefault(dictIndex, []).append(info)
|
resultDict.setdefault(dictIndex, []).append(info)
|
||||||
consumedList.append(info)
|
consumedList.append(info)
|
||||||
break
|
break
|
||||||
|
|
||||||
# Compare IR Left
|
# Compare IR Left
|
||||||
if hasIRLeftProfile:
|
if hasIRLeftProfile:
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info in consumedList:
|
if info in consumedList:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info.sensorType == 'ir_left' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
|
if info.sensorType == 'ir_left' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
|
||||||
resultDict.setdefault(dictIndex, []).append(info)
|
resultDict.setdefault(dictIndex, []).append(info)
|
||||||
consumedList.append(info)
|
consumedList.append(info)
|
||||||
break
|
break
|
||||||
|
|
||||||
# Compare IR Right
|
# Compare IR Right
|
||||||
if hasIRRightProfile:
|
if hasIRRightProfile:
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
if info.deviceId == primaryId and info.sensorType == comparePic.sensorType:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info in consumedList:
|
if info in consumedList:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if info.sensorType == 'ir_right' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
|
if info.sensorType == 'ir_right' and abs(info.syncTimeStamp - comparePic.syncTimeStamp) < frameTspHalfGap:
|
||||||
resultDict.setdefault(dictIndex, []).append(info)
|
resultDict.setdefault(dictIndex, []).append(info)
|
||||||
consumedList.append(info)
|
consumedList.append(info)
|
||||||
break
|
break
|
||||||
|
|
||||||
# Calculate deviation
|
# Calculate deviation
|
||||||
minTsp = min(resultDict[dictIndex], key=lambda x: x.syncTimeStamp)
|
minTsp = min(resultDict[dictIndex], key=lambda x: x.syncTimeStamp)
|
||||||
for info in resultDict[dictIndex]:
|
for info in resultDict[dictIndex]:
|
||||||
info.tspDiff = info.syncTimeStamp - minTsp.syncTimeStamp
|
info.tspDiff = info.syncTimeStamp - minTsp.syncTimeStamp
|
||||||
|
|
||||||
dictIndex += 1
|
dictIndex += 1
|
||||||
|
|
||||||
return resultDict
|
return resultDict
|
||||||
|
|
||||||
|
|
||||||
def safe_make_dir(path):
|
def safe_make_dir(path):
|
||||||
if not os.path.exists(path):
|
if not os.path.exists(path):
|
||||||
os.makedirs(path)
|
os.makedirs(path)
|
||||||
|
|
||||||
|
|
||||||
def handleSyncFrames():
|
def handleSyncFrames():
|
||||||
global resultPath
|
global resultPath
|
||||||
global sourceFramesPath
|
global sourceFramesPath
|
||||||
global streamProfileDict
|
global streamProfileDict
|
||||||
|
|
||||||
fp = open(f"{resultPath}/frameMatchLog.txt", "w")
|
fp = open(f"{resultPath}/frameMatchLog.txt", "w")
|
||||||
|
|
||||||
if not initProfileInfoDict():
|
if not initProfileInfoDict():
|
||||||
print("Initialize stream profile dictionary failed. exit")
|
print("Initialize stream profile dictionary failed. exit")
|
||||||
return
|
return
|
||||||
print(f"Stream profiles: {streamProfileDict}")
|
print(f"Stream profiles: {streamProfileDict}")
|
||||||
streamProfileCount = len(streamProfileDict.items())
|
streamProfileCount = len(streamProfileDict.items())
|
||||||
|
|
||||||
pictureInfoDict = {}
|
pictureInfoDict = {}
|
||||||
|
|
||||||
initPictureInfoDictionary(Path(sourceFramesPath), pictureInfoDict)
|
initPictureInfoDictionary(Path(sourceFramesPath), pictureInfoDict)
|
||||||
if len(pictureInfoDict) <= 0:
|
if len(pictureInfoDict) <= 0:
|
||||||
print("init pictureInfoDict failed. pictureInfoDict.len = 0")
|
print("init pictureInfoDict failed. pictureInfoDict.len = 0")
|
||||||
return
|
return
|
||||||
|
|
||||||
# # Dump pictureInfoDict
|
# # Dump pictureInfoDict
|
||||||
# for key in pictureInfoDict:
|
# for key in pictureInfoDict:
|
||||||
# print("===================key:%s" % key)
|
# print("===================key:%s" % key)
|
||||||
# listTmp = list(pictureInfoDict[key])
|
# listTmp = list(pictureInfoDict[key])
|
||||||
# for info in listTmp:
|
# for info in listTmp:
|
||||||
# print("=====================value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s" % (info.deviceId,info.sensorType,info.syncTimeStamp,info.picturePath))
|
# print("=====================value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s" % (info.deviceId,info.sensorType,info.syncTimeStamp,info.picturePath))
|
||||||
|
|
||||||
deviceCount = getDeviceCount()
|
deviceCount = getDeviceCount()
|
||||||
print("=================device count:%d" % deviceCount)
|
print("=================device count:%d" % deviceCount)
|
||||||
|
|
||||||
resultDict = {}
|
resultDict = {}
|
||||||
resultDict = matchFrame(pictureInfoDict)
|
resultDict = matchFrame(pictureInfoDict)
|
||||||
|
|
||||||
for key in resultDict:
|
for key in resultDict:
|
||||||
fp.write("===================result key:%s\n" % key)
|
fp.write("===================result key:%s\n" % key)
|
||||||
print("===================result key:%s" % key)
|
print("===================result key:%s" % key)
|
||||||
listTmp = list(resultDict[key])
|
listTmp = list(resultDict[key])
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
fp.write("=====================result value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s\n" % (
|
fp.write("=====================result value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s\n" % (
|
||||||
info.deviceId, info.sensorType, info.syncTimeStamp, info.picturePath))
|
info.deviceId, info.sensorType, info.syncTimeStamp, info.picturePath))
|
||||||
print("=====================result value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s" % (
|
print("=====================result value : deviceId:%s\tsensorType:%s\tsyncTimeStamp:%s\tpicturePath:%s" % (
|
||||||
info.deviceId, info.sensorType, info.syncTimeStamp, info.picturePath))
|
info.deviceId, info.sensorType, info.syncTimeStamp, info.picturePath))
|
||||||
|
|
||||||
matchPath = f"{resultPath}/matchFrames/"
|
matchPath = f"{resultPath}/matchFrames/"
|
||||||
safe_make_dir(matchPath)
|
safe_make_dir(matchPath)
|
||||||
notMatchPath = f"{resultPath}/notMatchFrames/"
|
notMatchPath = f"{resultPath}/notMatchFrames/"
|
||||||
abnormalPath = f"{resultPath}/abnormal/"
|
abnormalPath = f"{resultPath}/abnormal/"
|
||||||
|
|
||||||
for key in resultDict:
|
for key in resultDict:
|
||||||
listTmp = list(resultDict[key])
|
listTmp = list(resultDict[key])
|
||||||
if (len(listTmp) == (deviceCount * streamProfileCount)):
|
if (len(listTmp) == (deviceCount * streamProfileCount)):
|
||||||
haveAbnormalData = False
|
haveAbnormalData = False
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
if info.tspDiff >= tspRangeThreshold:
|
if info.tspDiff >= tspRangeThreshold:
|
||||||
path = matchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
path = matchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
||||||
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + "_xxxxxx" + "_"+ str(info.exp) + "_"+ str(info.gain) + info.fileExt
|
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + "_xxxxxx" + "_"+ str(info.exp) + "_"+ str(info.gain) + info.fileExt
|
||||||
shutil.copy(info.picturePath, path)
|
shutil.copy(info.picturePath, path)
|
||||||
haveAbnormalData = True
|
haveAbnormalData = True
|
||||||
else:
|
else:
|
||||||
path = matchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
path = matchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
||||||
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + "_"+ str(info.exp) + "_"+ str(info.gain) + info.fileExt
|
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + "_"+ str(info.exp) + "_"+ str(info.gain) + info.fileExt
|
||||||
shutil.copy(info.picturePath, path)
|
shutil.copy(info.picturePath, path)
|
||||||
|
|
||||||
if haveAbnormalData:
|
if haveAbnormalData:
|
||||||
safe_make_dir(abnormalPath)
|
safe_make_dir(abnormalPath)
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
if info.tspDiff >= tspRangeThreshold:
|
if info.tspDiff >= tspRangeThreshold:
|
||||||
path = abnormalPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
path = abnormalPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
||||||
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + "_xxxxxx" + "_"+ str(info.exp) + "_"+ str(info.gain) + info.fileExt
|
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + "_xxxxxx" + "_"+ str(info.exp) + "_"+ str(info.gain) + info.fileExt
|
||||||
shutil.copy(info.picturePath, path)
|
shutil.copy(info.picturePath, path)
|
||||||
else:
|
else:
|
||||||
path = abnormalPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
path = abnormalPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
||||||
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + "_"+ str(info.exp) + "_"+ str(info.gain) + info.fileExt
|
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + "_"+ str(info.exp) + "_"+ str(info.gain) + info.fileExt
|
||||||
shutil.copy(info.picturePath, path)
|
shutil.copy(info.picturePath, path)
|
||||||
else:
|
else:
|
||||||
safe_make_dir(notMatchPath)
|
safe_make_dir(notMatchPath)
|
||||||
for info in listTmp:
|
for info in listTmp:
|
||||||
newFilePath = notMatchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
newFilePath = notMatchPath + str(key) + "_" + info.sensorType + "_" + info.deviceIdFull + "_" + str(
|
||||||
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + "_"+ str(info.exp) + "_"+ str(info.gain) + info.fileExt
|
info.syncTimeStamp) + "_[" + str(info.tspDiff) + "]" + "_"+ str(info.exp) + "_"+ str(info.gain) + info.fileExt
|
||||||
shutil.copy(info.picturePath, newFilePath)
|
shutil.copy(info.picturePath, newFilePath)
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
if not initPrimaryId():
|
if not initPrimaryId():
|
||||||
print("Initialize primaryId failed. exit.")
|
print("Initialize primaryId failed. exit.")
|
||||||
return
|
return
|
||||||
|
|
||||||
if not initSyncConfigParams():
|
if not initSyncConfigParams():
|
||||||
print("Initialized Sync config parameter failed. exit.")
|
print("Initialized Sync config parameter failed. exit.")
|
||||||
return
|
return
|
||||||
|
|
||||||
initResultDir()
|
initResultDir()
|
||||||
|
|
||||||
print(f"PrimaryId={primaryId}, frameRate={frameRate}, tspRangeThreshold={tspRangeThreshold}")
|
print(f"PrimaryId={primaryId}, frameRate={frameRate}, tspRangeThreshold={tspRangeThreshold}")
|
||||||
handleSyncFrames()
|
handleSyncFrames()
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
parser = argparse.ArgumentParser(description="Synchronize frames support for 'Orbbec Devices'")
|
parser = argparse.ArgumentParser(description="Synchronize frames support for 'Orbbec Devices'")
|
||||||
parser.add_argument('frames_dir', type=str, help="Frames directory")
|
parser.add_argument('frames_dir', type=str, help="Frames directory")
|
||||||
parser.add_argument('main_script_root_dir', type=str, help="SyncFramesMain.py working directory")
|
parser.add_argument('main_script_root_dir', type=str, help="SyncFramesMain.py working directory")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
sourceRootPath = args.frames_dir
|
sourceRootPath = args.frames_dir
|
||||||
sourceFramesPath = f"{args.frames_dir}/TotalModeFrames"
|
sourceFramesPath = f"{args.frames_dir}/TotalModeFrames"
|
||||||
mainPythonWorkPath = args.main_script_root_dir
|
mainPythonWorkPath = args.main_script_root_dir
|
||||||
print(f"Start of CommonFrameMatch synchronize frame. sourceRootPath={sourceRootPath}")
|
print(f"Start of CommonFrameMatch synchronize frame. sourceRootPath={sourceRootPath}")
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|
||||||
print("Finish of CommonFrameMatch synchronize frame.")
|
print("Finish of CommonFrameMatch synchronize frame.")
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
std_msgs/Header header
|
std_msgs/Header header
|
||||||
string name
|
string name
|
||||||
string serial_number
|
string serial_number
|
||||||
string firmware_version
|
string firmware_version
|
||||||
string supported_min_sdk_version
|
string supported_min_sdk_version
|
||||||
string current_sdk_version
|
string current_sdk_version
|
||||||
string hardware_version
|
string hardware_version
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
---
|
---
|
||||||
sensor_msgs/CameraInfo info
|
sensor_msgs/CameraInfo info
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
---
|
---
|
||||||
DeviceInfo info
|
DeviceInfo info
|
||||||
bool success
|
bool success
|
||||||
string message
|
string message
|
||||||
@@ -1,418 +1,418 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!-- This URDF was automatically created by SolidWorks to URDF Exporter! Originally created by Stephen Brawner ([email protected])
|
<!-- This URDF was automatically created by SolidWorks to URDF Exporter! Originally created by Stephen Brawner ([email protected])
|
||||||
Commit Version: 1.6.0-4-g7f85cfe Build Version: 1.6.7995.38578
|
Commit Version: 1.6.0-4-g7f85cfe Build Version: 1.6.7995.38578
|
||||||
For more information, please see http://wiki.ros.org/sw_urdf_exporter -->
|
For more information, please see http://wiki.ros.org/sw_urdf_exporter -->
|
||||||
<robot xmlns:xacro="http://ros.org/wiki/xacro" name="astra_2">
|
<robot xmlns:xacro="http://ros.org/wiki/xacro" name="astra_2">
|
||||||
<xacro:property name="mesh_path" value="package://orbbec_description/meshes/astra2/" />
|
<xacro:property name="mesh_path" value="package://orbbec_description/meshes/astra2/" />
|
||||||
<link
|
<link
|
||||||
name="camera_link">
|
name="camera_link">
|
||||||
<inertial>
|
<inertial>
|
||||||
<origin
|
<origin
|
||||||
xyz="-0.0160938085585399 -0.00100885505248632 0.0279919581775268"
|
xyz="-0.0160938085585399 -0.00100885505248632 0.0279919581775268"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<mass
|
<mass
|
||||||
value="0.0101524380243699" />
|
value="0.0101524380243699" />
|
||||||
<inertia
|
<inertia
|
||||||
ixx="1.69184979927567E-05"
|
ixx="1.69184979927567E-05"
|
||||||
ixy="-8.18066547859061E-09"
|
ixy="-8.18066547859061E-09"
|
||||||
ixz="-1.27426373196599E-09"
|
ixz="-1.27426373196599E-09"
|
||||||
iyy="7.7096717121366E-07"
|
iyy="7.7096717121366E-07"
|
||||||
iyz="1.08838945581987E-08"
|
iyz="1.08838945581987E-08"
|
||||||
izz="1.61801971464778E-05" />
|
izz="1.61801971464778E-05" />
|
||||||
</inertial>
|
</inertial>
|
||||||
<visual>
|
<visual>
|
||||||
<origin
|
<origin
|
||||||
xyz="-0.012323995999904 -0.0374999999985815 -0.0281503197112"
|
xyz="-0.012323995999904 -0.0374999999985815 -0.0281503197112"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<geometry>
|
<geometry>
|
||||||
<mesh
|
<mesh
|
||||||
filename="${mesh_path}base_link.STL" />
|
filename="${mesh_path}base_link.STL" />
|
||||||
</geometry>
|
</geometry>
|
||||||
<material
|
<material
|
||||||
name="">
|
name="">
|
||||||
<color
|
<color
|
||||||
rgba="0.827450980392157 0.698039215686274 0.490196078431373 1" />
|
rgba="0.827450980392157 0.698039215686274 0.490196078431373 1" />
|
||||||
</material>
|
</material>
|
||||||
</visual>
|
</visual>
|
||||||
<collision>
|
<collision>
|
||||||
<origin
|
<origin
|
||||||
xyz="-0.012323995999904 -0.0374999999985815 -0.0281503197112"
|
xyz="-0.012323995999904 -0.0374999999985815 -0.0281503197112"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<geometry>
|
<geometry>
|
||||||
<mesh
|
<mesh
|
||||||
filename="${mesh_path}base_link.STL" />
|
filename="${mesh_path}base_link.STL" />
|
||||||
</geometry>
|
</geometry>
|
||||||
</collision>
|
</collision>
|
||||||
</link>
|
</link>
|
||||||
<link
|
<link
|
||||||
name="camera_bottom_screw_frame">
|
name="camera_bottom_screw_frame">
|
||||||
<inertial>
|
<inertial>
|
||||||
<origin
|
<origin
|
||||||
xyz="-0.00635589512085941 1.59480886486103E-08 0.0118534361269284"
|
xyz="-0.00635589512085941 1.59480886486103E-08 0.0118534361269284"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<mass
|
<mass
|
||||||
value="0.00583601107155577" />
|
value="0.00583601107155577" />
|
||||||
<inertia
|
<inertia
|
||||||
ixx="3.65092579901689E-06"
|
ixx="3.65092579901689E-06"
|
||||||
ixy="-5.00479838523244E-12"
|
ixy="-5.00479838523244E-12"
|
||||||
ixz="7.68810468643615E-07"
|
ixz="7.68810468643615E-07"
|
||||||
iyy="2.03966087595316E-06"
|
iyy="2.03966087595316E-06"
|
||||||
iyz="6.18841137398479E-13"
|
iyz="6.18841137398479E-13"
|
||||||
izz="3.65126403038314E-06" />
|
izz="3.65126403038314E-06" />
|
||||||
</inertial>
|
</inertial>
|
||||||
<visual>
|
<visual>
|
||||||
<origin
|
<origin
|
||||||
xyz="0 0 0"
|
xyz="0 0 0"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<geometry>
|
<geometry>
|
||||||
<mesh
|
<mesh
|
||||||
filename="${mesh_path}camera_bottom_screw_frame.STL" />
|
filename="${mesh_path}camera_bottom_screw_frame.STL" />
|
||||||
</geometry>
|
</geometry>
|
||||||
<material
|
<material
|
||||||
name="">
|
name="">
|
||||||
<color
|
<color
|
||||||
rgba="0.266666666666667 0.266666666666667 0.266666666666667 1" />
|
rgba="0.266666666666667 0.266666666666667 0.266666666666667 1" />
|
||||||
</material>
|
</material>
|
||||||
</visual>
|
</visual>
|
||||||
<collision>
|
<collision>
|
||||||
<origin
|
<origin
|
||||||
xyz="0 0 0"
|
xyz="0 0 0"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<geometry>
|
<geometry>
|
||||||
<mesh
|
<mesh
|
||||||
filename="${mesh_path}camera_bottom_screw_frame.STL" />
|
filename="${mesh_path}camera_bottom_screw_frame.STL" />
|
||||||
</geometry>
|
</geometry>
|
||||||
</collision>
|
</collision>
|
||||||
</link>
|
</link>
|
||||||
<joint
|
<joint
|
||||||
name="camera_bottom_screw_joint"
|
name="camera_bottom_screw_joint"
|
||||||
type="fixed">
|
type="fixed">
|
||||||
<origin
|
<origin
|
||||||
xyz="-0.012323995999904 -0.0374999999985815 -0.0281503197112"
|
xyz="-0.012323995999904 -0.0374999999985815 -0.0281503197112"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<parent
|
<parent
|
||||||
link="camera_link" />
|
link="camera_link" />
|
||||||
<child
|
<child
|
||||||
link="camera_bottom_screw_frame" />
|
link="camera_bottom_screw_frame" />
|
||||||
<axis
|
<axis
|
||||||
xyz="0 0 0" />
|
xyz="0 0 0" />
|
||||||
</joint>
|
</joint>
|
||||||
<link
|
<link
|
||||||
name="camera_ir_frame">
|
name="camera_ir_frame">
|
||||||
<inertial>
|
<inertial>
|
||||||
<origin
|
<origin
|
||||||
xyz="-0.00168460453866946 5.33451517362171E-07 6.08796009742363E-07"
|
xyz="-0.00168460453866946 5.33451517362171E-07 6.08796009742363E-07"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<mass
|
<mass
|
||||||
value="0.000608348661221201" />
|
value="0.000608348661221201" />
|
||||||
<inertia
|
<inertia
|
||||||
ixx="6.79778952271057E-09"
|
ixx="6.79778952271057E-09"
|
||||||
ixy="8.05787556448484E-13"
|
ixy="8.05787556448484E-13"
|
||||||
ixz="9.13275008053385E-13"
|
ixz="9.13275008053385E-13"
|
||||||
iyy="8.07147396496025E-09"
|
iyy="8.07147396496025E-09"
|
||||||
iyz="1.28152628023355E-12"
|
iyz="1.28152628023355E-12"
|
||||||
izz="8.07148645937271E-09" />
|
izz="8.07148645937271E-09" />
|
||||||
</inertial>
|
</inertial>
|
||||||
<visual>
|
<visual>
|
||||||
<origin
|
<origin
|
||||||
xyz="0 0 0"
|
xyz="0 0 0"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<geometry>
|
<geometry>
|
||||||
<mesh
|
<mesh
|
||||||
filename="${mesh_path}camera_infra1_frame.STL" />
|
filename="${mesh_path}camera_infra1_frame.STL" />
|
||||||
</geometry>
|
</geometry>
|
||||||
<material
|
<material
|
||||||
name="">
|
name="">
|
||||||
<color
|
<color
|
||||||
rgba="0.792156862745098 0.819607843137255 0.933333333333333 1" />
|
rgba="0.792156862745098 0.819607843137255 0.933333333333333 1" />
|
||||||
</material>
|
</material>
|
||||||
</visual>
|
</visual>
|
||||||
<collision>
|
<collision>
|
||||||
<origin
|
<origin
|
||||||
xyz="0 0 0"
|
xyz="0 0 0"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<geometry>
|
<geometry>
|
||||||
<mesh
|
<mesh
|
||||||
filename="${mesh_path}camera_infra1_frame.STL" />
|
filename="${mesh_path}camera_infra1_frame.STL" />
|
||||||
</geometry>
|
</geometry>
|
||||||
</collision>
|
</collision>
|
||||||
</link>
|
</link>
|
||||||
<joint
|
<joint
|
||||||
name="camera_ir_joint"
|
name="camera_ir_joint"
|
||||||
type="fixed">
|
type="fixed">
|
||||||
<origin
|
<origin
|
||||||
xyz="0 0 0"
|
xyz="0 0 0"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<parent
|
<parent
|
||||||
link="camera_depth_frame" />
|
link="camera_depth_frame" />
|
||||||
<child
|
<child
|
||||||
link="camera_ir_frame" />
|
link="camera_ir_frame" />
|
||||||
<axis
|
<axis
|
||||||
xyz="0 0 0" />
|
xyz="0 0 0" />
|
||||||
</joint>
|
</joint>
|
||||||
<link
|
<link
|
||||||
name="camera_ir_optical_frame">
|
name="camera_ir_optical_frame">
|
||||||
<inertial>
|
<inertial>
|
||||||
<origin
|
<origin
|
||||||
xyz="-5.33451517362171E-07 -6.0879600974216E-07 -0.00168460453866946"
|
xyz="-5.33451517362171E-07 -6.0879600974216E-07 -0.00168460453866946"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<mass
|
<mass
|
||||||
value="0.000608348661221202" />
|
value="0.000608348661221202" />
|
||||||
<inertia
|
<inertia
|
||||||
ixx="8.07147396496025E-09"
|
ixx="8.07147396496025E-09"
|
||||||
ixy="1.28152628023355E-12"
|
ixy="1.28152628023355E-12"
|
||||||
ixz="-8.0578755644897E-13"
|
ixz="-8.0578755644897E-13"
|
||||||
iyy="8.07148645937271E-09"
|
iyy="8.07148645937271E-09"
|
||||||
iyz="-9.13275008052949E-13"
|
iyz="-9.13275008052949E-13"
|
||||||
izz="6.79778952271057E-09" />
|
izz="6.79778952271057E-09" />
|
||||||
</inertial>
|
</inertial>
|
||||||
<visual>
|
<visual>
|
||||||
<origin
|
<origin
|
||||||
xyz="0 0 0"
|
xyz="0 0 0"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<geometry>
|
<geometry>
|
||||||
<mesh
|
<mesh
|
||||||
filename="${mesh_path}camera_infra1_optical_frame.STL" />
|
filename="${mesh_path}camera_infra1_optical_frame.STL" />
|
||||||
</geometry>
|
</geometry>
|
||||||
<material
|
<material
|
||||||
name="">
|
name="">
|
||||||
<color
|
<color
|
||||||
rgba="0.792156862745098 0.819607843137255 0.933333333333333 1" />
|
rgba="0.792156862745098 0.819607843137255 0.933333333333333 1" />
|
||||||
</material>
|
</material>
|
||||||
</visual>
|
</visual>
|
||||||
<collision>
|
<collision>
|
||||||
<origin
|
<origin
|
||||||
xyz="0 0 0"
|
xyz="0 0 0"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<geometry>
|
<geometry>
|
||||||
<mesh
|
<mesh
|
||||||
filename="${mesh_path}camera_infra1_optical_frame.STL" />
|
filename="${mesh_path}camera_infra1_optical_frame.STL" />
|
||||||
</geometry>
|
</geometry>
|
||||||
</collision>
|
</collision>
|
||||||
</link>
|
</link>
|
||||||
<joint
|
<joint
|
||||||
name="camera_ir_optical_joint"
|
name="camera_ir_optical_joint"
|
||||||
type="fixed">
|
type="fixed">
|
||||||
<origin
|
<origin
|
||||||
xyz="0 0 0"
|
xyz="0 0 0"
|
||||||
rpy="-1.5707963267949 0 -1.5707963267949" />
|
rpy="-1.5707963267949 0 -1.5707963267949" />
|
||||||
<parent
|
<parent
|
||||||
link="camera_ir_frame" />
|
link="camera_ir_frame" />
|
||||||
<child
|
<child
|
||||||
link="camera_ir_optical_frame" />
|
link="camera_ir_optical_frame" />
|
||||||
<axis
|
<axis
|
||||||
xyz="0 0 0" />
|
xyz="0 0 0" />
|
||||||
</joint>
|
</joint>
|
||||||
<link
|
<link
|
||||||
name="camera_color_frame">
|
name="camera_color_frame">
|
||||||
<inertial>
|
<inertial>
|
||||||
<origin
|
<origin
|
||||||
xyz="-0.0010912488631539 -4.73353451897057E-07 7.19396296308746E-07"
|
xyz="-0.0010912488631539 -4.73353451897057E-07 7.19396296308746E-07"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<mass
|
<mass
|
||||||
value="7.68929599151334E-05" />
|
value="7.68929599151334E-05" />
|
||||||
<inertia
|
<inertia
|
||||||
ixx="3.55949372682833E-10"
|
ixx="3.55949372682833E-10"
|
||||||
ixy="-6.02255513042918E-14"
|
ixy="-6.02255513042918E-14"
|
||||||
ixz="-1.32613402096388E-13"
|
ixz="-1.32613402096388E-13"
|
||||||
iyy="2.2724816811302E-10"
|
iyy="2.2724816811302E-10"
|
||||||
iyz="-4.27828382910552E-14"
|
iyz="-4.27828382910552E-14"
|
||||||
izz="2.2743913744705E-10" />
|
izz="2.2743913744705E-10" />
|
||||||
</inertial>
|
</inertial>
|
||||||
<visual>
|
<visual>
|
||||||
<origin
|
<origin
|
||||||
xyz="0 0 0"
|
xyz="0 0 0"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<geometry>
|
<geometry>
|
||||||
<mesh
|
<mesh
|
||||||
filename="${mesh_path}camera_colorl_frame.STL" />
|
filename="${mesh_path}camera_colorl_frame.STL" />
|
||||||
</geometry>
|
</geometry>
|
||||||
<material
|
<material
|
||||||
name="">
|
name="">
|
||||||
<color
|
<color
|
||||||
rgba="0.792156862745098 0.819607843137255 0.933333333333333 1" />
|
rgba="0.792156862745098 0.819607843137255 0.933333333333333 1" />
|
||||||
</material>
|
</material>
|
||||||
</visual>
|
</visual>
|
||||||
<collision>
|
<collision>
|
||||||
<origin
|
<origin
|
||||||
xyz="0 0 0"
|
xyz="0 0 0"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<geometry>
|
<geometry>
|
||||||
<mesh
|
<mesh
|
||||||
filename="${mesh_path}camera_colorl_frame.STL" />
|
filename="${mesh_path}camera_colorl_frame.STL" />
|
||||||
</geometry>
|
</geometry>
|
||||||
</collision>
|
</collision>
|
||||||
</link>
|
</link>
|
||||||
<joint
|
<joint
|
||||||
name="camera_color_joint"
|
name="camera_color_joint"
|
||||||
type="fixed">
|
type="fixed">
|
||||||
<origin
|
<origin
|
||||||
xyz="0.0025420000310987234 -0.01850000023841858 0"
|
xyz="0.0025420000310987234 -0.01850000023841858 0"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<parent
|
<parent
|
||||||
link="camera_depth_frame" />
|
link="camera_depth_frame" />
|
||||||
<child
|
<child
|
||||||
link="camera_color_frame" />
|
link="camera_color_frame" />
|
||||||
<axis
|
<axis
|
||||||
xyz="0 0 0" />
|
xyz="0 0 0" />
|
||||||
</joint>
|
</joint>
|
||||||
<link
|
<link
|
||||||
name="camera_color_optical_frame">
|
name="camera_color_optical_frame">
|
||||||
<inertial>
|
<inertial>
|
||||||
<origin
|
<origin
|
||||||
xyz="4.73353451897057E-07 -7.19396296308746E-07 -0.0010912488631539"
|
xyz="4.73353451897057E-07 -7.19396296308746E-07 -0.0010912488631539"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<mass
|
<mass
|
||||||
value="7.68929599151334E-05" />
|
value="7.68929599151334E-05" />
|
||||||
<inertia
|
<inertia
|
||||||
ixx="2.2724816811302E-10"
|
ixx="2.2724816811302E-10"
|
||||||
ixy="-4.27828382910548E-14"
|
ixy="-4.27828382910548E-14"
|
||||||
ixz="6.02255513042915E-14"
|
ixz="6.02255513042915E-14"
|
||||||
iyy="2.2743913744705E-10"
|
iyy="2.2743913744705E-10"
|
||||||
iyz="1.32613402096386E-13"
|
iyz="1.32613402096386E-13"
|
||||||
izz="3.55949372682833E-10" />
|
izz="3.55949372682833E-10" />
|
||||||
</inertial>
|
</inertial>
|
||||||
<visual>
|
<visual>
|
||||||
<origin
|
<origin
|
||||||
xyz="0 0 0"
|
xyz="0 0 0"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<geometry>
|
<geometry>
|
||||||
<mesh
|
<mesh
|
||||||
filename="${mesh_path}camera_color_optical_frame.STL" />
|
filename="${mesh_path}camera_color_optical_frame.STL" />
|
||||||
</geometry>
|
</geometry>
|
||||||
<material
|
<material
|
||||||
name="">
|
name="">
|
||||||
<color
|
<color
|
||||||
rgba="0.792156862745098 0.819607843137255 0.933333333333333 1" />
|
rgba="0.792156862745098 0.819607843137255 0.933333333333333 1" />
|
||||||
</material>
|
</material>
|
||||||
</visual>
|
</visual>
|
||||||
<collision>
|
<collision>
|
||||||
<origin
|
<origin
|
||||||
xyz="0 0 0"
|
xyz="0 0 0"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<geometry>
|
<geometry>
|
||||||
<mesh
|
<mesh
|
||||||
filename="${mesh_path}camera_color_optical_frame.STL" />
|
filename="${mesh_path}camera_color_optical_frame.STL" />
|
||||||
</geometry>
|
</geometry>
|
||||||
</collision>
|
</collision>
|
||||||
</link>
|
</link>
|
||||||
<joint
|
<joint
|
||||||
name="camera_color_optical_joint"
|
name="camera_color_optical_joint"
|
||||||
type="fixed">
|
type="fixed">
|
||||||
<origin
|
<origin
|
||||||
xyz="0 0 0"
|
xyz="0 0 0"
|
||||||
rpy="-1.5707963267949 0 -1.5707963267949" />
|
rpy="-1.5707963267949 0 -1.5707963267949" />
|
||||||
<parent
|
<parent
|
||||||
link="camera_color_frame" />
|
link="camera_color_frame" />
|
||||||
<child
|
<child
|
||||||
link="camera_color_optical_frame" />
|
link="camera_color_optical_frame" />
|
||||||
<axis
|
<axis
|
||||||
xyz="0 0 0" />
|
xyz="0 0 0" />
|
||||||
</joint>
|
</joint>
|
||||||
<link
|
<link
|
||||||
name="camera_depth_frame">
|
name="camera_depth_frame">
|
||||||
<inertial>
|
<inertial>
|
||||||
<origin
|
<origin
|
||||||
xyz="-0.00168460453866946 5.33451517362171E-07 6.08796009742395E-07"
|
xyz="-0.00168460453866946 5.33451517362171E-07 6.08796009742395E-07"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<mass
|
<mass
|
||||||
value="0.000608348661221201" />
|
value="0.000608348661221201" />
|
||||||
<inertia
|
<inertia
|
||||||
ixx="6.79778952271057E-09"
|
ixx="6.79778952271057E-09"
|
||||||
ixy="8.05787556448476E-13"
|
ixy="8.05787556448476E-13"
|
||||||
ixz="9.13275008053388E-13"
|
ixz="9.13275008053388E-13"
|
||||||
iyy="8.07147396496025E-09"
|
iyy="8.07147396496025E-09"
|
||||||
iyz="1.28152628023353E-12"
|
iyz="1.28152628023353E-12"
|
||||||
izz="8.07148645937271E-09" />
|
izz="8.07148645937271E-09" />
|
||||||
</inertial>
|
</inertial>
|
||||||
<visual>
|
<visual>
|
||||||
<origin
|
<origin
|
||||||
xyz="0 0 0"
|
xyz="0 0 0"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<geometry>
|
<geometry>
|
||||||
<mesh
|
<mesh
|
||||||
filename="${mesh_path}camera_depth_frame.STL" />
|
filename="${mesh_path}camera_depth_frame.STL" />
|
||||||
</geometry>
|
</geometry>
|
||||||
<material
|
<material
|
||||||
name="">
|
name="">
|
||||||
<color
|
<color
|
||||||
rgba="0.792156862745098 0.819607843137255 0.933333333333333 1" />
|
rgba="0.792156862745098 0.819607843137255 0.933333333333333 1" />
|
||||||
</material>
|
</material>
|
||||||
</visual>
|
</visual>
|
||||||
<collision>
|
<collision>
|
||||||
<origin
|
<origin
|
||||||
xyz="0 0 0"
|
xyz="0 0 0"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<geometry>
|
<geometry>
|
||||||
<mesh
|
<mesh
|
||||||
filename="${mesh_path}camera_depth_frame.STL" />
|
filename="${mesh_path}camera_depth_frame.STL" />
|
||||||
</geometry>
|
</geometry>
|
||||||
</collision>
|
</collision>
|
||||||
</link>
|
</link>
|
||||||
<joint
|
<joint
|
||||||
name="camera_depth_joint"
|
name="camera_depth_joint"
|
||||||
type="fixed">
|
type="fixed">
|
||||||
<origin
|
<origin
|
||||||
xyz="0 0 0"
|
xyz="0 0 0"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<parent
|
<parent
|
||||||
link="camera_link" />
|
link="camera_link" />
|
||||||
<child
|
<child
|
||||||
link="camera_depth_frame" />
|
link="camera_depth_frame" />
|
||||||
<axis
|
<axis
|
||||||
xyz="0 0 0" />
|
xyz="0 0 0" />
|
||||||
</joint>
|
</joint>
|
||||||
<link
|
<link
|
||||||
name="camera_depth_optical_frame">
|
name="camera_depth_optical_frame">
|
||||||
<inertial>
|
<inertial>
|
||||||
<origin
|
<origin
|
||||||
xyz="-5.33451517362171E-07 -6.08796009742075E-07 -0.00168460453866946"
|
xyz="-5.33451517362171E-07 -6.08796009742075E-07 -0.00168460453866946"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<mass
|
<mass
|
||||||
value="0.000608348661221202" />
|
value="0.000608348661221202" />
|
||||||
<inertia
|
<inertia
|
||||||
ixx="8.07147396496025E-09"
|
ixx="8.07147396496025E-09"
|
||||||
ixy="1.28152628023353E-12"
|
ixy="1.28152628023353E-12"
|
||||||
ixz="-8.05787556448886E-13"
|
ixz="-8.05787556448886E-13"
|
||||||
iyy="8.07148645937271E-09"
|
iyy="8.07148645937271E-09"
|
||||||
iyz="-9.13275008052966E-13"
|
iyz="-9.13275008052966E-13"
|
||||||
izz="6.79778952271057E-09" />
|
izz="6.79778952271057E-09" />
|
||||||
</inertial>
|
</inertial>
|
||||||
<visual>
|
<visual>
|
||||||
<origin
|
<origin
|
||||||
xyz="0 0 0"
|
xyz="0 0 0"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<geometry>
|
<geometry>
|
||||||
<mesh
|
<mesh
|
||||||
filename="${mesh_path}camera_depth_optical_frame.STL" />
|
filename="${mesh_path}camera_depth_optical_frame.STL" />
|
||||||
</geometry>
|
</geometry>
|
||||||
<material
|
<material
|
||||||
name="">
|
name="">
|
||||||
<color
|
<color
|
||||||
rgba="0.792156862745098 0.819607843137255 0.933333333333333 1" />
|
rgba="0.792156862745098 0.819607843137255 0.933333333333333 1" />
|
||||||
</material>
|
</material>
|
||||||
</visual>
|
</visual>
|
||||||
<collision>
|
<collision>
|
||||||
<origin
|
<origin
|
||||||
xyz="0 0 0"
|
xyz="0 0 0"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<geometry>
|
<geometry>
|
||||||
<mesh
|
<mesh
|
||||||
filename="${mesh_path}camera_depth_optical_frame.STL" />
|
filename="${mesh_path}camera_depth_optical_frame.STL" />
|
||||||
</geometry>
|
</geometry>
|
||||||
</collision>
|
</collision>
|
||||||
</link>
|
</link>
|
||||||
<joint
|
<joint
|
||||||
name="camera_depth_optical_joint"
|
name="camera_depth_optical_joint"
|
||||||
type="fixed">
|
type="fixed">
|
||||||
<origin
|
<origin
|
||||||
xyz="0 0 0"
|
xyz="0 0 0"
|
||||||
rpy="-1.5707963267949 0 -1.5707963267949" />
|
rpy="-1.5707963267949 0 -1.5707963267949" />
|
||||||
<parent
|
<parent
|
||||||
link="camera_depth_frame" />
|
link="camera_depth_frame" />
|
||||||
<child
|
<child
|
||||||
link="camera_depth_optical_frame" />
|
link="camera_depth_optical_frame" />
|
||||||
<axis
|
<axis
|
||||||
xyz="0 0 0" />
|
xyz="0 0 0" />
|
||||||
</joint>
|
</joint>
|
||||||
</robot>
|
</robot>
|
||||||
|
|||||||
@@ -1,471 +1,471 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!-- This URDF was automatically created by SolidWorks to URDF Exporter! Originally created by Stephen Brawner ([email protected])
|
<!-- This URDF was automatically created by SolidWorks to URDF Exporter! Originally created by Stephen Brawner ([email protected])
|
||||||
Commit Version: 1.6.0-4-g7f85cfe Build Version: 1.6.7995.38578
|
Commit Version: 1.6.0-4-g7f85cfe Build Version: 1.6.7995.38578
|
||||||
For more information, please see http://wiki.ros.org/sw_urdf_exporter -->
|
For more information, please see http://wiki.ros.org/sw_urdf_exporter -->
|
||||||
<robot xmlns:xacro="http://ros.org/wiki/xacro" name="gemini_2">
|
<robot xmlns:xacro="http://ros.org/wiki/xacro" name="gemini_2">
|
||||||
<xacro:property name="mesh_path" value="package://orbbec_description/meshes/gemini2/" />
|
<xacro:property name="mesh_path" value="package://orbbec_description/meshes/gemini2/" />
|
||||||
<link
|
<link
|
||||||
name="camera_link">
|
name="camera_link">
|
||||||
<inertial>
|
<inertial>
|
||||||
<origin
|
<origin
|
||||||
xyz="0.0027714370634978 -9.29434319373592E-06 0.0128014057830239"
|
xyz="0.0027714370634978 -9.29434319373592E-06 0.0128014057830239"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<mass
|
<mass
|
||||||
value="0.0186201988654731" />
|
value="0.0186201988654731" />
|
||||||
<inertia
|
<inertia
|
||||||
ixx="1.38952652762223E-05"
|
ixx="1.38952652762223E-05"
|
||||||
ixy="-4.88105621547421E-09"
|
ixy="-4.88105621547421E-09"
|
||||||
ixz="1.98670223779875E-08"
|
ixz="1.98670223779875E-08"
|
||||||
iyy="1.7072236178685E-06"
|
iyy="1.7072236178685E-06"
|
||||||
iyz="-8.49860443053716E-09"
|
iyz="-8.49860443053716E-09"
|
||||||
izz="1.31795237727551E-05" />
|
izz="1.31795237727551E-05" />
|
||||||
</inertial>
|
</inertial>
|
||||||
<visual>
|
<visual>
|
||||||
<origin
|
<origin
|
||||||
xyz="-0.01491 -0.025 -0.0125"
|
xyz="-0.01491 -0.025 -0.0125"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<geometry>
|
<geometry>
|
||||||
<mesh
|
<mesh
|
||||||
filename="${mesh_path}base_link.STL" />
|
filename="${mesh_path}base_link.STL" />
|
||||||
</geometry>
|
</geometry>
|
||||||
<material
|
<material
|
||||||
name="">
|
name="">
|
||||||
<color
|
<color
|
||||||
rgba="0.792156862745098 0.819607843137255 0.933333333333333 1" />
|
rgba="0.792156862745098 0.819607843137255 0.933333333333333 1" />
|
||||||
</material>
|
</material>
|
||||||
</visual>
|
</visual>
|
||||||
<collision>
|
<collision>
|
||||||
<origin
|
<origin
|
||||||
xyz="-0.01491 -0.025 -0.0125"
|
xyz="-0.01491 -0.025 -0.0125"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<geometry>
|
<geometry>
|
||||||
<mesh
|
<mesh
|
||||||
filename="${mesh_path}base_link.STL" />
|
filename="${mesh_path}base_link.STL" />
|
||||||
</geometry>
|
</geometry>
|
||||||
</collision>
|
</collision>
|
||||||
</link>
|
</link>
|
||||||
<link
|
<link
|
||||||
name="camera_botter_screw_frame">
|
name="camera_botter_screw_frame">
|
||||||
<inertial>
|
<inertial>
|
||||||
<origin
|
<origin
|
||||||
xyz="0.00255175353418556 -0.00123907270798541 0.0118889783016768"
|
xyz="0.00255175353418556 -0.00123907270798541 0.0118889783016768"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<mass
|
<mass
|
||||||
value="0.00564464822744556" />
|
value="0.00564464822744556" />
|
||||||
<inertia
|
<inertia
|
||||||
ixx="3.07688942133184E-06"
|
ixx="3.07688942133184E-06"
|
||||||
ixy="-1.84968755859098E-08"
|
ixy="-1.84968755859098E-08"
|
||||||
ixz="-9.2787127214088E-09"
|
ixz="-9.2787127214088E-09"
|
||||||
iyy="2.27625032346061E-07"
|
iyy="2.27625032346061E-07"
|
||||||
iyz="1.65176768024159E-08"
|
iyz="1.65176768024159E-08"
|
||||||
izz="2.93984854119768E-06" />
|
izz="2.93984854119768E-06" />
|
||||||
</inertial>
|
</inertial>
|
||||||
<visual>
|
<visual>
|
||||||
<origin
|
<origin
|
||||||
xyz="0 0 0"
|
xyz="0 0 0"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<geometry>
|
<geometry>
|
||||||
<mesh
|
<mesh
|
||||||
filename="${mesh_path}camera_botter_screw_frame.STL" />
|
filename="${mesh_path}camera_botter_screw_frame.STL" />
|
||||||
</geometry>
|
</geometry>
|
||||||
<material
|
<material
|
||||||
name="">
|
name="">
|
||||||
<color
|
<color
|
||||||
rgba="0.792156862745098 0.819607843137255 0.933333333333333 1" />
|
rgba="0.792156862745098 0.819607843137255 0.933333333333333 1" />
|
||||||
</material>
|
</material>
|
||||||
</visual>
|
</visual>
|
||||||
<collision>
|
<collision>
|
||||||
<origin
|
<origin
|
||||||
xyz="0 0 0"
|
xyz="0 0 0"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<geometry>
|
<geometry>
|
||||||
<mesh
|
<mesh
|
||||||
filename="${mesh_path}camera_botter_screw_frame.STL" />
|
filename="${mesh_path}camera_botter_screw_frame.STL" />
|
||||||
</geometry>
|
</geometry>
|
||||||
</collision>
|
</collision>
|
||||||
</link>
|
</link>
|
||||||
<joint
|
<joint
|
||||||
name="camera_botter_screw_joint"
|
name="camera_botter_screw_joint"
|
||||||
type="fixed">
|
type="fixed">
|
||||||
<origin
|
<origin
|
||||||
xyz="-0.01491 -0.025 -0.0125"
|
xyz="-0.01491 -0.025 -0.0125"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<parent
|
<parent
|
||||||
link="camera_link" />
|
link="camera_link" />
|
||||||
<child
|
<child
|
||||||
link="camera_botter_screw_frame" />
|
link="camera_botter_screw_frame" />
|
||||||
<axis
|
<axis
|
||||||
xyz="0 0 0" />
|
xyz="0 0 0" />
|
||||||
</joint>
|
</joint>
|
||||||
<link
|
<link
|
||||||
name="camera_right_ir_frame">
|
name="camera_right_ir_frame">
|
||||||
<inertial>
|
<inertial>
|
||||||
<origin
|
<origin
|
||||||
xyz="-0.000620201436687004 -1.61358465547434E-08 -1.50984520398332E-07"
|
xyz="-0.000620201436687004 -1.61358465547434E-08 -1.50984520398332E-07"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<mass
|
<mass
|
||||||
value="0.000453168343720438" />
|
value="0.000453168343720438" />
|
||||||
<inertia
|
<inertia
|
||||||
ixx="4.34107789199216E-09"
|
ixx="4.34107789199216E-09"
|
||||||
ixy="-3.70099015891851E-13"
|
ixy="-3.70099015891851E-13"
|
||||||
ixz="-1.46784711283119E-13"
|
ixz="-1.46784711283119E-13"
|
||||||
iyy="4.84012228066652E-09"
|
iyy="4.84012228066652E-09"
|
||||||
iyz="2.0076254107311E-14"
|
iyz="2.0076254107311E-14"
|
||||||
izz="4.84044599033091E-09" />
|
izz="4.84044599033091E-09" />
|
||||||
</inertial>
|
</inertial>
|
||||||
<visual>
|
<visual>
|
||||||
<origin
|
<origin
|
||||||
xyz="0 0 0"
|
xyz="0 0 0"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<geometry>
|
<geometry>
|
||||||
<mesh
|
<mesh
|
||||||
filename="${mesh_path}camera_infra1_frame.STL" />
|
filename="${mesh_path}camera_infra1_frame.STL" />
|
||||||
</geometry>
|
</geometry>
|
||||||
<material
|
<material
|
||||||
name="">
|
name="">
|
||||||
<color
|
<color
|
||||||
rgba="0.792156862745098 0.819607843137255 0.933333333333333 1" />
|
rgba="0.792156862745098 0.819607843137255 0.933333333333333 1" />
|
||||||
</material>
|
</material>
|
||||||
</visual>
|
</visual>
|
||||||
<collision>
|
<collision>
|
||||||
<origin
|
<origin
|
||||||
xyz="0 0 0"
|
xyz="0 0 0"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<geometry>
|
<geometry>
|
||||||
<mesh
|
<mesh
|
||||||
filename="${mesh_path}camera_infra1_frame.STL" />
|
filename="${mesh_path}camera_infra1_frame.STL" />
|
||||||
</geometry>
|
</geometry>
|
||||||
</collision>
|
</collision>
|
||||||
</link>
|
</link>
|
||||||
<joint
|
<joint
|
||||||
name="camera_right_ir_joint"
|
name="camera_right_ir_joint"
|
||||||
type="fixed">
|
type="fixed">
|
||||||
<origin
|
<origin
|
||||||
xyz="0 -0.05000000074505806 0"
|
xyz="0 -0.05000000074505806 0"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<parent
|
<parent
|
||||||
link="camera_depth_frame" />
|
link="camera_depth_frame" />
|
||||||
<child
|
<child
|
||||||
link="camera_right_ir_frame" />
|
link="camera_right_ir_frame" />
|
||||||
<axis
|
<axis
|
||||||
xyz="0 0 0" />
|
xyz="0 0 0" />
|
||||||
</joint>
|
</joint>
|
||||||
<link
|
<link
|
||||||
name="camera_right_ir_optical_frame">
|
name="camera_right_ir_optical_frame">
|
||||||
<inertial>
|
<inertial>
|
||||||
<origin
|
<origin
|
||||||
xyz="1.61358465547434E-08 1.50984520398324E-07 -0.000620201436687004"
|
xyz="1.61358465547434E-08 1.50984520398324E-07 -0.000620201436687004"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<mass
|
<mass
|
||||||
value="0.000453168343720438" />
|
value="0.000453168343720438" />
|
||||||
<inertia
|
<inertia
|
||||||
ixx="4.84012228066652E-09"
|
ixx="4.84012228066652E-09"
|
||||||
ixy="2.00762541073067E-14"
|
ixy="2.00762541073067E-14"
|
||||||
ixz="3.70099015891915E-13"
|
ixz="3.70099015891915E-13"
|
||||||
iyy="4.84044599033091E-09"
|
iyy="4.84044599033091E-09"
|
||||||
iyz="1.46784711283141E-13"
|
iyz="1.46784711283141E-13"
|
||||||
izz="4.34107789199216E-09" />
|
izz="4.34107789199216E-09" />
|
||||||
</inertial>
|
</inertial>
|
||||||
<visual>
|
<visual>
|
||||||
<origin
|
<origin
|
||||||
xyz="0 0 0"
|
xyz="0 0 0"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<geometry>
|
<geometry>
|
||||||
<mesh
|
<mesh
|
||||||
filename="${mesh_path}camera_infra1_optical_frame.STL" />
|
filename="${mesh_path}camera_infra1_optical_frame.STL" />
|
||||||
</geometry>
|
</geometry>
|
||||||
<material
|
<material
|
||||||
name="">
|
name="">
|
||||||
<color
|
<color
|
||||||
rgba="0.792156862745098 0.819607843137255 0.933333333333333 1" />
|
rgba="0.792156862745098 0.819607843137255 0.933333333333333 1" />
|
||||||
</material>
|
</material>
|
||||||
</visual>
|
</visual>
|
||||||
<collision>
|
<collision>
|
||||||
<origin
|
<origin
|
||||||
xyz="0 0 0"
|
xyz="0 0 0"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<geometry>
|
<geometry>
|
||||||
<mesh
|
<mesh
|
||||||
filename="${mesh_path}camera_infra1_optical_frame.STL" />
|
filename="${mesh_path}camera_infra1_optical_frame.STL" />
|
||||||
</geometry>
|
</geometry>
|
||||||
</collision>
|
</collision>
|
||||||
</link>
|
</link>
|
||||||
<joint
|
<joint
|
||||||
name="camera_right_ir_optical_joint"
|
name="camera_right_ir_optical_joint"
|
||||||
type="fixed">
|
type="fixed">
|
||||||
<origin
|
<origin
|
||||||
xyz="0 0 0"
|
xyz="0 0 0"
|
||||||
rpy="-1.5707963267949 0 -1.5707963267949" />
|
rpy="-1.5707963267949 0 -1.5707963267949" />
|
||||||
<parent
|
<parent
|
||||||
link="camera_right_ir_frame" />
|
link="camera_right_ir_frame" />
|
||||||
<child
|
<child
|
||||||
link="camera_right_ir_optical_frame" />
|
link="camera_right_ir_optical_frame" />
|
||||||
<axis
|
<axis
|
||||||
xyz="0 0 0" />
|
xyz="0 0 0" />
|
||||||
</joint>
|
</joint>
|
||||||
<link
|
<link
|
||||||
name="camera_color_frame">
|
name="camera_color_frame">
|
||||||
<inertial>
|
<inertial>
|
||||||
<origin
|
<origin
|
||||||
xyz="2.29364384785394E-07 -2.11520958501546E-07 -0.00105779474323097"
|
xyz="2.29364384785394E-07 -2.11520958501546E-07 -0.00105779474323097"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<mass
|
<mass
|
||||||
value="0.000139779411914196" />
|
value="0.000139779411914196" />
|
||||||
<inertia
|
<inertia
|
||||||
ixx="6.11273726117097E-10"
|
ixx="6.11273726117097E-10"
|
||||||
ixy="3.95051289663905E-14"
|
ixy="3.95051289663905E-14"
|
||||||
ixz="1.55845266007242E-13"
|
ixz="1.55845266007242E-13"
|
||||||
iyy="6.11076547268852E-10"
|
iyy="6.11076547268852E-10"
|
||||||
iyz="2.25440284353371E-14"
|
iyz="2.25440284353371E-14"
|
||||||
izz="6.69129408711142E-10" />
|
izz="6.69129408711142E-10" />
|
||||||
</inertial>
|
</inertial>
|
||||||
<visual>
|
<visual>
|
||||||
<origin
|
<origin
|
||||||
xyz="0 0 0"
|
xyz="0 0 0"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<geometry>
|
<geometry>
|
||||||
<mesh
|
<mesh
|
||||||
filename="${mesh_path}camera_color_frame.STL" />
|
filename="${mesh_path}camera_color_frame.STL" />
|
||||||
</geometry>
|
</geometry>
|
||||||
<material
|
<material
|
||||||
name="">
|
name="">
|
||||||
<color
|
<color
|
||||||
rgba="0.792156862745098 0.819607843137255 0.933333333333333 1" />
|
rgba="0.792156862745098 0.819607843137255 0.933333333333333 1" />
|
||||||
</material>
|
</material>
|
||||||
</visual>
|
</visual>
|
||||||
<collision>
|
<collision>
|
||||||
<origin
|
<origin
|
||||||
xyz="0 0 0"
|
xyz="0 0 0"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<geometry>
|
<geometry>
|
||||||
<mesh
|
<mesh
|
||||||
filename="${mesh_path}camera_color_frame.STL" />
|
filename="${mesh_path}camera_color_frame.STL" />
|
||||||
</geometry>
|
</geometry>
|
||||||
</collision>
|
</collision>
|
||||||
</link>
|
</link>
|
||||||
<joint
|
<joint
|
||||||
name="camera_color_joint"
|
name="camera_color_joint"
|
||||||
type="fixed">
|
type="fixed">
|
||||||
<origin
|
<origin
|
||||||
xyz="0.0019099999917671084 -0.01400499977171421 4.999999873689376e-06"
|
xyz="0.0019099999917671084 -0.01400499977171421 4.999999873689376e-06"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<parent
|
<parent
|
||||||
link="camera_depth_frame" />
|
link="camera_depth_frame" />
|
||||||
<child
|
<child
|
||||||
link="camera_color_frame" />
|
link="camera_color_frame" />
|
||||||
<axis
|
<axis
|
||||||
xyz="0 0 0" />
|
xyz="0 0 0" />
|
||||||
</joint>
|
</joint>
|
||||||
<link
|
<link
|
||||||
name="camera_color_optical_frame">
|
name="camera_color_optical_frame">
|
||||||
<inertial>
|
<inertial>
|
||||||
<origin
|
<origin
|
||||||
xyz="2.29364384785394E-07 -2.11520958501541E-07 -0.00105779474323097"
|
xyz="2.29364384785394E-07 -2.11520958501541E-07 -0.00105779474323097"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<mass
|
<mass
|
||||||
value="0.000139779411914196" />
|
value="0.000139779411914196" />
|
||||||
<inertia
|
<inertia
|
||||||
ixx="6.11273726117097E-10"
|
ixx="6.11273726117097E-10"
|
||||||
ixy="3.95051289663901E-14"
|
ixy="3.95051289663901E-14"
|
||||||
ixz="1.55845266007242E-13"
|
ixz="1.55845266007242E-13"
|
||||||
iyy="6.11076547268852E-10"
|
iyy="6.11076547268852E-10"
|
||||||
iyz="2.25440284353391E-14"
|
iyz="2.25440284353391E-14"
|
||||||
izz="6.69129408711142E-10" />
|
izz="6.69129408711142E-10" />
|
||||||
</inertial>
|
</inertial>
|
||||||
<visual>
|
<visual>
|
||||||
<origin
|
<origin
|
||||||
xyz="0 0 0"
|
xyz="0 0 0"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<geometry>
|
<geometry>
|
||||||
<mesh
|
<mesh
|
||||||
filename="${mesh_path}camera_color_optical_frame.STL" />
|
filename="${mesh_path}camera_color_optical_frame.STL" />
|
||||||
</geometry>
|
</geometry>
|
||||||
<material
|
<material
|
||||||
name="">
|
name="">
|
||||||
<color
|
<color
|
||||||
rgba="0.792156862745098 0.819607843137255 0.933333333333333 1" />
|
rgba="0.792156862745098 0.819607843137255 0.933333333333333 1" />
|
||||||
</material>
|
</material>
|
||||||
</visual>
|
</visual>
|
||||||
<collision>
|
<collision>
|
||||||
<origin
|
<origin
|
||||||
xyz="0 0 0"
|
xyz="0 0 0"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<geometry>
|
<geometry>
|
||||||
<mesh
|
<mesh
|
||||||
filename="${mesh_path}camera_color_optical_frame.STL" />
|
filename="${mesh_path}camera_color_optical_frame.STL" />
|
||||||
</geometry>
|
</geometry>
|
||||||
</collision>
|
</collision>
|
||||||
</link>
|
</link>
|
||||||
<joint
|
<joint
|
||||||
name="camera_color_optical_joint"
|
name="camera_color_optical_joint"
|
||||||
type="fixed">
|
type="fixed">
|
||||||
<origin
|
<origin
|
||||||
xyz="0 0 0"
|
xyz="0 0 0"
|
||||||
rpy="-1.5707963267949 0 -1.5707963267949" />
|
rpy="-1.5707963267949 0 -1.5707963267949" />
|
||||||
<parent
|
<parent
|
||||||
link="camera_color_frame" />
|
link="camera_color_frame" />
|
||||||
<child
|
<child
|
||||||
link="camera_color_optical_frame" />
|
link="camera_color_optical_frame" />
|
||||||
<axis
|
<axis
|
||||||
xyz="0 0 0" />
|
xyz="0 0 0" />
|
||||||
</joint>
|
</joint>
|
||||||
<link
|
<link
|
||||||
name="camera_left_ir_frame">
|
name="camera_left_ir_frame">
|
||||||
<inertial>
|
<inertial>
|
||||||
<origin
|
<origin
|
||||||
xyz="-0.000620201436687001 -1.6135846551274E-08 -1.50984520410662E-07"
|
xyz="-0.000620201436687001 -1.6135846551274E-08 -1.50984520410662E-07"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<mass
|
<mass
|
||||||
value="0.000453168343720439" />
|
value="0.000453168343720439" />
|
||||||
<inertia
|
<inertia
|
||||||
ixx="4.34107789199216E-09"
|
ixx="4.34107789199216E-09"
|
||||||
ixy="-3.70099015888916E-13"
|
ixy="-3.70099015888916E-13"
|
||||||
ixz="-1.46784711288897E-13"
|
ixz="-1.46784711288897E-13"
|
||||||
iyy="4.84012228066651E-09"
|
iyy="4.84012228066651E-09"
|
||||||
iyz="2.0076254105875E-14"
|
iyz="2.0076254105875E-14"
|
||||||
izz="4.8404459903309E-09" />
|
izz="4.8404459903309E-09" />
|
||||||
</inertial>
|
</inertial>
|
||||||
<visual>
|
<visual>
|
||||||
<origin
|
<origin
|
||||||
xyz="0 0 0"
|
xyz="0 0 0"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<geometry>
|
<geometry>
|
||||||
<mesh
|
<mesh
|
||||||
filename="${mesh_path}camera_infra2_frame.STL" />
|
filename="${mesh_path}camera_infra2_frame.STL" />
|
||||||
</geometry>
|
</geometry>
|
||||||
<material
|
<material
|
||||||
name="">
|
name="">
|
||||||
<color
|
<color
|
||||||
rgba="0.792156862745098 0.819607843137255 0.933333333333333 1" />
|
rgba="0.792156862745098 0.819607843137255 0.933333333333333 1" />
|
||||||
</material>
|
</material>
|
||||||
</visual>
|
</visual>
|
||||||
<collision>
|
<collision>
|
||||||
<origin
|
<origin
|
||||||
xyz="0 0 0"
|
xyz="0 0 0"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<geometry>
|
<geometry>
|
||||||
<mesh
|
<mesh
|
||||||
filename="${mesh_path}camera_infra2_frame.STL" />
|
filename="${mesh_path}camera_infra2_frame.STL" />
|
||||||
</geometry>
|
</geometry>
|
||||||
</collision>
|
</collision>
|
||||||
</link>
|
</link>
|
||||||
<joint
|
<joint
|
||||||
name="camera_left_ir_joint"
|
name="camera_left_ir_joint"
|
||||||
type="fixed">
|
type="fixed">
|
||||||
<origin
|
<origin
|
||||||
xyz="0 0 0"
|
xyz="0 0 0"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<parent
|
<parent
|
||||||
link="camera_link" />
|
link="camera_link" />
|
||||||
<child
|
<child
|
||||||
link="camera_left_ir_frame" />
|
link="camera_left_ir_frame" />
|
||||||
<axis
|
<axis
|
||||||
xyz="0 0 0" />
|
xyz="0 0 0" />
|
||||||
</joint>
|
</joint>
|
||||||
<link
|
<link
|
||||||
name="camera_left_ir_optical_frame">
|
name="camera_left_ir_optical_frame">
|
||||||
<inertial>
|
<inertial>
|
||||||
<origin
|
<origin
|
||||||
xyz="1.6135846551274E-08 1.50984520410652E-07 -0.000620201436687001"
|
xyz="1.6135846551274E-08 1.50984520410652E-07 -0.000620201436687001"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<mass
|
<mass
|
||||||
value="0.000453168343720439" />
|
value="0.000453168343720439" />
|
||||||
<inertia
|
<inertia
|
||||||
ixx="4.84012228066652E-09"
|
ixx="4.84012228066652E-09"
|
||||||
ixy="2.00762541058687E-14"
|
ixy="2.00762541058687E-14"
|
||||||
ixz="3.70099015888909E-13"
|
ixz="3.70099015888909E-13"
|
||||||
iyy="4.8404459903309E-09"
|
iyy="4.8404459903309E-09"
|
||||||
iyz="1.46784711288896E-13"
|
iyz="1.46784711288896E-13"
|
||||||
izz="4.34107789199216E-09" />
|
izz="4.34107789199216E-09" />
|
||||||
</inertial>
|
</inertial>
|
||||||
<visual>
|
<visual>
|
||||||
<origin
|
<origin
|
||||||
xyz="0 0 0"
|
xyz="0 0 0"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<geometry>
|
<geometry>
|
||||||
<mesh
|
<mesh
|
||||||
filename="${mesh_path}camera_infra2_optical_frame.STL" />
|
filename="${mesh_path}camera_infra2_optical_frame.STL" />
|
||||||
</geometry>
|
</geometry>
|
||||||
<material
|
<material
|
||||||
name="">
|
name="">
|
||||||
<color
|
<color
|
||||||
rgba="0.792156862745098 0.819607843137255 0.933333333333333 1" />
|
rgba="0.792156862745098 0.819607843137255 0.933333333333333 1" />
|
||||||
</material>
|
</material>
|
||||||
</visual>
|
</visual>
|
||||||
<collision>
|
<collision>
|
||||||
<origin
|
<origin
|
||||||
xyz="0 0 0"
|
xyz="0 0 0"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<geometry>
|
<geometry>
|
||||||
<mesh
|
<mesh
|
||||||
filename="${mesh_path}camera_infra2_optical_frame.STL" />
|
filename="${mesh_path}camera_infra2_optical_frame.STL" />
|
||||||
</geometry>
|
</geometry>
|
||||||
</collision>
|
</collision>
|
||||||
</link>
|
</link>
|
||||||
<joint
|
<joint
|
||||||
name="camera_left_ir_optical_joint"
|
name="camera_left_ir_optical_joint"
|
||||||
type="fixed">
|
type="fixed">
|
||||||
<origin
|
<origin
|
||||||
xyz="0 0 0"
|
xyz="0 0 0"
|
||||||
rpy="-1.5707963267949 0 -1.5707963267949" />
|
rpy="-1.5707963267949 0 -1.5707963267949" />
|
||||||
<parent
|
<parent
|
||||||
link="camera_left_ir_frame" />
|
link="camera_left_ir_frame" />
|
||||||
<child
|
<child
|
||||||
link="camera_left_ir_optical_frame" />
|
link="camera_left_ir_optical_frame" />
|
||||||
<axis
|
<axis
|
||||||
xyz="0 0 0" />
|
xyz="0 0 0" />
|
||||||
</joint>
|
</joint>
|
||||||
<link
|
<link
|
||||||
name="camera_depth_frame">
|
name="camera_depth_frame">
|
||||||
<inertial>
|
<inertial>
|
||||||
<origin
|
<origin
|
||||||
xyz="-0.000620201436687001 -1.6135846551274E-08 -1.50984520410661E-07"
|
xyz="-0.000620201436687001 -1.6135846551274E-08 -1.50984520410661E-07"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<mass
|
<mass
|
||||||
value="0.000453168343720439" />
|
value="0.000453168343720439" />
|
||||||
<inertia
|
<inertia
|
||||||
ixx="4.34107789199216E-09"
|
ixx="4.34107789199216E-09"
|
||||||
ixy="-3.70099015888929E-13"
|
ixy="-3.70099015888929E-13"
|
||||||
ixz="-1.46784711288886E-13"
|
ixz="-1.46784711288886E-13"
|
||||||
iyy="4.84012228066651E-09"
|
iyy="4.84012228066651E-09"
|
||||||
iyz="2.00762541058859E-14"
|
iyz="2.00762541058859E-14"
|
||||||
izz="4.8404459903309E-09" />
|
izz="4.8404459903309E-09" />
|
||||||
</inertial>
|
</inertial>
|
||||||
<visual>
|
<visual>
|
||||||
<origin
|
<origin
|
||||||
xyz="0 0 0"
|
xyz="0 0 0"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<geometry>
|
<geometry>
|
||||||
<mesh
|
<mesh
|
||||||
filename="${mesh_path}camera_depth_frame.STL" />
|
filename="${mesh_path}camera_depth_frame.STL" />
|
||||||
</geometry>
|
</geometry>
|
||||||
<material
|
<material
|
||||||
name="">
|
name="">
|
||||||
<color
|
<color
|
||||||
rgba="0.792156862745098 0.819607843137255 0.933333333333333 1" />
|
rgba="0.792156862745098 0.819607843137255 0.933333333333333 1" />
|
||||||
</material>
|
</material>
|
||||||
</visual>
|
</visual>
|
||||||
<collision>
|
<collision>
|
||||||
<origin
|
<origin
|
||||||
xyz="0 0 0"
|
xyz="0 0 0"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<geometry>
|
<geometry>
|
||||||
<mesh
|
<mesh
|
||||||
filename="${mesh_path}camera_depth_frame.STL" />
|
filename="${mesh_path}camera_depth_frame.STL" />
|
||||||
</geometry>
|
</geometry>
|
||||||
</collision>
|
</collision>
|
||||||
</link>
|
</link>
|
||||||
<joint
|
<joint
|
||||||
name="camera_depth_joint"
|
name="camera_depth_joint"
|
||||||
type="fixed">
|
type="fixed">
|
||||||
<origin
|
<origin
|
||||||
xyz="0 0 0"
|
xyz="0 0 0"
|
||||||
rpy="0 0 0" />
|
rpy="0 0 0" />
|
||||||
<parent
|
<parent
|
||||||
link="camera_link" />
|
link="camera_link" />
|
||||||
<child
|
<child
|
||||||
link="camera_depth_frame" />
|
link="camera_depth_frame" />
|
||||||
<axis
|
<axis
|
||||||
xyz="0 0 0" />
|
xyz="0 0 0" />
|
||||||
</joint>
|
</joint>
|
||||||
</robot>
|
</robot>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user