make variables public, vesion variable and minor changes
This commit is contained in:
@@ -5,12 +5,12 @@
|
|||||||
1. 根据平台和python 版本下载对应的`.whl`文件
|
1. 根据平台和python 版本下载对应的`.whl`文件
|
||||||
2. 运行pip命令安装:
|
2. 运行pip命令安装:
|
||||||
```bash
|
```bash
|
||||||
pip install orisys-{version}-{python}-none-{os}_amd64.whl
|
pip install orisys-{version}-{python-version}-none-{os}_amd64.whl
|
||||||
```
|
```
|
||||||
3. 并测试导入:
|
3. 并测试导入:
|
||||||
```python
|
```python
|
||||||
import orisys
|
import orisys
|
||||||
orisys.__version__
|
print(orisys.__version__)
|
||||||
```
|
```
|
||||||
---
|
---
|
||||||
## `Sensor` 类别
|
## `Sensor` 类别
|
||||||
@@ -39,7 +39,7 @@ sensor = Sensor("/data/data.mp4")
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 2. `get_img` 方法
|
## 2. `Sensor.get_img` 方法
|
||||||
|
|
||||||
### 描述
|
### 描述
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ if img is None:
|
|||||||
```
|
```
|
||||||
---
|
---
|
||||||
|
|
||||||
## 3. `compute_deformation` 方法
|
## 3. `Sensor.compute_deformation` 方法
|
||||||
|
|
||||||
### 描述
|
### 描述
|
||||||
|
|
||||||
@@ -81,7 +81,7 @@ if img is None:
|
|||||||
sensor.compute_deformation()
|
sensor.compute_deformation()
|
||||||
```
|
```
|
||||||
---
|
---
|
||||||
## 4. `compute_contact` 方法
|
## 4. `Sensor.compute_contact` 方法
|
||||||
|
|
||||||
### 描述
|
### 描述
|
||||||
基于已计算的法向形变场进行接触区域分析,输出接触质心与轮廓等信息,并生成接触强度图。
|
基于已计算的法向形变场进行接触区域分析,输出接触质心与轮廓等信息,并生成接触强度图。
|
||||||
@@ -120,7 +120,7 @@ centroid, contour, depth = sensor.read_info(
|
|||||||
)
|
)
|
||||||
```
|
```
|
||||||
---
|
---
|
||||||
## 4. `read_info` 方法
|
## 4. `Sensor.read_info` 方法
|
||||||
|
|
||||||
### 描述
|
### 描述
|
||||||
|
|
||||||
@@ -176,7 +176,7 @@ flow = sensor.read_info(sensor.info.VRAW)
|
|||||||
```
|
```
|
||||||
---
|
---
|
||||||
|
|
||||||
## 5. `disconnect` 方法
|
## 5. `Sensor.disconnect` 方法
|
||||||
|
|
||||||
### 描述
|
### 描述
|
||||||
|
|
||||||
@@ -188,21 +188,7 @@ flow = sensor.read_info(sensor.info.VRAW)
|
|||||||
---
|
---
|
||||||
# 配置标定相关
|
# 配置标定相关
|
||||||
|
|
||||||
## 1. `export_config` 方法
|
## 1. `list_config` 方法
|
||||||
|
|
||||||
### 描述
|
|
||||||
导出当前传感器实例使用的配置参数字典。
|
|
||||||
|
|
||||||
### 输入参数
|
|
||||||
* **config_name**: 需要导出的配置参数字典名字`str`
|
|
||||||
* **path**: 导出的路径,默认`"./config/exported_config.json"`
|
|
||||||
|
|
||||||
### 返回
|
|
||||||
|
|
||||||
* `dict`: 导出的配置参数字典。
|
|
||||||
|
|
||||||
---
|
|
||||||
## 2. `list_config` 方法
|
|
||||||
|
|
||||||
### 描述
|
### 描述
|
||||||
列出内置传感器配置参数字典。
|
列出内置传感器配置参数字典。
|
||||||
@@ -210,6 +196,23 @@ flow = sensor.read_info(sensor.info.VRAW)
|
|||||||
### 返回
|
### 返回
|
||||||
|
|
||||||
* `list`: 内置传感器配置参数字典的名字列表。
|
* `list`: 内置传感器配置参数字典的名字列表。
|
||||||
|
---
|
||||||
|
## 2. `export_config` 方法
|
||||||
|
|
||||||
|
### 描述
|
||||||
|
导出当前传感器实例使用的配置参数字典。
|
||||||
|
|
||||||
|
### 输入参数
|
||||||
|
* **config_name**: 需要导出的配置参数字典名字,`str`
|
||||||
|
* **path**: 导出的路径,默认`"./config/exported_config.json"`
|
||||||
|
|
||||||
|
### 返回
|
||||||
|
|
||||||
|
* `dict`: 导出的配置参数字典。
|
||||||
|
|
||||||
|
### 保存
|
||||||
|
|
||||||
|
* 导出内置的`config_name`配置参数字典至`path`
|
||||||
|
|
||||||
---
|
---
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ import platform
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
# Package version
|
||||||
|
VERSION = "0.2.0"
|
||||||
|
|
||||||
# Python versions to build for
|
# Python versions to build for
|
||||||
PYTHON_VERSIONS = ['3.8', '3.9', '3.10']
|
PYTHON_VERSIONS = ['3.8', '3.9', '3.10']
|
||||||
|
|
||||||
@@ -157,7 +160,7 @@ def copy_additional_files():
|
|||||||
shutil.copytree('config', 'dist_obfuscated/config', dirs_exist_ok=True)
|
shutil.copytree('config', 'dist_obfuscated/config', dirs_exist_ok=True)
|
||||||
|
|
||||||
# Copy README and other metadata files
|
# Copy README and other metadata files
|
||||||
files_to_copy = ['README.md', 'Readme(未完成).md', 'requirements.txt', 'LICENSE']
|
files_to_copy = ['README.md', 'requirements.txt', 'LICENSE']
|
||||||
for file in files_to_copy:
|
for file in files_to_copy:
|
||||||
if os.path.exists(file):
|
if os.path.exists(file):
|
||||||
print(f"Copying {file}...")
|
print(f"Copying {file}...")
|
||||||
@@ -217,7 +220,7 @@ for pkg in packages:
|
|||||||
|
|
||||||
setup(
|
setup(
|
||||||
name="orisys",
|
name="orisys",
|
||||||
version="0.2.0",
|
version="{VERSION}",
|
||||||
description="Orisys - Optical Tactile Sensor SDK (Protected)",
|
description="Orisys - Optical Tactile Sensor SDK (Protected)",
|
||||||
author="Your Name",
|
author="Your Name",
|
||||||
package_dir={{"": "src"}},
|
package_dir={{"": "src"}},
|
||||||
@@ -335,7 +338,7 @@ def build_wheel_for_version(python_version):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
print(f"✅ Wheel for Python {python_version} on {PLATFORM_NAME} built successfully!")
|
print(f"✅ Wheel for Python {python_version} on {PLATFORM_NAME} built successfully!")
|
||||||
print(f" Expected: orisys-0.2.0-{py_tag}-none-{plat_tag}.whl")
|
print(f" Expected: orisys-{VERSION}-{py_tag}-none-{plat_tag}.whl")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
@@ -444,7 +447,7 @@ def main():
|
|||||||
for wheel in Path(f'dist/{PLATFORM_NAME}').glob('*.whl'):
|
for wheel in Path(f'dist/{PLATFORM_NAME}').glob('*.whl'):
|
||||||
print(f" - {wheel.name}")
|
print(f" - {wheel.name}")
|
||||||
print("\nInstall with:")
|
print("\nInstall with:")
|
||||||
print(f" pip install dist/{PLATFORM_NAME}/orisys-0.2.0-*.whl")
|
print(f" pip install dist/{PLATFORM_NAME}/orisys-{VERSION}-*.whl")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
+12
-3
@@ -1,5 +1,5 @@
|
|||||||
"""
|
"""
|
||||||
Orisys - Optical Tactile Sensor SDK
|
orisys - Optical Tactile Sensor SDK
|
||||||
|
|
||||||
A Python library for processing and analyzing optical tactile sensor data,
|
A Python library for processing and analyzing optical tactile sensor data,
|
||||||
including image stitching, optical flow tracking, and deformation decomposition.
|
including image stitching, optical flow tracking, and deformation decomposition.
|
||||||
@@ -9,7 +9,6 @@ __version__ = "0.2.0"
|
|||||||
__author__ = "Orisys"
|
__author__ = "Orisys"
|
||||||
|
|
||||||
from .sensor import Sensor
|
from .sensor import Sensor
|
||||||
from .MultiSensor import MultiSensor
|
|
||||||
from . import util
|
from . import util
|
||||||
from . import configs
|
from . import configs
|
||||||
|
|
||||||
@@ -17,4 +16,14 @@ from . import configs
|
|||||||
list_config = configs.list_config
|
list_config = configs.list_config
|
||||||
export_config = configs.export_config
|
export_config = configs.export_config
|
||||||
|
|
||||||
__all__ = ['Sensor', 'MultiSensor', 'util', 'list_config', 'export_config']
|
__all__ = [
|
||||||
|
# class
|
||||||
|
'Sensor',
|
||||||
|
|
||||||
|
# util functions
|
||||||
|
'util',
|
||||||
|
|
||||||
|
# configs utilities functions
|
||||||
|
'list_config',
|
||||||
|
'export_config'
|
||||||
|
]
|
||||||
|
|||||||
@@ -67,6 +67,29 @@ def list_config():
|
|||||||
config_files = sorted(CONFIG_DIR.glob("*.json"))
|
config_files = sorted(CONFIG_DIR.glob("*.json"))
|
||||||
return [f.stem for f in config_files]
|
return [f.stem for f in config_files]
|
||||||
|
|
||||||
|
def export_config(config_name = None, path="./config/exported_config.json"):
|
||||||
|
"""
|
||||||
|
Export configuration to JSON file with readable formatting.
|
||||||
|
Arrays/lists are kept on a single line, while nested objects are indented.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
config: Configuration dictionary to export
|
||||||
|
path: Output file path (default: "./config/exported_config.json")
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The exported config dictionary
|
||||||
|
"""
|
||||||
|
config = load_config(config_name)
|
||||||
|
Path(path).parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
with open(path, 'w', encoding='utf-8') as f:
|
||||||
|
formatted = _format_json_value(config)
|
||||||
|
f.write(formatted)
|
||||||
|
f.write('\n') # Add trailing newline
|
||||||
|
|
||||||
|
print(f"Config name: {config_name} exported to {path}")
|
||||||
|
return config
|
||||||
|
|
||||||
def _format_json_value(value, indent_level=0, indent_str=" "):
|
def _format_json_value(value, indent_level=0, indent_str=" "):
|
||||||
"""
|
"""
|
||||||
Recursively format JSON value with arrays/lists on single line.
|
Recursively format JSON value with arrays/lists on single line.
|
||||||
@@ -97,27 +120,3 @@ def _format_json_value(value, indent_level=0, indent_str=" "):
|
|||||||
else:
|
else:
|
||||||
# Primitive types (string, number, bool, None)
|
# Primitive types (string, number, bool, None)
|
||||||
return json.dumps(value, ensure_ascii=False)
|
return json.dumps(value, ensure_ascii=False)
|
||||||
|
|
||||||
def export_config(config_name = None, path="./config/exported_config.json"):
|
|
||||||
"""
|
|
||||||
Export configuration to JSON file with readable formatting.
|
|
||||||
Arrays/lists are kept on a single line, while nested objects are indented.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
config: Configuration dictionary to export
|
|
||||||
path: Output file path (default: "./config/exported_config.json")
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
The exported config dictionary
|
|
||||||
"""
|
|
||||||
config = load_config(config_name)
|
|
||||||
Path(path).parent.mkdir(parents=True, exist_ok=True)
|
|
||||||
|
|
||||||
with open(path, 'w', encoding='utf-8') as f:
|
|
||||||
formatted = _format_json_value(config)
|
|
||||||
f.write(formatted)
|
|
||||||
f.write('\n') # Add trailing newline
|
|
||||||
|
|
||||||
print(f"Config name: {config_name} exported to {path}")
|
|
||||||
return config
|
|
||||||
|
|
||||||
+58
-58
@@ -92,21 +92,21 @@ class Sensor:
|
|||||||
self.compute_deformation_valid = False
|
self.compute_deformation_valid = False
|
||||||
self.compute_contact_valid = False
|
self.compute_contact_valid = False
|
||||||
|
|
||||||
# Data Variables
|
# Data Variables (public)
|
||||||
self.__img = None
|
self.img = None
|
||||||
self.__img_size_raw = None
|
self.img_size_raw = None
|
||||||
self.__img_filtered = None
|
self.img_filtered = None
|
||||||
self.__flow = None
|
self.flow = None
|
||||||
self.__vnormal = None
|
self.vnormal = None
|
||||||
self.__vshear = None
|
self.vshear = None
|
||||||
self.__n_boxes = None
|
self.n_boxes = None
|
||||||
self.__fnormal = self.__fshearx = self.__fsheary = self.__ftor = 0.0
|
self.fnormal = self.fshearx = self.fsheary = self.ftor = 0.0
|
||||||
|
|
||||||
# Contact Data Variables
|
# Contact Data Variables (public)
|
||||||
self.__centroid = None
|
self.centroid = None
|
||||||
self.__centroid_found = False
|
self.centroid_found = False
|
||||||
self.__contour = None
|
self.contour = None
|
||||||
self.__depth_map = None
|
self.depth_map = None
|
||||||
|
|
||||||
# Timing
|
# Timing
|
||||||
self.last_log_time = time.perf_counter()
|
self.last_log_time = time.perf_counter()
|
||||||
@@ -180,26 +180,26 @@ class Sensor:
|
|||||||
img = np.ascontiguousarray(self.__stitcher.stitch_rt_optimized())
|
img = np.ascontiguousarray(self.__stitcher.stitch_rt_optimized())
|
||||||
if log_timing: timings['stitch'] = (time.perf_counter() - t0) * 1000
|
if log_timing: timings['stitch'] = (time.perf_counter() - t0) * 1000
|
||||||
|
|
||||||
self.__img_size_raw = img.shape
|
self.img_size_raw = img.shape
|
||||||
# Resize
|
# Resize
|
||||||
img = cv2.resize(img, tuple(self._config_resolution_stitch), interpolation=cv2.INTER_CUBIC)
|
img = cv2.resize(img, tuple(self._config_resolution_stitch), interpolation=cv2.INTER_CUBIC)
|
||||||
|
|
||||||
# Temporal filtering (noise reduction)
|
# Temporal filtering (noise reduction)
|
||||||
alpha = 0.7
|
alpha = 0.7
|
||||||
if self.__img_filtered is None:
|
if self.img_filtered is None:
|
||||||
self.__img_filtered = img.astype(np.float32)
|
self.img_filtered = img.astype(np.float32)
|
||||||
else:
|
else:
|
||||||
self.__img_filtered = alpha * img + (1 - alpha) * self.__img_filtered
|
self.img_filtered = alpha * img + (1 - alpha) * self.img_filtered
|
||||||
|
|
||||||
self.__img = self.__img_filtered.astype(np.uint8)
|
self.img = self.img_filtered.astype(np.uint8)
|
||||||
|
|
||||||
if log_timing:
|
if log_timing:
|
||||||
timings['total'] = (time.perf_counter() - t_start) * 1000
|
timings['total'] = (time.perf_counter() - t_start) * 1000
|
||||||
self._print_timings("get_img", timings)
|
self._print_timings("get_img", timings)
|
||||||
if self.mirror:
|
if self.mirror:
|
||||||
self.__img = cv2.flip(self.__img, 1)
|
self.img = cv2.flip(self.img, 1)
|
||||||
|
|
||||||
return self.__img.copy()
|
return self.img.copy()
|
||||||
|
|
||||||
def compute_deformation(self):
|
def compute_deformation(self):
|
||||||
"""
|
"""
|
||||||
@@ -208,7 +208,7 @@ class Sensor:
|
|||||||
Returns:
|
Returns:
|
||||||
np.ndarray: Optical flow field
|
np.ndarray: Optical flow field
|
||||||
"""
|
"""
|
||||||
if self.__img is None:
|
if self.img is None:
|
||||||
raise Exception("Warning: Get image first")
|
raise Exception("Warning: Get image first")
|
||||||
|
|
||||||
self.__compute_flow()
|
self.__compute_flow()
|
||||||
@@ -220,17 +220,17 @@ class Sensor:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def __compute_flow(self):
|
def __compute_flow(self):
|
||||||
if self.__img is None:
|
if self.img is None:
|
||||||
raise Exception("Warning: Get image first")
|
raise Exception("Warning: Get image first")
|
||||||
|
|
||||||
flow = self.__tracker.track(self.__img)
|
flow = self.__tracker.track(self.img)
|
||||||
if hasattr(flow, 'download'):
|
if hasattr(flow, 'download'):
|
||||||
flow = flow.download()
|
flow = flow.download()
|
||||||
self.__flow = flow
|
self.flow = flow
|
||||||
|
|
||||||
def __compute_hhd(self):
|
def __compute_hhd(self):
|
||||||
|
|
||||||
flow = self.__flow
|
flow = self.flow
|
||||||
if flow is None:
|
if flow is None:
|
||||||
raise Exception("Warning: Compute flow first")
|
raise Exception("Warning: Compute flow first")
|
||||||
|
|
||||||
@@ -243,11 +243,11 @@ class Sensor:
|
|||||||
_, forces = self.__hhd.get_force_gpu_v2(flow)
|
_, forces = self.__hhd.get_force_gpu_v2(flow)
|
||||||
else:
|
else:
|
||||||
_, forces = self.__hhd.get_force(flow)
|
_, forces = self.__hhd.get_force(flow)
|
||||||
self.__fnormal, self.__fshearx, self.__fsheary, self.__ftor = forces
|
self.fnormal, self.fshearx, self.fsheary, self.ftor = forces
|
||||||
|
|
||||||
# Get components
|
# Get components
|
||||||
self.__vnormal = self.__hhd.get_normal()
|
self.vnormal = self.__hhd.get_normal()
|
||||||
self.__vshear = self.__hhd.get_shear()
|
self.vshear = self.__hhd.get_shear()
|
||||||
|
|
||||||
# Update state
|
# Update state
|
||||||
self.compute_deformation_valid = True
|
self.compute_deformation_valid = True
|
||||||
@@ -259,7 +259,7 @@ class Sensor:
|
|||||||
Compute contact information from vnormal field.
|
Compute contact information from vnormal field.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
vnormal: Optional vnormal field. If None, uses self.__vnormal.
|
vnormal: Optional vnormal field. If None, uses self.vnormal.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
dict: Contact result with centroid, contour, and depth_map
|
dict: Contact result with centroid, contour, and depth_map
|
||||||
@@ -267,7 +267,7 @@ class Sensor:
|
|||||||
multiple_foe = False
|
multiple_foe = False
|
||||||
|
|
||||||
# Use provided vnormal or fall back to internal state
|
# Use provided vnormal or fall back to internal state
|
||||||
vnormal_to_use = vnormal if vnormal is not None else self.__vnormal
|
vnormal_to_use = vnormal if vnormal is not None else self.vnormal
|
||||||
|
|
||||||
if vnormal_to_use is None:
|
if vnormal_to_use is None:
|
||||||
raise Exception("Warning: vnormal is required for contact computation")
|
raise Exception("Warning: vnormal is required for contact computation")
|
||||||
@@ -280,11 +280,11 @@ class Sensor:
|
|||||||
else:
|
else:
|
||||||
result = self.__contact3d.compute_foe(vnormal_to_use)
|
result = self.__contact3d.compute_foe(vnormal_to_use)
|
||||||
|
|
||||||
self.__centroid = result['centroid']
|
self.centroid = result['centroid']
|
||||||
self.__centroid_found = result['centroid_found']
|
self.centroid_found = result['centroid_found']
|
||||||
if 'contour' in result:
|
if 'contour' in result:
|
||||||
self.__contour = result['contour']
|
self.contour = result['contour']
|
||||||
self.__depth_map = result['divergence_map']
|
self.depth_map = result['divergence_map']
|
||||||
|
|
||||||
self.compute_contact_valid = True
|
self.compute_contact_valid = True
|
||||||
return result
|
return result
|
||||||
@@ -301,7 +301,7 @@ class Sensor:
|
|||||||
Tuple: Requested data in order
|
Tuple: Requested data in order
|
||||||
"""
|
"""
|
||||||
if any(arg in [self.info.IMG] for arg in args):
|
if any(arg in [self.info.IMG] for arg in args):
|
||||||
if self.__img is None:
|
if self.img is None:
|
||||||
raise Exception("Warning: Get image first")
|
raise Exception("Warning: Get image first")
|
||||||
|
|
||||||
if any(arg in [self.info.VRAW, self.info.VNORMAL, self.info.VSHEAR, self.info.FNORMAL, self.info.FSHEARX, self.info.FSHEARY] for arg in args):
|
if any(arg in [self.info.VRAW, self.info.VNORMAL, self.info.VSHEAR, self.info.FNORMAL, self.info.FSHEARX, self.info.FSHEARY] for arg in args):
|
||||||
@@ -314,26 +314,26 @@ class Sensor:
|
|||||||
|
|
||||||
mapping = {
|
mapping = {
|
||||||
# Return copies of arrays to prevent external modification of internal state
|
# Return copies of arrays to prevent external modification of internal state
|
||||||
self.info.VRAW: lambda: self.__flow.copy() if self.__flow is not None else np.array([]),
|
self.info.VRAW: lambda: self.flow.copy() if self.flow is not None else np.array([]),
|
||||||
self.info.VNORMAL: lambda: self.__vnormal.copy() if self.__vnormal is not None else np.array([]),
|
self.info.VNORMAL: lambda: self.vnormal.copy() if self.vnormal is not None else np.array([]),
|
||||||
self.info.VSHEAR: lambda: self.__vshear.copy() if self.__vshear is not None else np.array([]),
|
self.info.VSHEAR: lambda: self.vshear.copy() if self.vshear is not None else np.array([]),
|
||||||
# Scalar values are safe to return directly
|
# Scalar values are safe to return directly
|
||||||
self.info.FNORMAL: lambda: self.__fnormal,
|
self.info.FNORMAL: lambda: self.fnormal,
|
||||||
self.info.FSHEARX: lambda: self.__fshearx,
|
self.info.FSHEARX: lambda: self.fshearx,
|
||||||
self.info.FSHEARY: lambda: self.__fsheary,
|
self.info.FSHEARY: lambda: self.fsheary,
|
||||||
self.info.FPS: lambda: self._fps,
|
self.info.FPS: lambda: self._fps,
|
||||||
self.info.TIMESTAMP: lambda: time.strftime('%H:%M:%S'),
|
self.info.TIMESTAMP: lambda: time.strftime('%H:%M:%S'),
|
||||||
# Return copies of arrays to prevent external modification
|
# Return copies of arrays to prevent external modification
|
||||||
self.info.DEPTH: lambda: self.__depth_map.copy() if self.__depth_map is not None else np.array([]),
|
self.info.DEPTH: lambda: self.depth_map.copy() if self.depth_map is not None else np.array([]),
|
||||||
# Centroid: can be tuple, list, or array - return a copy to prevent modification
|
# Centroid: can be tuple, list, or array - return a copy to prevent modification
|
||||||
# Return None if centroid is not found or empty
|
# Return None if centroid is not found or empty
|
||||||
self.info.CENTROID: lambda: (
|
self.info.CENTROID: lambda: (
|
||||||
np.array(self.__centroid).copy()
|
np.array(self.centroid).copy()
|
||||||
if self.__centroid is not None and len(self.__centroid) > 0
|
if self.centroid is not None and len(self.centroid) > 0
|
||||||
else None
|
else None
|
||||||
),
|
),
|
||||||
self.info.CONTOUR: lambda: self.__contour.copy() if self.__contour is not None else np.array([]),
|
self.info.CONTOUR: lambda: self.contour.copy() if self.contour is not None else np.array([]),
|
||||||
self.info.IMG: lambda: self.__img.copy() if self.__img is not None else np.array([]),
|
self.info.IMG: lambda: self.img.copy() if self.img is not None else np.array([]),
|
||||||
}
|
}
|
||||||
|
|
||||||
return tuple(mapping.get(arg, lambda: None)() for arg in args if isinstance(arg, self.info))
|
return tuple(mapping.get(arg, lambda: None)() for arg in args if isinstance(arg, self.info))
|
||||||
@@ -475,7 +475,7 @@ class Sensor:
|
|||||||
break
|
break
|
||||||
v_mean0 = v_mean
|
v_mean0 = v_mean
|
||||||
|
|
||||||
self.__n_boxes = n_boxes
|
self.n_boxes = n_boxes
|
||||||
self.stitch_valid = self.isstitch and n_boxes == self._config_units
|
self.stitch_valid = self.isstitch and n_boxes == self._config_units
|
||||||
|
|
||||||
status = "valid for stitching" if self.stitch_valid else "non-stitch mode"
|
status = "valid for stitching" if self.stitch_valid else "non-stitch mode"
|
||||||
@@ -607,9 +607,9 @@ class Sensor:
|
|||||||
# continue
|
# continue
|
||||||
|
|
||||||
# # Put the processed image in the queue
|
# # Put the processed image in the queue
|
||||||
# # get_img() updates self.__img, so we use that
|
# # get_img() updates self.img, so we use that
|
||||||
# if self.__img is not None:
|
# if self.img is not None:
|
||||||
# self._queue_put(self._capture_queue, self.__img.copy())
|
# self._queue_put(self._capture_queue, self.img.copy())
|
||||||
# except Exception as e:
|
# except Exception as e:
|
||||||
# if self.verbose: print(f"Capture error: {e}")
|
# if self.verbose: print(f"Capture error: {e}")
|
||||||
|
|
||||||
@@ -619,9 +619,9 @@ class Sensor:
|
|||||||
# try:
|
# try:
|
||||||
# img = self._capture_queue.get(timeout=0.1)
|
# img = self._capture_queue.get(timeout=0.1)
|
||||||
# # Set __img to reuse __compute_flow()
|
# # Set __img to reuse __compute_flow()
|
||||||
# self.__img = img
|
# self.img = img
|
||||||
# self.__compute_flow()
|
# self.__compute_flow()
|
||||||
# flow = self.__flow.copy() if self.__flow is not None else None
|
# flow = self.flow.copy() if self.flow is not None else None
|
||||||
# self._queue_put(self._flow_queue, (img, flow))
|
# self._queue_put(self._flow_queue, (img, flow))
|
||||||
# except Empty:
|
# except Empty:
|
||||||
# continue
|
# continue
|
||||||
@@ -635,16 +635,16 @@ class Sensor:
|
|||||||
# img, flow = self._flow_queue.get(timeout=0.1)
|
# img, flow = self._flow_queue.get(timeout=0.1)
|
||||||
|
|
||||||
# # Set __flow to reuse __compute_hhd()
|
# # Set __flow to reuse __compute_hhd()
|
||||||
# self.__flow = flow
|
# self.flow = flow
|
||||||
# self.__compute_hhd()
|
# self.__compute_hhd()
|
||||||
# # Get results from internal variables set by __compute_hhd()
|
# # Get results from internal variables set by __compute_hhd()
|
||||||
# result = {
|
# result = {
|
||||||
# 'img': img, 'flow': flow,
|
# 'img': img, 'flow': flow,
|
||||||
# 'normal': self.__vnormal.copy() if self.__vnormal is not None else None,
|
# 'normal': self.vnormal.copy() if self.vnormal is not None else None,
|
||||||
# 'shear': self.__vshear.copy() if self.__vshear is not None else None,
|
# 'shear': self.vshear.copy() if self.vshear is not None else None,
|
||||||
# # 'depth': getFilteredDensity(flow, use_cuda=self.cuda),
|
# # 'depth': getFilteredDensity(flow, use_cuda=self.cuda),
|
||||||
# 'fnormal': self.__fnormal, 'fshearx': self.__fshearx,
|
# 'fnormal': self.fnormal, 'fshearx': self.fshearx,
|
||||||
# 'fsheary': self.__fsheary, 'ftor': self.__ftor,
|
# 'fsheary': self.fsheary, 'ftor': self.ftor,
|
||||||
# }
|
# }
|
||||||
|
|
||||||
# # Always include contact fields to ensure consistent result structure
|
# # Always include contact fields to ensure consistent result structure
|
||||||
|
|||||||
@@ -103,3 +103,4 @@ def draw_contact(image, contour, centroid, point_color=(0, 255, 0), region_color
|
|||||||
cv2.circle(image, (cx, cy), 10, point_color, 2)
|
cv2.circle(image, (cx, cy), 10, point_color, 2)
|
||||||
|
|
||||||
return image
|
return image
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user