diff --git a/config/compound_eye.png b/config/compound_eye.png index d80e6f6..ef3b17b 100644 Binary files a/config/compound_eye.png and b/config/compound_eye.png differ diff --git a/example1_basic.py b/example1_basic.py index f7319f8..6ef9f3c 100644 --- a/example1_basic.py +++ b/example1_basic.py @@ -58,14 +58,12 @@ def main(): # 其他: # - FPS: 当前帧率 # - TIMESTAMP: 时间戳字符串 - # - DEPTH: 深度图(归一化 0-1) - fps, fn, fx, fy, flow, depth = sensor.read_info( + fps, fn, fx, fy, flow = sensor.read_info( sensor.info.FPS, sensor.info.FNORMAL, sensor.info.FSHEARX, sensor.info.FSHEARY, - sensor.info.VRAW, - sensor.info.DEPTH + sensor.info.VRAW ) # 打印力的数值 @@ -90,12 +88,6 @@ def main(): ) cv2.imshow("形变场 Deformation", arrows) - # 绘制深度图(热力图) - depth_img = cv2.applyColorMap( - (depth * 255.0).astype('uint8'), - cv2.COLORMAP_HOT - ) - cv2.imshow("深度图 Depth", depth_img) # ===================================================================== # 4. 键盘控制 diff --git a/example2_config.py b/example2_config.py index 45210b6..3d9745b 100644 --- a/example2_config.py +++ b/example2_config.py @@ -19,17 +19,12 @@ def main(): # 向量场: VRAW, VNORMAL, VSHEAR: 原始,法向,切向 # 帧率,时间戳: FPS, TIMESTAMP # 变形量总和: FNORMAL , FSHEARX, FSHEARY : 法向,切向(X),切向(Y) - # 深度图: DEPTH - fps, fn, fx, fy, flow, depth = sensor1.read_info(sensor1.info.FPS, sensor1.info.FNORMAL, sensor1.info.FSHEARX, sensor1.info.FSHEARY, sensor1.info.VRAW, sensor1.info.DEPTH) + fps, fn, fx, fy, flow = sensor1.read_info(sensor1.info.FPS, sensor1.info.FNORMAL, sensor1.info.FSHEARX, sensor1.info.FSHEARY, sensor1.info.VRAW) # 显示向量场 arrows = orisys.util.draw_arrows(sensor1.img, flow, threshold=5, grid_spacing=40, arrow_scale=1.0) cv2.imshow("Deformation", arrows) - depth_img = cv2.applyColorMap((depth*1* 255.0).astype('uint8'), cv2.COLORMAP_HOT) - - cv2.imshow('depth', depth_img) - key = cv2.waitKey(1) if key & 0xFF == ord("q"): print("\n 停止程序") diff --git a/example3_manual_box.py b/example3_manual_box.py index e086fc8..3a46e1a 100644 --- a/example3_manual_box.py +++ b/example3_manual_box.py @@ -25,17 +25,12 @@ def main(): # 向量场: VRAW, VNORMAL, VSHEAR: 原始,法向,切向 # 帧率,时间戳: FPS, TIMESTAMP # 变形量总和: FNORMAL , FSHEARX, FSHEARY : 法向,切向(X),切向(Y) - # 深度图: DEPTH - fps, fn, fx, fy, flow, depth = sensor1.read_info(sensor1.info.FPS, sensor1.info.FNORMAL, sensor1.info.FSHEARX, sensor1.info.FSHEARY, sensor1.info.VRAW, sensor1.info.DEPTH) + fps, fn, fx, fy, flow = sensor1.read_info(sensor1.info.FPS, sensor1.info.FNORMAL, sensor1.info.FSHEARX, sensor1.info.FSHEARY, sensor1.info.VRAW) print(fps,fn,fx,fy) # 显示向量场 arrows = orisys.util.draw_arrows(sensor1.img, flow, threshold=5, grid_spacing=40, arrow_scale=1.0) cv2.imshow("Deformation", arrows) - depth_img = cv2.applyColorMap((depth*1* 255.0).astype('uint8'), cv2.COLORMAP_HOT) - - cv2.imshow('depth', depth_img) - key = cv2.waitKey(1) if key & 0xFF == ord("q"): print("\n 停止程序") diff --git a/example4_multiple_sensor.py b/example4_multiple_sensor.py index b13991a..276b550 100644 --- a/example4_multiple_sensor.py +++ b/example4_multiple_sensor.py @@ -44,7 +44,7 @@ def main(): 'cal_path': './config/cal.npy' }, { - 'vid_src': './s1_copy.mp4', + 'vid_src': './s1.mp4', 'isstitch': True, 'cuda': True, 'cal_path': './config/cal.npy' @@ -84,13 +84,6 @@ def main(): ) cv2.imshow(f"传感器 {sid} - 形变", arrows) - # 显示深度图 - if data['depth'] is not None: - depth_img = cv2.applyColorMap( - (data['depth'] * 255).astype('uint8'), - cv2.COLORMAP_HOT - ) - cv2.imshow(f"传感器 {sid} - 深度", depth_img) # 检查退出键 if cv2.waitKey(1) & 0xFF == ord('q'): diff --git a/example5_async.py b/example5_async.py index 5b145eb..6171098 100644 --- a/example5_async.py +++ b/example5_async.py @@ -80,13 +80,6 @@ def main(): ) cv2.imshow("异步模式 - 形变", arrows) - # 显示深度图 - if data['depth'] is not None: - depth_img = cv2.applyColorMap( - (data['depth'] * 255).astype('uint8'), - cv2.COLORMAP_HOT - ) - cv2.imshow("异步模式 - 深度", depth_img) # 键盘控制 key = cv2.waitKey(1) & 0xFF diff --git a/example6_multi_async.py b/example6_multi_async.py index 047f430..3fc369e 100644 --- a/example6_multi_async.py +++ b/example6_multi_async.py @@ -98,7 +98,7 @@ def main_manual(): """ configs = [ {'vid_src': './s1.mp4', 'isstitch': True, 'cuda': True, 'cal_path': './config/cal.npy'}, - {'vid_src': './s1_copy.mp4', 'isstitch': True, 'cuda': True, 'cal_path': './config/cal.npy'}, + {'vid_src': './s1.mp4', 'isstitch': True, 'cuda': True, 'cal_path': './config/cal.npy'}, ] # 创建 MultiSensor 实例 diff --git a/example_foe.py b/example_foe.py index c463243..5c91f9a 100644 --- a/example_foe.py +++ b/example_foe.py @@ -25,19 +25,16 @@ def main(): # 步骤 2.2: 计算形变场 sensor.compute_deformation() - fps, flow,vnormal, depth = sensor.read_info( + fps, flow,vnormal = sensor.read_info( sensor.info.FPS, sensor.info.VRAW, - sensor.info.VNORMAL, - sensor.info.DEPTH + sensor.info.VNORMAL ) # depth = get_depth_improved(vnormal, fps) # print(f"FPS: {fps:5.1f}, 深度: {np.min(depth):8.2f}, {np.mean(depth):8.2f}, {np.max(depth):8.2f}") - - arrows = orisys.util.draw_arrows( sensor.img.copy(), # 使用 copy() 避免修改原图 @@ -60,17 +57,11 @@ def main(): # 计算扩张焦点 # foe_result = orisys.util.compute_foe(vnormal,min_magnitude=1,expansion_threshold=0.01,downsample_factor=1) - foe_result = sensor.get_foe(multiple_foe=False, min_magnitude=1, expansion_threshold=0.01, downsample_factor=1) + foe_result = sensor.get_foe(multiple_foe=False, min_magnitude=1, expansion_threshold=0.01, downsample_factor=1,denoise_sigma=10) # 在图像上绘制焦点和区域 image_with_foe = orisys.util.draw_foe(sensor.img.copy(), foe_result) cv2.imshow("Focus of Expansion", image_with_foe) - # 计算多个扩张焦点 - # foe_result = orisys.util.compute_multiple_foe(vnormal, min_contour_area=3000,min_magnitude=1,expansion_threshold=0.001,downsample_factor=10) - - # # 在图像上绘制多个焦点和区域 - # image_with_foe = orisys.util.draw_multiple_foe(sensor.img.copy(), foe_result) - # cv2.imshow("Multiple FOE", image_with_foe) # ===================================================================== # 4. 键盘控制 diff --git a/src/orisys/MultiSensor.py b/src/orisys/MultiSensor.py index 7d099f5..374adc0 100644 --- a/src/orisys/MultiSensor.py +++ b/src/orisys/MultiSensor.py @@ -75,7 +75,7 @@ def _sensor_worker(sensor_id, config, data_queue, stop_event, use_async=False): 'sensor_id': sensor_id, 'img': sensor.img.copy() if sensor.img is not None else None, 'flow': sensor.flow.copy() if sensor.flow is not None else None, - 'normal': sensor.normal.copy() if sensor.normal is not None else None, + 'normal': sensor.vnormal.copy() if sensor.vnormal is not None else None, 'shear': sensor.shear.copy() if sensor.shear is not None else None, 'depth': sensor.depth.copy() if sensor.depth is not None else None, 'fps': sensor.fps, diff --git a/src/orisys/get_depth.py b/src/orisys/get_depth.py index 39be8f1..ede7da0 100644 --- a/src/orisys/get_depth.py +++ b/src/orisys/get_depth.py @@ -1,7 +1,8 @@ import numpy as np import cv2 +from scipy.ndimage import gaussian_filter -def compute_foe(flow_field, min_magnitude=1.0, expansion_threshold=1, downsample_factor=10, return_all_contours=False, kernel_size=(5,5), denoise_sigma=1.5): +def compute_foe(flow_field, min_magnitude=1.0, expansion_threshold=1, downsample_factor=10, return_all_contours=False, kernel_size=(5,5), denoise_sigma=10): """ 计算光流场的扩张焦点(Focus of Expansion)。 @@ -87,7 +88,7 @@ def compute_foe(flow_field, min_magnitude=1.0, expansion_threshold=1, downsample return result def compute_multiple_foe(flow_field, min_magnitude=1.0, expansion_threshold=0.001, - downsample_factor=10, min_contour_area=3000, denoise_sigma=1.5, kernel_size=(5,5)): + downsample_factor=10, min_contour_area=3000, denoise_sigma=10, kernel_size=(5,5)): """ 计算光流场的多个扩张焦点(Foci of Expansion)。 @@ -141,4 +142,32 @@ def compute_multiple_foe(flow_field, min_magnitude=1.0, expansion_threshold=0.00 result['foe_points'].append((cx, cy)) result['expansion_regions'].append(contour) - return result \ No newline at end of file + return result + +def smooth_magnitude(mag, method='moving_average', window_size=5, downsample_factor=4): + """ + 平滑幅度图以减少梯度计算时的伪影。 + + Args: + mag: 幅度图,形状为 (H, W) 的 numpy 数组 + method: 平滑方法,'moving_average' 或 'windowed_interpolation' + window_size: 移动平均的窗口大小(默认5) + downsample_factor: 窗口插值的下采样因子(默认4) + + Returns: + np.ndarray: 平滑后的幅度图 + """ + if method == 'moving_average': + # 使用移动平均滤波器(box filter) + kernel = np.ones((window_size, window_size), dtype=np.float32) / (window_size * window_size) + mag_smooth = cv2.filter2D(mag, -1, kernel) + elif method == 'windowed_interpolation': + # 使用窗口插值:下采样然后插值回原尺寸 + h, w = mag.shape + mag_downsampled = mag[::downsample_factor, ::downsample_factor] + mag_smooth = cv2.resize(mag_downsampled, (w, h), interpolation=cv2.INTER_CUBIC) + else: + # 默认使用高斯滤波 + mag_smooth = gaussian_filter(mag, sigma=1.5) + + return mag_smooth \ No newline at end of file diff --git a/test_depth_v2.py b/test_depth_v2.py index cd2c962..7c2484b 100644 --- a/test_depth_v2.py +++ b/test_depth_v2.py @@ -42,13 +42,19 @@ def main(): cv2.imshow("形变场 Deformation", arrows) mag = np.sqrt(vnormal[:, :, 0]**2 + vnormal[:, :, 1]**2) + mag = gaussian_filter(mag, sigma=12) + + mag_div = np.gradient(mag, axis=1) + np.gradient(mag, axis=0) + mag_div = np.where(mag_div>0, mag_div, 0) + mag_img = cv2.applyColorMap( - (mag/20 * 255.0).astype('uint8'), + (mag_div/0.2 * 255.0).astype('uint8'), cv2.COLORMAP_JET ) cv2.imshow("magnitude map", mag_img) - print(np.median(mag), np.min(mag), np.max(mag)) + # print(np.median(mag), np.min(mag), np.max(mag)) + print(np.median(mag_div), np.min(mag_div), np.max(mag_div)) # ===================================================================== # 4. 键盘控制 diff --git a/test_foe_depth.py b/test_foe_depth.py index fca85e0..7fa064d 100644 --- a/test_foe_depth.py +++ b/test_foe_depth.py @@ -204,11 +204,11 @@ def estimate_depth(foe=None, flow=None, init_depth=None, min_radial_flow=0.01, T # 处理FOE附近区域:使用平滑后的值 if np.any(mask_foe_region): - depth_smoothed = gaussian_filter(depth, sigma=2.0) + depth_smoothed = gaussian_filter(depth, sigma=15) depth[mask_foe_region] = depth_smoothed[mask_foe_region] # 应用高斯滤波平滑整个深度图,减少噪声和伪影 - depth = gaussian_filter(depth, sigma=1.5) + depth = gaussian_filter(depth, sigma=15) # 缩放深度(如果提供了初始深度,只使用掩码内的值) if init_depth is not None: @@ -248,7 +248,7 @@ def estimate_depth(foe=None, flow=None, init_depth=None, min_radial_flow=0.01, T depth = np.clip(depth, p1, p99) # 最终平滑:对FOE附近区域再次应用平滑,确保伪影被消除 - depth_final_smooth = gaussian_filter(depth, sigma=1.0) + depth_final_smooth = gaussian_filter(depth, sigma=15) # 重新计算FOE附近掩码 rx = xx - fx @@ -321,7 +321,7 @@ def main(): # 计算扩张焦点 # foe_result = orisys.util.compute_foe(vnormal,min_magnitude=1,expansion_threshold=0.01,downsample_factor=1) - foe_result = sensor.get_foe(multiple_foe=False, min_magnitude=1, expansion_threshold=0.01, downsample_factor=1) + foe_result = sensor.get_foe(multiple_foe=False, min_magnitude=1, expansion_threshold=0.01, downsample_factor=1,denoise_sigma=15) # 在图像上绘制焦点和区域 image_with_foe = orisys.util.draw_foe(sensor.img.copy(), foe_result) cv2.imshow("Focus of Expansion", image_with_foe)