diff --git a/Point.py b/Point.py index 158d60b..54fcbea 100644 --- a/Point.py +++ b/Point.py @@ -1,129 +1,130 @@ +from datetime import time + import numpy as np from PIL import Image import math import config -from cat import clip_and_rotate_point_cloud, merge_point_clouds -from image import detect_large_holes - +import asyncio -def tiff_depth_to_point_clouds(tiff_paths, sn, dedup=True): - """ - 将多个 TIFF 深度图转换为点云,并拼接在一起后生成 PCD 文件 - :param tiff_paths: list of str, TIFF 深度图路径列表 - :param sn: str, 设备序列号,用于查找配置参数 - :param dedup: bool, 是否根据 (x, y) 去重,默认开启 - :return: list of [x, y, z], 合并后的点云数据 - """ - merged_points = [] - - # Step 1: 遍历每个 TIFF 文件,生成对应的点云 - for tiff_path in tiff_paths: - points = tiff_depth_to_point_cloud(tiff_path+".tiff", sn, dedup) - merged_points.extend([points]) - - # Step 2: 可选:使用 merge_point_clouds 对点云进行 x 轴拼接(若需要) - # 注意:如果每个点云已经带有偏移,则不需要再次拼接 - has_voids = True - if hasattr(config, 'CUT_CONFIG_MAP') and isinstance(config.CUT_CONFIG_MAP, dict) and (sn in config.CUT_CONFIG_MAP): - merged_points, xrange = merge_point_clouds(merged_points, config.CUT_CONFIG_MAP[sn],sn) - - real_holes = detect_large_holes(merged_points, sn, xrange) - if real_holes.__len__()==0: - has_voids=False - # Step 3: 写入最终的 PCD 文件 - output_pcd_path = config.save_path("pcd", f"{sn}_merged.pcd") - write_pcd(output_pcd_path, merged_points) - # print(f"Merged and saved to {output_pcd_path}") - return has_voids - - -def tiff_depth_to_point_cloud(tiff_path,sn, dedup=True): - """ - 将 TIFF 深度图转换为点云,基于给定的视场角计算相机内参 - - :param tiff_path: str, TIFF 深度图路径 - :param hfov_degrees: float or None, 水平视场角(单位:度) - :param vfov_degrees: float or None, 垂直视场角(单位:度) - :param output_ply_path: str or None, 输出 Pcd 文件路径(可选) - :param dedup: bool, 是否根据 (x, y) 去重,默认开启 - :return: list of [x, y, z] 点云数据 - """ - hfov_degrees = config.CAMERA_CONFIG_MAP[sn].get("x_angle") - max_z = config.CAMERA_CONFIG_MAP[sn].get("max_z") - vfov_degrees = config.CAMERA_CONFIG_MAP[sn].get("y_angle") - # plane_scaling_ratio = config.CAMERA_CONFIG_MAP[sn].get("plane_scaling_ratio") - # 加载 TIFF 图像 - depth_image = Image.open(tiff_path) - depth_array = np.array(depth_image, dtype=np.float32) - - height, width = depth_array.shape - - # 根据提供的 FOV 计算 fx/fy - if hfov_degrees is not None: - hfov_rad = math.radians(hfov_degrees) - fx = width / (2 * math.tan(hfov_rad / 2)) - fy = fx * height / width # 保持像素方形比例 - else: - vfov_rad = math.radians(vfov_degrees) - fy = height / (2 * math.tan(vfov_rad / 2)) - fx = fy * width / height # 保持像素方形比例 +import numpy as np +from scipy.spatial.transform import Rotation as R - cx = width / 2 - cy = height / 2 +from logConfig import get_logger - print(f"Calculated intrinsics: fx={fx:.2f}, fy={fy:.2f}, cx={cx:.2f}, cy={cy:.2f}") +# 使用示例 +logger = get_logger() - points = [] - seen_xy = set() # 用于记录已添加的 (x, y) +def apply_rotation(matrix, angle_degrees, axis='x'): + """ + 对输入的 3x3 旋转矩阵 应用额外的旋转 - # 获取裁剪配置 - clip_config = config.CUT_CONFIG_MAP.get(sn) - if clip_config: - min_pt = np.array(clip_config.get("min_pt", [-np.inf] * 3)) - max_pt = np.array(clip_config.get("max_pt", [np.inf] * 3)) - rotation = np.array(clip_config.get("rotation", [1,0,0,0,1,0,0,0,1])).reshape(3, 3) - else: - min_pt = max_pt = rotation = None - - for v in range(height): - for u in range(width): - z = depth_array[v, u] # mm -> m - if z <= 0 or z > max_z: - continue - - x = (u - cx) * z / fx - y = (v - cy) * z / fy - - # 构造点并旋转(保留浮点精度) - point = np.array([x, y, z]) - if clip_config: - rotated_point = (rotation @ point.T).T - if not np.all(rotated_point >= min_pt) or not np.all(rotated_point <= max_pt): - continue - x_final, y_final, z_final = rotated_point - else: - x_final, y_final, z_final = point - - # 到这里才进行去重判断 - if dedup: - x_int = int(round(x_final)) - y_int = int(round(y_final)) - z_int = int(round(z_final)) - if (x_int, y_int) in seen_xy: - continue - seen_xy.add((x_int, y_int)) - # 保留浮点精度写入结果 - points.append([x_int, y_int, z_int]) - - - # 可选输出PLY文件用于可视化 - if config.CAMERA_CONFIG_MAP[sn].get("save_pcd"): - output_ply_path = config.save_path("pcd",sn+".pcd") - write_pcd(output_ply_path, points) + 参数: + matrix (np.ndarray): 原始的 3x3 旋转矩阵 + angle_degrees (float): 旋转角度 (单位: 度) + axis (str): 旋转轴,支持 'x', 'y', 'z' - return points + 返回: + np.ndarray: 新的 3x3 旋转矩阵 + """ + # 创建绕指定轴旋转的旋转对象 + rot = R.from_euler(axis, angle_degrees, degrees=True) + + # 将当前旋转转换为矩阵 + rotation_matrix = rot.as_matrix() + + # 合并旋转:新旋转 × 原始矩阵 + combined_rotation = np.dot(rotation_matrix, matrix) + + return combined_rotation + +# +# def tiff_depth_to_point_cloud(tiff_path,sn, dedup=True): +# """ +# 将 TIFF 深度图转换为点云,基于给定的视场角计算相机内参 +# +# :param tiff_path: str, TIFF 深度图路径 +# :param hfov_degrees: float or None, 水平视场角(单位:度) +# :param vfov_degrees: float or None, 垂直视场角(单位:度) +# :param output_ply_path: str or None, 输出 Pcd 文件路径(可选) +# :param dedup: bool, 是否根据 (x, y) 去重,默认开启 +# :return: list of [x, y, z] 点云数据 +# """ +# hfov_degrees = config.CAMERA_CONFIG_MAP[sn].get("x_angle") +# max_z = config.CAMERA_CONFIG_MAP[sn].get("max_z") +# vfov_degrees = config.CAMERA_CONFIG_MAP[sn].get("y_angle") +# # plane_scaling_ratio = config.CAMERA_CONFIG_MAP[sn].get("plane_scaling_ratio") +# # 加载 TIFF 图像 +# depth_image = Image.open(tiff_path) +# depth_array = np.array(depth_image, dtype=np.float32) +# +# height, width = depth_array.shape +# +# # 根据提供的 FOV 计算 fx/fy +# if hfov_degrees is not None: +# hfov_rad = math.radians(hfov_degrees) +# fx = width / (2 * math.tan(hfov_rad / 2)) +# fy = fx * height / width # 保持像素方形比例 +# else: +# vfov_rad = math.radians(vfov_degrees) +# fy = height / (2 * math.tan(vfov_rad / 2)) +# fx = fy * width / height # 保持像素方形比例 +# +# cx = width / 2 +# cy = height / 2 +# +# print(f"Calculated intrinsics: fx={fx:.2f}, fy={fy:.2f}, cx={cx:.2f}, cy={cy:.2f}") +# +# points = [] +# seen_xy = set() # 用于记录已添加的 (x, y) +# +# # 获取裁剪配置 +# clip_config = config.CUT_CONFIG_MAP.get(sn) +# if clip_config: +# min_pt = np.array(clip_config.get("min_pt", [-np.inf] * 3)) +# max_pt = np.array(clip_config.get("max_pt", [np.inf] * 3)) +# rotation = np.array(clip_config.get("rotation", [1,0,0,0,1,0,0,0,1])).reshape(3, 3) +# else: +# min_pt = max_pt = rotation = None +# +# for v in range(height): +# for u in range(width): +# z = depth_array[v, u] # mm -> m +# if z <= 0 or z > max_z: +# continue +# +# x = (u - cx) * z / fx +# y = (v - cy) * z / fy +# +# # 构造点并旋转(保留浮点精度) +# point = np.array([x, y, z]) +# if clip_config: +# rotated_point = (rotation @ point.T).T +# if not np.all(rotated_point >= min_pt) or not np.all(rotated_point <= max_pt): +# continue +# x_final, y_final, z_final = rotated_point +# else: +# x_final, y_final, z_final = point +# +# # 到这里才进行去重判断 +# if dedup: +# x_int = int(round(x_final)) +# y_int = int(round(y_final)) +# z_int = int(round(z_final)) +# if (x_int, y_int) in seen_xy: +# continue +# seen_xy.add((x_int, y_int)) +# # 保留浮点精度写入结果 +# points.append([x_int, y_int, z_int]) +# +# +# # 可选输出PLY文件用于可视化 +# if config.CAMERA_CONFIG_MAP[sn].get("save_pcd"): +# output_ply_path = config.save_path("pcd",sn+".pcd") +# write_pcd(output_ply_path, points) +# +# return points # 新增点云数据转换函数 @@ -141,67 +142,139 @@ def convert_sdk_points(sValue, width, height): mask = np.all(np.isfinite(points), axis=1) return points[mask] +# def process_point_cloud_fast(points, sn, type): +# points = np.array(points, dtype=np.float32) +# # 获取目标高度和容差(来自模板配置) +# template_config = config.TEMPLATE_CONFIG_MAP.get(type, {}) +# target_z = template_config.get("height", 0) # 假设 height 是期望的中心高度 +# tolerance = template_config.get("tolerance", 50) # 默认容差为 50 +# +# # 计算上下限 +# z_min = target_z - tolerance +# z_max = target_z + tolerance # 不超过 200 +# # Z 值过滤 +# valid_mask = ((points[:, 2] > 0) +# & (points[:, 2] <= config.CAMERA_CONFIG_MAP[sn].get("max_z", np.inf)) +# ) +# +# points = points[valid_mask] +# +# if clip_config := config.CUT_CONFIG_MAP.get(sn): +# rotation = np.array(clip_config["rotation"], dtype=np.float32).reshape(3, 3) +# min_pt = np.array(clip_config["min_pt"], dtype=np.float32) +# max_pt = np.array(clip_config["max_pt"], dtype=np.float32) +# floorHeight = clip_config.get("floorHeight", 0) +# +# # 批量旋转 +# rotated = (rotation @ points.T).T +# +# # 裁剪范围过滤 +# bounds_mask = np.all((rotated >= min_pt) & (rotated <= max_pt), axis=1) +# rotated = rotated[bounds_mask] +# x_trimmed = np.round(rotated[:, 0], 3) +# y_trimmed = np.round(rotated[:, 1], 3) +# z_trimmed = np.round(floorHeight - rotated[:, 2], 3) +# else: +# x_trimmed = np.round(points[:, 0], 3) +# y_trimmed = np.round(points[:, 1], 3) +# z_trimmed = np.round(points[:, 2], 3) +# +# # 合并为一个数组 +# trimmed_points = np.column_stack((x_trimmed, y_trimmed, z_trimmed)) +# # 应用 z 值过滤 +# final_mask = ( +# (trimmed_points[:, 2] >= z_min) & +# (trimmed_points[:, 2] <= z_max) +# ) +# filtered_points = trimmed_points[final_mask] +# +# # 去重 +# keys = np.column_stack((filtered_points[:, 0], filtered_points[:, 1])) +# _, unique_indices = np.unique(keys, axis=0, return_index=True) +# +# # 返回 list of [x, y, z] +# return filtered_points[unique_indices].tolist() +def process_point_cloud_fast(points, sn, type): + points = np.array(points, dtype=np.float32) + if not len(points): + return [] + + # 获取配置 + template_config = config.TEMPLATE_CONFIG_MAP.get(type, {}) + target_z = template_config.get("height", 0) + tolerance = template_config.get("tolerance", 25) + z_min = target_z - tolerance + z_max = target_z + tolerance + + # 初始 Z 过滤 + valid_mask = (points[:, 2] > 0) & (points[:, 2] <= config.CAMERA_CONFIG_MAP[sn].get("max_z", np.inf)) + points = points[valid_mask] -def process_point_cloud(points, sn, dedup=True): - """ - 对原始点云应用旋转、裁剪和去重 + # 获取裁剪配置 + clip_config = config.CUT_CONFIG_MAP.get(sn + "_" + type, None) or config.CUT_CONFIG_MAP.get(sn) - :param points: np.ndarray(shape=(N,3)), 原始点云数据 - :param sn: str, 设备序列号(用于加载配置) - :param dedup: bool, 是否启用去重 - :return: list of [x, y, z], 处理后的点云列表 - """ - # 加载配置参数 - clip_config = config.CUT_CONFIG_MAP.get(sn) if clip_config: - min_pt = np.array(clip_config.get("min_pt", [-np.inf] * 3)) - max_pt = np.array(clip_config.get("max_pt", [np.inf] * 3)) - rotation = np.array(clip_config.get("rotation", [1, 0, 0, 0, 1, 0, 0, 0, 1])).reshape(3, 3) + rotation = np.array(clip_config["rotation"], dtype=np.float32).reshape(3, 3) + min_pt = np.array(clip_config["min_pt"], dtype=np.float32) + max_pt = np.array(clip_config["max_pt"], dtype=np.float32) + floorHeight = clip_config.get("floorHeight", 0) + + # 批量旋转 + rotated = (rotation @ points.T).T + + # 裁剪范围过滤 + bounds_mask = np.all((rotated >= min_pt) & (rotated <= max_pt), axis=1) + rotated = rotated[bounds_mask] + + # 计算坐标并应用 floorHeight + x_trimmed = rotated[:, 0] + y_trimmed = rotated[:, 1] + z_trimmed = floorHeight - rotated[:, 2] else: - min_pt = max_pt = rotation = None - - processed_points = [] - seen_xy = set() - - for point in points: - x, y, z = point + x_trimmed = points[:, 0] + y_trimmed = points[:, 1] + z_trimmed = points[:, 2] - # 无效点过滤(Z ≤ 0 或超出最大距离) - if z <= 0 or z > config.CAMERA_CONFIG_MAP[sn].get("max_z", np.inf): - continue + # 合并为一个数组 + trimmed_points = np.column_stack(( + np.round(x_trimmed, 3), + np.round(y_trimmed, 3), + np.round(z_trimmed, 3) + )) - # 应用旋转矩阵 - if clip_config: - rotated = rotation @ point - if not np.all(rotated >= min_pt) or not np.all(rotated <= max_pt): - continue - x_final, y_final, z_final = rotated - else: - x_final, y_final, z_final = x, y, z + # 应用 z 值过滤 + final_mask = (trimmed_points[:, 2] >= z_min) & (trimmed_points[:, 2] <= z_max) + filtered_points = trimmed_points[final_mask] - # 去重逻辑(保留浮点精度) - if dedup: - # 使用浮点哈希避免离散化损失 - key = (round(x_final, 3), round(y_final, 3)) - if key in seen_xy: - continue - seen_xy.add(key) + # 去重 + keys = filtered_points[:, :2] # 只取 x,y + _, unique_indices = np.unique(keys, axis=0, return_index=True) - processed_points.append([x_final, y_final, z_final]) + # 返回 list of [x, y, z] + return filtered_points[unique_indices].tolist() - return processed_points - -def sValue_to_pcd(sValue,stPointCloudImage,sn): +def sValue_to_pcd(sValue,stPointCloudImage,sn,type): # 数据格式转换 points = convert_sdk_points(sValue, stPointCloudImage.nWidth, stPointCloudImage.nHeight) # 应用旋转、裁剪、去重(假设设备序列号已知) - processed_points = process_point_cloud(points, sn, dedup=True) + processed_points = process_point_cloud_fast(points, sn,type) output_ply_path = config.save_path("pcd", sn + ".pcd") # 保存结果 - write_pcd(output_ply_path, processed_points) + # Point.py 修改部分 + from thread_pool import submit_task + + if config.CAMERA_CONFIG_MAP[sn].get("save_pcd"): + output_ply_path = config.save_path("pcd", sn + ".pcd") + # 使用线程池异步执行点云文件写入 + submit_task(write_pcd, output_ply_path, processed_points) + if config.CAMERA_CONFIG_MAP[sn].get("save_not_cut", True): + output_ply_path = config.save_path("pcd", sn + "_original.pcd") + submit_task(write_pcd, output_ply_path, points) + + return output_ply_path,processed_points def write_pcd(filename, points): @@ -214,23 +287,21 @@ def write_pcd(filename, points): with open(filename, 'w') as f: # 写入 PCD 文件头 f.write("# .PCD v0.7 - Point Cloud Data file format\n") - f.write(f"VERSION 0.7\n") + f.write("VERSION 0.7\n") f.write("FIELDS x y z\n") - f.write("SIZE 4 4 4\n") # float 类型的大小是 4 字节 - f.write("TYPE F F F\n") # 每个字段的数据类型 - f.write(f"COUNT 1 1 1\n") # 每个字段的数量 - f.write(f"WIDTH {len(points)}\n") # 点数量 - f.write("HEIGHT 1\n") # 单行表示无结构点云 - f.write("VIEWPOINT 0 0 0 1 0 0 0\n") # 默认视角参数 - f.write(f"POINTS {len(points)}\n") # 总点数 - f.write("DATA ascii\n") # 数据部分以 ASCII 形式存储 + f.write("SIZE 4 4 4\n") + f.write("TYPE F F F\n") + f.write("COUNT 1 1 1\n") + f.write(f"WIDTH {len(points)}\n") + f.write(f"HEIGHT 1\n") + f.write("VIEWPOINT 0 0 0 1 0 0 0\n") + f.write(f"POINTS {len(points)}\n") + f.write("DATA ascii\n") + # 写入点数据 for point in points: f.write(f"{point[0]} {point[1]} {point[2]}\n") - print(f"Saved point cloud to {filename}") - + logger.info(f"Saved point cloud to {filename}") -if __name__ == '__main__': - tiff_depth_to_point_cloud("D:/git/test/hik3d-python/image/2025-06-26/depth/191330147_-Depth.tiff", "00DA6823936") diff --git a/SimpleView_SaveImage.py b/SimpleView_SaveImage.py index 936f1b1..fb5ee15 100644 --- a/SimpleView_SaveImage.py +++ b/SimpleView_SaveImage.py @@ -5,6 +5,7 @@ import ctypes import time import os import struct +from thread_pool import submit_task from ctypes import * from datetime import datetime import Point as point @@ -17,17 +18,47 @@ from Mv3dRgbdImport.Mv3dRgbdDefine import DeviceType_Ethernet, DeviceType_USB, D import config as configMap # 全局变量 SN_MAP = {} # {sn: camera_instance} +import time +import random +from ctypes import * +from logConfig import get_logger -def initialize_devices(): - nDeviceNum = ctypes.c_uint(0) +# 使用示例 +logger = get_logger() + +def reconnect_device(sn, max_retries=5, base_delay=1.0, max_delay=10.0): + """ + 重新连接指定序列号的设备 + + Args: + sn (str): 设备序列号 + max_retries (int): 最大重试次数 + base_delay (float): 初始延迟时间(秒) + max_delay (float): 最大延迟时间(秒) + + Returns: + bool: 重连是否成功 + """ + camera = SN_MAP.get(sn) + + + # 如果设备已存在,先尝试关闭 + try: + camera.MV3D_RGBD_CloseDevice() + except: + pass # 忽略关闭时可能的错误 + + # 获取设备信息(需要重新枚举设备) + nDeviceNum = c_uint(0) ret = Mv3dRgbd.MV3D_RGBD_GetDeviceNumber( DeviceType_Ethernet | DeviceType_USB | DeviceType_Ethernet_Vir | DeviceType_USB_Vir, byref(nDeviceNum) ) + if ret != MV3D_RGBD_OK or nDeviceNum.value == 0: - print("Failed to get device number or no devices found.") - return + logger.error("Failed to get device number or no devices found.") + return False stDeviceList = MV3D_RGBD_DEVICE_INFO_LIST() Mv3dRgbd.MV3D_RGBD_GetDeviceList( @@ -35,115 +66,280 @@ def initialize_devices(): pointer(stDeviceList.DeviceInfo[0]), 20, byref(nDeviceNum) ) + # 查找对应序列号的设备 + target_device_info = None for i in range(nDeviceNum.value): - serial_number = ''.join(chr(c) for c in stDeviceList.DeviceInfo[i].chSerialNumber).rstrip('\x00') - print(f"Found device [{i}]: Serial Number: {serial_number}") + device_sn = ''.join(chr(c) for c in stDeviceList.DeviceInfo[i].chSerialNumber).rstrip('\x00') + if device_sn == sn: + target_device_info = stDeviceList.DeviceInfo[i] + break - camera = Mv3dRgbd() + if not target_device_info: + logger.error(f"Device with SN: {sn} not found during reconnection attempt") + return False - # 打开设备 - ret = camera.MV3D_RGBD_OpenDevice(pointer(stDeviceList.DeviceInfo[i])) - if ret != MV3D_RGBD_OK: - print(f"Failed to open device with SN: {serial_number}. Error code: {ret:#x}") - continue + # 尝试重连 + for attempt in range(max_retries): + try: + # 创建新的相机实例 + new_camera = Mv3dRgbd() - # 存入全局 map - SN_MAP[serial_number] = camera - print(f"Successfully added device {serial_number} to SN_MAP") + # 尝试打开设备 + ret = new_camera.MV3D_RGBD_OpenDevice(pointer(target_device_info)) + if ret == MV3D_RGBD_OK: + # 更新全局映射 + SN_MAP[sn] = new_camera + logger.info(f"Successfully reconnected to device {sn}") + return True + else: + logger.info(f"Failed to reconnect to device {sn}. Error code: {ret:#x}") -def pic(sn): + except Exception as e: + logger.info(f"Exception during reconnection attempt {attempt + 1}: {e}") + + # 如果不是最后一次尝试,等待后重试 + if attempt < max_retries - 1: + # 指数退避延迟 + delay = min(base_delay * (2 ** attempt) + random.uniform(0, 1), max_delay) + logger.info(f"Retrying reconnection in {delay:.2f} seconds...") + time.sleep(delay) + + logger.info(f"Failed to reconnect to device {sn} after {max_retries} attempts") + return False + + +def retry_initialize_devices(max_retries=3, base_delay=2.0): + """ + 重试初始化设备 + + Args: + max_retries (int): 最大重试次数 + base_delay (float): 初始延迟时间(秒) + + Returns: + bool: 初始化是否成功 + """ + for attempt in range(max_retries): + try: + # 清空现有设备映射 + SN_MAP.clear() + + nDeviceNum = c_uint(0) + ret = Mv3dRgbd.MV3D_RGBD_GetDeviceNumber( + DeviceType_Ethernet | DeviceType_USB | DeviceType_Ethernet_Vir | DeviceType_USB_Vir, + byref(nDeviceNum) + ) + + if ret != MV3D_RGBD_OK or nDeviceNum.value == 0: + logger.info("Failed to get device number or no devices found.") + if attempt < max_retries - 1: + delay = base_delay * (2 ** attempt) + logger.info(f"Retrying device initialization in {delay} seconds...") + time.sleep(delay) + continue + + stDeviceList = MV3D_RGBD_DEVICE_INFO_LIST() + Mv3dRgbd.MV3D_RGBD_GetDeviceList( + DeviceType_Ethernet | DeviceType_USB | DeviceType_Ethernet_Vir | DeviceType_USB_Vir, + pointer(stDeviceList.DeviceInfo[0]), 20, byref(nDeviceNum) + ) + + success_count = 0 + for i in range(nDeviceNum.value): + serial_number = ''.join(chr(c) for c in stDeviceList.DeviceInfo[i].chSerialNumber).rstrip('\x00') + logger.info(f"Found device [{i}]: Serial Number: {serial_number}") + + camera = Mv3dRgbd() + + # 打开设备 + ret = camera.MV3D_RGBD_OpenDevice(pointer(stDeviceList.DeviceInfo[i])) + if ret != MV3D_RGBD_OK: + logger.info(f"Failed to open device with SN: {serial_number}. Error code: {ret:#x}") + continue + + # 存入全局 map + SN_MAP[serial_number] = camera + logger.info(f"Successfully added device {serial_number} to SN_MAP") + success_count += 1 + + if success_count > 0: + logger.info(f"Successfully initialized {success_count} devices") + return True + else: + logger.info("No devices were successfully initialized") + + except Exception as e: + logger.info(f"Exception during device initialization attempt {attempt + 1}: {e}") + + if attempt < max_retries - 1: + delay = base_delay * (2 ** attempt) + logger.info(f"Retrying device initialization in {delay} seconds...") + time.sleep(delay) + + logger.info(f"Failed to initialize devices after {max_retries} attempts") + return False + + +def enhanced_pic(sn, type): + """ + 增强版的图片采集函数,包含重连机制和点云数据重试机制 + """ camera = SN_MAP.get(sn) if not camera: - print(f"No camera found for SN: {sn}") - return + logger.info(f"No camera found for SN: {sn}, attempting reconnection...") + if not reconnect_device(sn): + logger.info(f"Failed to reconnect to device {sn}") + return None + camera = SN_MAP.get(sn) config = configMap.CAMERA_CONFIG_MAP.get(sn) if not config: - print(f"No config found for SN: {sn}") - return + logger.info(f"No config found for SN: {sn}") + return None - time_on = config.get("time_on", 0) # 延时开始(毫秒) - print(f"Delaying start by {time_on}ms...") - time.sleep(time_on / 1000.0) # 转成秒 + time_on = config.get("time_on", 0) + logger.info(f"Delaying start by {time_on}ms...") + time.sleep(time_on / 1000.0) saved_files = { - "depth": [], - "color": [], - "pcd": [] + "sn": sn, + "depth": "", + "color": "", + "pcd": "", + "point": [] } - # 开始取流 + # 尝试开始取流,如果失败则尝试重连 ret = camera.MV3D_RGBD_Start() if ret != MV3D_RGBD_OK: - print(f"Failed to start grabbing. Error code: {ret:#x}") - return + logger.info(f"Failed to start grabbing. Error code: {ret:#x}") + logger.info("Attempting reconnection...") + if reconnect_device(sn): + camera = SN_MAP.get(sn) + ret = camera.MV3D_RGBD_Start() + if ret != MV3D_RGBD_OK: + logger.info(f"Failed to start grabbing after reconnection. Error code: {ret:#x}") + return saved_files + else: + logger.info("Reconnection failed") + return saved_files try: - stFrameData = MV3D_RGBD_FRAME_DATA() - - # 获取单帧数据 - ret = camera.MV3D_RGBD_FetchFrame(pointer(stFrameData), 5000) - if ret == MV3D_RGBD_OK: - - for i in range(stFrameData.nImageCount): - image_info = stFrameData.stImageData[i] - - # 保存深度图 - if image_info.enImageType == ImageType_Depth: - file_name = configMap.save_path("depth", "-Depth") - ret_save = camera.MV3D_RGBD_SaveImage(pointer(image_info), FileType_TIFF, file_name) - print("Saved depth image." if ret_save == MV3D_RGBD_OK else "Failed to save depth image.") - if ret_save == MV3D_RGBD_OK: - saved_files["depth"].append(file_name) - - # 点云转换与保存 - stPointCloudImage = MV3D_RGBD_IMAGE_DATA() - ret = camera.MV3D_RGBD_MapDepthToPointCloud(pointer(stFrameData.stImageData[i]), pointer(stPointCloudImage)) - if MV3D_RGBD_OK != ret: - print("_MapDepthToPointCloud() Run failed...") - else: - print( - "_MapDepthToPointCloud() Run Succeed: framenum (%d) height(%d) width(%d) len (%d)!" % ( - stPointCloudImage.nFrameNum, - stPointCloudImage.nHeight, stPointCloudImage.nWidth, stPointCloudImage.nDataLen)) - strMode = string_at(stPointCloudImage.pData, stPointCloudImage.nDataLen) - sValue = struct.unpack('f' * int(stPointCloudImage.nHeight * stPointCloudImage.nWidth * 3), - strMode) - pcd_file = point.sValue_to_pcd(sValue, stPointCloudImage, sn) - if pcd_file: - saved_files["pcd"].append(pcd_file) - - # 保存彩色图 - elif image_info.enImageType in ( - ImageType_RGB8_Planar, ImageType_YUV420SP_NV12, - ImageType_YUV420SP_NV21, ImageType_YUV422 - ): - file_name = configMap.save_path("color", "-_Color") - ret_save = camera.MV3D_RGBD_SaveImage(pointer(image_info), FileType_BMP, file_name) - print("Saved color image." if ret_save == MV3D_RGBD_OK else "Failed to save color image.") - if ret_save == MV3D_RGBD_OK: - saved_files["color"].append(file_name) + # 最多重试10次获取有效的点云数据 + max_retries = 10 + retry_count = 0 + point_cloud_success = False - else: - print("Failed to fetch frame.") + # 用于存储最后一次成功的彩色图数据 + last_color_image_info = None + last_color_file_name = None + + while retry_count < max_retries and not point_cloud_success: + stFrameData = MV3D_RGBD_FRAME_DATA() + + # 获取单帧数据 + ret = camera.MV3D_RGBD_FetchFrame(pointer(stFrameData), 5000) + if ret == MV3D_RGBD_OK: + has_depth_data = False + current_color_image_info = None + current_color_file_name = None + + flag = True + for i in range(stFrameData.nImageCount): + image_info = stFrameData.stImageData[i] + + # 保存深度图 + if image_info.enImageType == ImageType_Depth: + has_depth_data = True + stPointCloudImage = MV3D_RGBD_IMAGE_DATA() + ret = camera.MV3D_RGBD_MapDepthToPointCloud(pointer(stFrameData.stImageData[i]), + pointer(stPointCloudImage)) + if MV3D_RGBD_OK != ret: + logger.info(f"_MapDepthToPointCloud() Run failed... Retry: {retry_count + 1}/{max_retries}") + else: + logger.info( + "_MapDepthToPointCloud() Run Succeed: framenum (%d) height(%d) width(%d) len (%d)!" % ( + stPointCloudImage.nFrameNum, + stPointCloudImage.nHeight, stPointCloudImage.nWidth, stPointCloudImage.nDataLen)) + strMode = string_at(stPointCloudImage.pData, stPointCloudImage.nDataLen) + sValue = struct.unpack('f' * int(stPointCloudImage.nHeight * stPointCloudImage.nWidth * 3), + strMode) + pcd_file, processed_points = point.sValue_to_pcd(sValue, stPointCloudImage, sn, type) + if pcd_file and len(processed_points) > 0: + saved_files["pcd"] = pcd_file + saved_files["point"] = processed_points + point_cloud_success = True # 成功获取点云数据 + flag = False + + # 记录彩色图信息,但不立即保存 + elif image_info.enImageType in ( + ImageType_RGB8_Planar, ImageType_YUV420SP_NV12, + ImageType_YUV420SP_NV21, ImageType_YUV422 + ): + file_name = configMap.save_path("color", sn+"_Color") + if config.get("save_image"): + submit_task(camera.MV3D_RGBD_SaveImage,pointer(image_info), FileType_BMP, file_name) + saved_files["color"] = file_name + ".bmp" + logger.info(f"Color image saved successfully: {saved_files['color']}") + + if flag:break + # 如果没有深度数据或点云处理失败,增加重试次数 + if not has_depth_data: + logger.info(f"No depth data found in frame. Retry: {retry_count + 1}/{max_retries}") + retry_count += 1 + time.sleep(0.1) # 短暂等待后重试 + elif not point_cloud_success: + retry_count += 1 + time.sleep(0.1) # 短暂等待后重试 + + else: + logger.info(f"Failed to fetch frame. Error code: {ret:#x}. Retry: {retry_count + 1}/{max_retries}") + retry_count += 1 + time.sleep(0.1) # 短暂等待后重试 + + except Exception as e: + logger.error(f"Error during frame capture for device {sn}: {e}") finally: camera.MV3D_RGBD_Stop() - print("Single capture completed.") - - # 输出结果路径 - print("Saved files:") - for key, paths in saved_files.items(): - if paths: - print(f" {key.upper()}:") - for path in paths: - print(f" - {path}") + # logger.info(f"Single capture completed. Results: {saved_files}") return saved_files -initialize_devices() +def initialize_devices(): + nDeviceNum = ctypes.c_uint(0) + ret = Mv3dRgbd.MV3D_RGBD_GetDeviceNumber( + DeviceType_Ethernet | DeviceType_USB | DeviceType_Ethernet_Vir | DeviceType_USB_Vir, + byref(nDeviceNum) + ) + if ret != MV3D_RGBD_OK or nDeviceNum.value == 0: + logger.info("Failed to get device number or no devices found.") + return -if __name__ == '__main__': - pic("00DA6823936") \ No newline at end of file + stDeviceList = MV3D_RGBD_DEVICE_INFO_LIST() + Mv3dRgbd.MV3D_RGBD_GetDeviceList( + DeviceType_Ethernet | DeviceType_USB | DeviceType_Ethernet_Vir | DeviceType_USB_Vir, + pointer(stDeviceList.DeviceInfo[0]), 20, byref(nDeviceNum) + ) + + for i in range(nDeviceNum.value): + serial_number = ''.join(chr(c) for c in stDeviceList.DeviceInfo[i].chSerialNumber).rstrip('\x00') + logger.info(f"Found device [{i}]: Serial Number: {serial_number}") + + camera = Mv3dRgbd() + + # 打开设备 + ret = camera.MV3D_RGBD_OpenDevice(pointer(stDeviceList.DeviceInfo[i])) + if ret != MV3D_RGBD_OK: + logger.info(f"Failed to open device with SN: {serial_number}. Error code: {ret:#x}") + continue + + # 存入全局 map + SN_MAP[serial_number] = camera + logger.info(f"Successfully added device {serial_number} to SN_MAP") + + + +initialize_devices() diff --git a/__pycache__/Point.cpython-311.pyc b/__pycache__/Point.cpython-311.pyc index 42d59a1..02a82fb 100644 Binary files a/__pycache__/Point.cpython-311.pyc and b/__pycache__/Point.cpython-311.pyc differ diff --git a/__pycache__/SimpleView_SaveImage.cpython-311.pyc b/__pycache__/SimpleView_SaveImage.cpython-311.pyc index a43789e..9a5d373 100644 Binary files a/__pycache__/SimpleView_SaveImage.cpython-311.pyc and b/__pycache__/SimpleView_SaveImage.cpython-311.pyc differ diff --git a/__pycache__/config.cpython-311.pyc b/__pycache__/config.cpython-311.pyc index 01b272a..21af9b1 100644 Binary files a/__pycache__/config.cpython-311.pyc and b/__pycache__/config.cpython-311.pyc differ diff --git a/__pycache__/image.cpython-311.pyc b/__pycache__/image.cpython-311.pyc index f27d7f0..b294c11 100644 Binary files a/__pycache__/image.cpython-311.pyc and b/__pycache__/image.cpython-311.pyc differ diff --git a/config.py b/config.py index c41cc90..2fffadb 100644 --- a/config.py +++ b/config.py @@ -6,7 +6,7 @@ from datetime import datetime CAMERA_CONFIG_MAP = {} # {sn: config_dict} CUT_CONFIG_MAP = {} # {filename_without_ext: config_dict} DIRECTION_CAMERA = {} -TEMPLATE_MAP = {} +TEMPLATE_CONFIG_MAP = {} def load_camera_configs(config_dir="./config/camera"): """ @@ -50,7 +50,7 @@ def load_template_configs(config_dir="./config/template"): config = json.load(f) type = config.get("type") if type: - TEMPLATE_MAP[type] = config + TEMPLATE_CONFIG_MAP[type] = config print(f"Loaded camera config: {type}") else: print(f"[WARN] No 'sn' found in {filename}") diff --git a/config/camera/00DA6823936.json b/config/camera/00DA6823936.json index f22b34e..9171015 100644 --- a/config/camera/00DA6823936.json +++ b/config/camera/00DA6823936.json @@ -1,13 +1,10 @@ { "sn": "00DA6823936", "direction": "1", - "x_angle": 125, - "y_angle": 75, "save_pcd": true, + "save_image": true, "resolution": 8, - "max_z": 1800, - "reverse_order": false, - "time_on": 100, - "time_off": 5500, - "time_hop": 800 + "max_z": 2000, + "time_on": 0, + "save_not_cut": true } \ No newline at end of file diff --git a/config/camera/00DA6823953.json b/config/camera/00DA6823953.json new file mode 100644 index 0000000..b268dac --- /dev/null +++ b/config/camera/00DA6823953.json @@ -0,0 +1,10 @@ +{ + "sn": "00DA6823953", + "direction": "2", + "save_pcd": true, + "save_image": true, + "resolution": 8, + "max_z": 2000, + "time_on": 0, + "save_not_cut": true +} \ No newline at end of file diff --git a/config/cut/00DA6823936.json b/config/cut/00DA6823936.json new file mode 100644 index 0000000..b43ef6c --- /dev/null +++ b/config/cut/00DA6823936.json @@ -0,0 +1,24 @@ +{ + "floorHeight": 1920, + "max_pt": [ + 550.1860961914062, + -325.56182861328125, + 1564.596435546875 + ], + "min_pt": [ + -560.0139770507812, + -1206.5701904296875, + 344.9464111328125 + ], + "rotation": [ + 1, + 0, + 0, + 0, + 0.7197034358978271, + -0.6942816376686096, + 0, + 0.6942816376686096, + 0.7197034358978271 + ] +} diff --git a/config/cut/00DA6823936_47.json b/config/cut/00DA6823936_47.json new file mode 100644 index 0000000..931bc9c --- /dev/null +++ b/config/cut/00DA6823936_47.json @@ -0,0 +1,24 @@ +{ + "floorHeight": 1920, + "max_pt": [ + 400.86029052734375, + -500.30865478515625, + 1564.596435546875 + ], + "min_pt": [ + -530.2582397460938, + -968.01953125, + 344.9464111328125 + ], + "rotation": [ + 1, + 0, + 0, + 0, + 0.7197034358978271, + -0.6942816376686096, + 0, + 0.6942816376686096, + 0.7197034358978271 + ] +} diff --git a/config/cut/00DA6823936_A.json b/config/cut/00DA6823936_A.json deleted file mode 100644 index 7717188..0000000 --- a/config/cut/00DA6823936_A.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "floorHeight": 1, - "max_pt": [ - 103.20252990722656, - -169.6024932861328, - 182.84439086914062 - ], - "min_pt": [ - 16.854652404785156, - -1234.1793212890625, - 153.4544677734375 - ], - "rotation": [ - -0.006754159927368164, - -0.9998819828033447, - 0.013793319463729858, - 0.43973052501678467, - -0.015358209609985352, - -0.8979983329772949, - 0.8981043100357056, - 0, - 0.4397825002670288 - ] -} diff --git a/config/cut/00DA6823936_B.json b/config/cut/00DA6823936_B.json deleted file mode 100644 index 37c2314..0000000 --- a/config/cut/00DA6823936_B.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "floorHeight": 1, - "max_pt": [ - 59.17729568481445, - -177.37328052520752, - 823.2836303710938 - ], - "min_pt": [ - 0, - -1263.9830322265625, - 200.47930908203125 - ], - "rotation": [ - -0.0070345401763916016, - -0.9998821020126343, - 0.013652533292770386, - 0.4579751193523407, - -0.015358328819274902, - -0.8888324499130249, - 0.88893723487854, - -2.9802322387695312e-08, - 0.45802903175354004 - ] -} diff --git a/config/cut/00DA6823953.json b/config/cut/00DA6823953.json new file mode 100644 index 0000000..1386c86 --- /dev/null +++ b/config/cut/00DA6823953.json @@ -0,0 +1,24 @@ +{ + "floorHeight": 1920, + "max_pt": [ + 512.0901489257812, + -500.2588500976562, + 1564.596435546875 + ], + "min_pt": [ + -508.4150390625, + -1008.01953125, + 344.9464111328125 + ], + "rotation": [ + 1, + 0, + 0, + 0, + 0.7197034358978271, + -0.6942816376686096, + 0, + 0.6942816376686096, + 0.7197034358978271 + ] +} diff --git a/config/cut/00DA6823953_47.json b/config/cut/00DA6823953_47.json new file mode 100644 index 0000000..e9d7142 --- /dev/null +++ b/config/cut/00DA6823953_47.json @@ -0,0 +1,24 @@ +{ + "floorHeight": 1920, + "max_pt": [ + 450.0901489257812, + -500.2588500976562, + 1564.596435546875 + ], + "min_pt": [ + -460.4150390625, + -908.01953125, + 344.9464111328125 + ], + "rotation": [ + 1, + 0, + 0, + 0, + 0.7197034358978271, + -0.6942816376686096, + 0, + 0.6942816376686096, + 0.7197034358978271 + ] +} diff --git a/config/template/45.json b/config/template/45.json index cd50c33..18e970f 100644 --- a/config/template/45.json +++ b/config/template/45.json @@ -1,6 +1,8 @@ { "type": "45", - "width":"299", - "length":"355", - "high":"314" + "width":299, + "length":355, + "height": 1540 , + "min_area": 50, + "tolerance": 60 } \ No newline at end of file diff --git a/config/template/46.json b/config/template/46.json new file mode 100644 index 0000000..44860a1 --- /dev/null +++ b/config/template/46.json @@ -0,0 +1,8 @@ +{ + "type": "46", + "width": 140, + "length": 138, + "height": 1070, + "min_area": 120, + "tolerance": 150 +} \ No newline at end of file diff --git a/config/template/47.json b/config/template/47.json new file mode 100644 index 0000000..0441084 --- /dev/null +++ b/config/template/47.json @@ -0,0 +1,8 @@ +{ + "type": "47", + "width": 299, + "length": 355, + "height": 1370, + "min_area": 500, + "tolerance": 150 +} \ No newline at end of file diff --git a/config/接口说明 b/config/接口说明 new file mode 100644 index 0000000..53de1a3 --- /dev/null +++ b/config/接口说明 @@ -0,0 +1,190 @@ +以下是您当前 Flask 应用中已实现的两个主要接口的 **API 接口文档**,采用标准 RESTful 风格描述。 + +--- + +## 🌐 接口文档 + +### 1. 更新配置 `/config/update` + +#### ✅ 方法 +- `GET` + +#### 📦 描述 +- 重新加载所有配置文件(相机、裁剪、模板等),用于刷新服务端配置。 + +#### 📤 响应示例 + +```json +{ + "message": "Hello, this service config update!", + "status": "OK" +} +``` + + +--- + +### 2. 添加/更新模板配置 `/api/addTemplate` + +#### ✅ 方法 +- `POST` + +#### 📦 描述 +- 接收一个 JSON 对象,以 `"type"` 字段作为文件名,保存为 `./config/template/{type}.json`。 +- 支持覆盖写入已有模板。 +- 写入成功后自动调用 [config.load_configs()](file://D:\git\test\hik3d-python\config.py#L82-L89) 刷新配置。 + +#### 📥 请求体(JSON) + +| 字段名 | 类型 | 必填 | 示例值 | 描述 | +|-------------|--------|------|-----------|--------------------| +| type | string | ✅ | "45" | 模板名称 | +| width | string | ❌ | "299" | 模板宽度(暂无作用) | +| length | string | ❌ | "355" | 模板长度(暂无作用) | +| height | number | ✅ | 314 | 最高高度(单位:毫米)| +| min_area | number | ✅ | 20 | 空洞最小面积 | +| tolerance | number | ✅ | 30 | 容差范围(单位:毫米)| + +##### 示例请求体: + +```json +{ + "type": "45", + "width": "299", + "length": "355", + "height": 314, + "min_area": 20, + "tolerance": 30 +} +``` + + +#### 📤 成功响应 + +```json +{ + "status": "OK", + "message": "Template '45' saved successfully." +} +``` + + +#### 📤 错误响应 + +- 缺少数据: + ```json + { + "status": "ERROR", + "message": "No data provided" + } + ``` + + +- 缺少 `type`: + ```json + { + "status": "ERROR", + "message": "Missing 'type' field" + } + ``` + + +- 写入失败: + ```json + { + "status": "ERROR", + "message": "Failed to save template: [错误信息]" + } + ``` + + +--- + +### 3. 图像处理与空洞检测 `/api/picCompute` + +#### ✅ 方法 +- `POST` + +#### 📦 描述 +- 根据设备编号和模板类型,获取点云并检测是否存在大空洞。 +- 调用了 [SimpleView_SaveImage.pic()](file://D:\git\test\hik3d-python\SimpleView_SaveImage.py#L53-L137) 和 [image.detect_large_holes()](file://D:\git\test\hik3d-python\image.py#L187-L208)。 + +#### 📥 请求体(JSON) + +| 字段名 | 类型 | 必填 | 示例值 | 描述 | +|--------|--------|------|------------|----------------| +| sn | string | ✅ | "00DA6823936" | 设备序列号 | +| type | string | ✅ | "45" | 模板类型(对应模板配置) | + +##### 示例请求体: + +```json +{ + "sn": "00DA6823936", + "type": "45" +} +``` + + +#### 📤 成功响应 + +```json +{ + "message": true, + "status": "OK" +} +``` + + +> `message` 表示是否检测到空洞: +> - `true`:有空洞 +> - `false`:无空洞 + +#### 📤 错误响应 + +- 缺少参数: + ```json + { + "message": "", + "status": "ERROR", + "error": "Missing required parameter: 'sn'" + } + ``` + + +- 模板不存在: + ```json + { + "message": "", + "status": "ERROR", + "error": "Missing required parameter: 'type'" + } + ``` + + +- 其他异常: + ```json + { + "message": "", + "status": "ERROR", + "error": "Failed to get TIFF paths: [错误信息]" + } + ``` + + +--- + +## ⚠️ 全局异常处理 + +所有未捕获的异常都会被全局异常处理器捕获,并返回如下格式: + +```json +{ + "message": "", + "status": "ERROR", + "error": "[错误信息]" +} +``` + + +--- diff --git a/config/配置文件说明.txt b/config/配置文件说明.txt index caf4797..e7ae3cd 100644 --- a/config/配置文件说明.txt +++ b/config/配置文件说明.txt @@ -2,13 +2,26 @@ camera文档 { "sn": "00DA6823936",#sn "direction": "1",#方向 - "x_angle": 55,#相机的水平视场角(相机自身的) - "y_angle": 84,#相机的垂直视场角 "save_pcd": true,#是否保存pcd - "resolution": 8,#像素大小(可以调整来区别 + "resolution": 8,#像素大小(可以调整生成的图片,根据生成图片识别空洞 "max_z": 2000,#最大深度(裁剪之前的 - "reverse_order": false,#是否pcd组成的图片是否翻转 "time_on": 300,#开始时间 - "time_off": 3500,#结束时间 - "time_hop": 500#时间间隔 -} \ No newline at end of file + "save_not_cut": true #基础的没有裁剪的pcd是否保存 +} + +cut 裁剪文档 +名称:sn_template +当template没有的时候读取sn.json + +template 模版文档 +{ + "type": "45", #模版名称 + "width":"299",#模版横 暂无作用 + "length":"355",#模版宽 暂无作用 + "height": 314 ,#最高高度,从裁剪文档里的floorHeight为0 + "min_area": 20 ,#空洞的最小面积 + "tolerance": 30 #冗余,将判断在最高的位置附近,单位毫米 +} + + +先进行最低的位置,写入floorHeight和旋转参数 \ No newline at end of file diff --git a/image.py b/image.py index e4122cc..b06eb81 100644 --- a/image.py +++ b/image.py @@ -1,12 +1,50 @@ import numpy as np import cv2 -import matplotlib.pyplot as plt +import threading +from thread_pool import submit_task from scipy.ndimage import label import config - +from logConfig import get_logger + +# 使用示例 +logger = get_logger() +# +# def point_cloud_to_2d_image(points, resolution=1.0, x_range=(17, 275), y_range=(-129, -1227)): +# """ +# 将点云转换为 2D 图像(X-Y 平面),每个像素值表示对应位置的 Z 值平均值 +# """ +# if not isinstance(points, np.ndarray): +# points = np.array(points) +# +# if len(points) == 0: +# raise ValueError("点云为空") +# +# x_min, x_max = x_range +# y_min, y_max = y_range +# +# width = int((x_max - x_min) / resolution) + 1 +# height = int((y_max - y_min) / resolution) + 1 +# +# image = np.zeros((height, width), dtype=np.float32) +# count_map = np.zeros((height, width), dtype=np.int32) +# +# for x, y, z in points: +# xi = int((x - x_min) / resolution) +# yi = int((y - y_min) / resolution) +# +# if 0 <= xi < width and 0 <= yi < height: +# image[yi, xi] += z +# count_map[yi, xi] += 1 +# +# # 防止除零错误 +# count_map[count_map == 0] = 1 +# image /= count_map +# +# return image, (x_min, y_min) +# 优化 point_cloud_to_2d_image 函数 def point_cloud_to_2d_image(points, resolution=1.0, x_range=(17, 275), y_range=(-129, -1227)): """ 将点云转换为 2D 图像(X-Y 平面),每个像素值表示对应位置的 Z 值平均值 @@ -23,16 +61,32 @@ def point_cloud_to_2d_image(points, resolution=1.0, x_range=(17, 275), y_range=( width = int((x_max - x_min) / resolution) + 1 height = int((y_max - y_min) / resolution) + 1 + # 使用向量化操作替代循环 + x_coords = points[:, 0] + y_coords = points[:, 1] + z_coords = points[:, 2] + + # 计算像素坐标 + xi = ((x_coords - x_min) / resolution).astype(int) + yi = ((y_coords - y_min) / resolution).astype(int) + + # 筛选有效坐标 + valid_mask = (xi >= 0) & (xi < width) & (yi >= 0) & (yi < height) + xi = xi[valid_mask] + yi = yi[valid_mask] + z_coords = z_coords[valid_mask] + + # 使用直方图统计替代循环累加 image = np.zeros((height, width), dtype=np.float32) count_map = np.zeros((height, width), dtype=np.int32) - for x, y, z in points: - xi = int((x - x_min) / resolution) - yi = int((y - y_min) / resolution) + # 使用 bincount 进行快速统计 + indices = yi * width + xi + z_sums = np.bincount(indices, weights=z_coords, minlength=height * width) + counts = np.bincount(indices, minlength=height * width) - if 0 <= xi < width and 0 <= yi < height: - image[yi, xi] += z - count_map[yi, xi] += 1 + image.flat[:] = z_sums + count_map.flat[:] = counts # 防止除零错误 count_map[count_map == 0] = 1 @@ -41,50 +95,30 @@ def point_cloud_to_2d_image(points, resolution=1.0, x_range=(17, 275), y_range=( return image, (x_min, y_min) -def detect_holes_by_density(density_map, density_threshold_ratio=0.5, min_area=100): - """ - 基于点云密度图识别空洞区域 +def stitch(imagePath1, imagePath2): + # 读取两张图像 + image1 = cv2.imread(imagePath1) + image2 = cv2.imread(imagePath2) - :param density_map: 2D numpy array, 每个像素表示该位置点云密度 - :param density_threshold_ratio: 密度低于均值的 ratio 倍时视为空洞候选 - :param min_area: 最小空洞面积(像素数) - :return: list of ((cx, cy), area),空洞中心和面积(图像坐标) - """ - # 计算邻域平均密度(3x3窗口) - avg_density = np.zeros_like(density_map) - for i in range(density_map.shape[0]): - for j in range(density_map.shape[1]): - # 取 3x3 邻域 - neighbors = density_map[ - max(0, i - 1):min(i + 2, density_map.shape[0]), - max(0, j - 1):min(j + 2, density_map.shape[1]) - ] - avg_density[i, j] = np.mean(neighbors) - - # 构建空洞候选区:密度低于邻域平均值的 50% - binary_map = (density_map < avg_density * density_threshold_ratio).astype(np.uint8) - - # 连通域分析 - structure = np.array([[1, 1, 1], - [1, 1, 1], - [1, 1, 1]]) - labeled_map, num_features = label(binary_map, structure=structure) + # 创建 Stitcher 对象 + stitcher = cv2.Stitcher_create() - holes = [] - for label_id in range(1, num_features + 1): - coords = np.where(labeled_map == label_id) - hole_pixel_count = len(coords[0]) + # 拼接图像 + (status, stitched) = stitcher.stitch((image1, image2)) - if hole_pixel_count >= min_area: - cx = np.mean(coords[1]) # x 坐标(列) - cy = np.mean(coords[0]) # y 坐标(行) - area = hole_pixel_count - holes.append(((cx, cy), area)) + # 检查拼接结果 + if status == cv2.Stitcher_OK: + cv2.imwrite('stitched_output.jpg', stitched) + print("图像拼接成功!") + else: + print(f"图像拼接失败,错误代码: {status}") +if __name__ == '__main__': + stitch('D:/git/test/hik3d-python/image/2025-07-01/color/105601193_-_Color.bmp' + , 'D:/git/test/hik3d-python/image/2025-07-01/color/164646720_-_Color.bmp') - return holes -def detect_black_regions(binary_mask, min_area=10): +def detect_black_regions(binary_mask, min_area=10,box_area=10): """ 检测图像中的黑色连通区域(值为 0 的区域) @@ -111,19 +145,18 @@ def detect_black_regions(binary_mask, min_area=10): labeled_map, num_features = label(binary, structure=structure) regions = [] + count = 0 for label_id in range(1, num_features + 1): coords = np.where(labeled_map == label_id) area = len(coords[0]) - if area >= min_area: cx = np.mean(coords[1]) # x 坐标(列) cy = np.mean(coords[0]) # y 坐标(行) - + logger.info(f"区域: {label_id} 中心: {cx, cy} 面积: {area}") regions.append(((cx, cy),area)) - - - return regions + count += ( area/box_area) + return regions,count def convert_image_holes_to_real(holes, offset, resolution): real_holes = [] x_min, y_min = offset @@ -138,23 +171,39 @@ def visualize_holes_on_image(image, holes, output_path=None): """ 在图像上画出检测到的空洞中心和轮廓 """ - # 彩色化灰度图用于可视化 - color_image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR) - - for (cx, cy), _ in holes: - # 绘制圆形标注空洞中心 - cv2.circle(color_image, (int(cx), int(cy)), radius=5, color=(0, 0, 255), thickness=-1) - - # 显示图像 - # plt.figure(figsize=(10, 8)) - plt.imshow(cv2.cvtColor(color_image, cv2.COLOR_BGR2RGB)) - # plt.title("Detected Holes") - plt.axis("off") - output_path = config.save_path("image", "_holes.png") - if output_path: - plt.savefig(output_path, bbox_inches='tight', dpi=200) - print(f"Saved visualization to {output_path}") - # plt.show() + try: + # 确保图像数据有效 + if image is None or len(image) == 0: + print("Warning: Empty image data for visualization") + return + + # 彩色化灰度图用于可视化 + if len(image.shape) == 2: # 灰度图 + color_image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR) + else: + color_image = image.copy() + + # 绘制空洞标记 + if holes: + for (cx, cy), _ in holes: + # 确保坐标有效 + if 0 <= int(cx) < color_image.shape[1] and 0 <= int(cy) < color_image.shape[0]: + cv2.circle(color_image, (int(cx), int(cy)), radius=5, color=(0, 0, 255), thickness=-1) + + # 生成输出路径 + if output_path is None: + output_path = config.save_path("image", "_holes.png") + + # 保存图像 + success = cv2.imwrite(output_path, color_image) + if success: + print(f"Saved visualization to {output_path}") + else: + print(f"Failed to save visualization to {output_path}") + + except Exception as e: + print(f"Error in visualize_holes_on_image: {e}") + def read_pcd_points(pcd_path): """ @@ -183,30 +232,44 @@ def read_pcd_points(pcd_path): continue return points -def detect_large_holes(points,sn, x_max): + +def detect_large_holes(points, sn, type): + # 获取裁剪配置 + cat_map = config.CUT_CONFIG_MAP.get(sn + "_" + type, None) or config.CUT_CONFIG_MAP.get(sn) + template_map = config.TEMPLATE_CONFIG_MAP[type] + camera_map = config.CAMERA_CONFIG_MAP[sn] # 2. 生成 2D 图像 - x_range = (config.CUT_CONFIG_MAP[sn]["min_pt"][0],x_max) # 手动指定 X 范围 - y_range = (config.CUT_CONFIG_MAP[sn]["min_pt"][1], config.CUT_CONFIG_MAP[sn]["max_pt"][1]) # 注意:这里要保证 y_min < y_max,否则反转一下 + x_range = (cat_map["min_pt"][0], cat_map["max_pt"][0]) + y_range = (cat_map["min_pt"][1], cat_map["max_pt"][1]) resolution = config.CAMERA_CONFIG_MAP[sn].get("resolution") image, offset = point_cloud_to_2d_image(points, resolution=resolution, x_range=x_range, y_range=y_range) # 3. 图像归一化用于可视化 normalized_image = cv2.normalize(image, None, 0, 255, cv2.NORM_MINMAX).astype(np.uint8) + min_area = min(template_map["min_area"], (template_map["width"] * template_map["height"]) /(2*camera_map["resolution"]*camera_map["resolution"])) # 4. 检测空洞 - holes = detect_black_regions(normalized_image, min_area=20) + holes, count = detect_black_regions(normalized_image, min_area, (template_map["width"] * template_map["height"]) / 2) + + if config.CAMERA_CONFIG_MAP[sn].get("save_image"): + # 创建数据副本确保异步执行时数据完整性 + image_copy = normalized_image.copy() + holes_copy = list(holes) # 创建holes的副本 - # 5. 可视化空洞 - visualize_holes_on_image(normalized_image, holes) + # 预先生成输出路径 + output_path = config.save_path("image", f"_{sn}_holes.png") + + # 使用线程池异步执行可视化操作 + submit_task(visualize_holes_on_image, image_copy, holes_copy, output_path) # 6. 输出真实世界坐标 real_holes = convert_image_holes_to_real(holes, offset, resolution) - return real_holes + return real_holes, count -if __name__ == '__main__': - points = read_pcd_points("D:/PycharmProjects/Hik3D/image/2025-06-25/pcd/182109899_00DA6823936_merged.pcd") - sn = "00DA6823936" - x_max = 326 - detect_large_holes(points,sn, x_max) +# if __name__ == '__main__': +# points = read_pcd_points("D:/PycharmProjects/Hik3D/image/2025-06-25/pcd/182109899_00DA6823936_merged.pcd") +# sn = "00DA6823936" +# x_max = 326 +# detect_large_holes(points,sn, x_max) \ No newline at end of file diff --git a/logConfig.py b/logConfig.py new file mode 100644 index 0000000..45e4df0 --- /dev/null +++ b/logConfig.py @@ -0,0 +1,64 @@ +import logging +from logging.handlers import TimedRotatingFileHandler +import asyncio +import time +import os + + +# 确保 logs 目录存在 +def ensure_logs_directory(): + logs_dir = "logs" + if not os.path.exists(logs_dir): + os.makedirs(logs_dir) + return logs_dir + + +# 配置日志 +def setup_logger(name, log_file, level=logging.INFO): + # 确保 logs 目录存在 + ensure_logs_directory() + + # 构建完整的日志文件路径 + logs_dir = "logs" + full_log_path = os.path.join(logs_dir, log_file) + + formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') + + # 创建按时间轮转的文件处理器 + handler = TimedRotatingFileHandler( + full_log_path, # 使用完整路径 + when="midnight", # 每天午夜轮转 + interval=1, # 间隔1天 + backupCount=30 # 保留30天的日志 + ) + handler.setFormatter(formatter) + + logger = logging.getLogger(name) + logger.setLevel(level) + # 避免重复添加 handler + if not logger.handlers: + logger.addHandler(handler) + + return logger + + +# 创建全局logger实例 +logger = setup_logger('hik3d', 'app.log') +def get_logger(): + """ + 获取全局logger实例 + """ + return logger +# 异步写入日志的包装函数 +async def async_log(logger, level, message): + # 在线程池中执行日志写入,避免阻塞事件循环 + loop = asyncio.get_event_loop() + await loop.run_in_executor(None, getattr(logger, level), message) + + +# # 使用示例 +# logger = setup_logger('my_app', 'app.log') + + +# 运行 +# asyncio.run(main()) diff --git a/logs/app.log b/logs/app.log new file mode 100644 index 0000000..2e1a4a3 --- /dev/null +++ b/logs/app.log @@ -0,0 +1,374 @@ +2025-08-15 14:58:42,508 - hik3d - INFO - Found device [0]: Serial Number: 00DA6823936 +2025-08-15 14:58:43,733 - hik3d - INFO - Successfully added device 00DA6823936 to SN_MAP +2025-08-15 14:58:43,733 - hik3d - INFO - Found device [1]: Serial Number: 00DA6823953 +2025-08-15 14:58:44,957 - hik3d - INFO - Successfully added device 00DA6823953 to SN_MAP +2025-08-15 14:58:45,411 - hik3d - INFO - ... +2025-08-15 14:58:45,412 - hik3d - INFO - ɹַ: http://0.0.0.0:5000 +2025-08-15 15:36:29,232 - hik3d - INFO - Failed to get device number or no devices found. +2025-08-15 15:36:29,679 - hik3d - INFO - ... +2025-08-15 15:36:29,680 - hik3d - INFO - ɹַ: http://0.0.0.0:5000 +2025-08-15 15:37:16,115 - hik3d - INFO - Found device [0]: Serial Number: 00DA6823936 +2025-08-15 15:37:17,490 - hik3d - INFO - Successfully added device 00DA6823936 to SN_MAP +2025-08-15 15:37:17,490 - hik3d - INFO - Found device [1]: Serial Number: 00DA6823953 +2025-08-15 15:37:18,713 - hik3d - INFO - Successfully added device 00DA6823953 to SN_MAP +2025-08-15 15:37:19,071 - hik3d - INFO - ... +2025-08-15 15:37:19,072 - hik3d - INFO - ɹַ: http://0.0.0.0:5000 +2025-08-15 15:37:32,450 - hik3d - INFO - յȫ豸ͼƬ +2025-08-15 15:37:32,453 - hik3d - INFO - ʼ豸 00DA6823936 ͼƬ +2025-08-15 15:37:32,454 - hik3d - INFO - Delaying start by 0ms... +2025-08-15 15:37:32,454 - hik3d - INFO - ʼ豸 00DA6823953 ͼƬ +2025-08-15 15:37:32,455 - hik3d - INFO - Delaying start by 0ms... +2025-08-15 15:37:32,754 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-15 15:37:32,991 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-15 15:37:34,600 - hik3d - INFO - 豸 00DA6823953 ɣʱ 2.146 룬ֿն: False +2025-08-15 15:37:35,121 - hik3d - INFO - 豸 00DA6823936 ɣʱ 2.668 룬ֿն: False +2025-08-15 15:37:35,198 - hik3d - INFO - ȫ豸ͼƬɣܺʱ 2.747 룬: False +2025-08-15 15:37:36,739 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\153733795_00DA6823953.pcd +2025-08-15 15:37:39,054 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\153734206_00DA6823936.pcd +2025-08-15 15:37:41,353 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\153734217_00DA6823936_original.pcd +2025-08-15 15:37:41,502 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\153733799_00DA6823953_original.pcd +2025-08-15 15:37:49,321 - hik3d - INFO - յȫ豸ͼƬ +2025-08-15 15:37:49,322 - hik3d - INFO - ʼ豸 00DA6823936 ͼƬ +2025-08-15 15:37:49,322 - hik3d - INFO - Delaying start by 0ms... +2025-08-15 15:37:49,322 - hik3d - INFO - ʼ豸 00DA6823953 ͼƬ +2025-08-15 15:37:49,322 - hik3d - INFO - Delaying start by 0ms... +2025-08-15 15:37:49,540 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-15 15:37:49,703 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-15 15:37:50,722 - hik3d - INFO - 豸 00DA6823953 ɣʱ 1.401 룬ֿն: False +2025-08-15 15:37:51,015 - hik3d - INFO - 豸 00DA6823936 ɣʱ 1.692 룬ֿն: False +2025-08-15 15:37:51,023 - hik3d - INFO - ȫ豸ͼƬɣܺʱ 1.702 룬: False +2025-08-15 15:37:52,630 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\153750100_00DA6823953.pcd +2025-08-15 15:37:54,952 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\153750465_00DA6823936.pcd +2025-08-15 15:37:55,908 - hik3d - INFO - յȫ豸ͼƬ +2025-08-15 15:37:55,913 - hik3d - INFO - ʼ豸 00DA6823936 ͼƬ +2025-08-15 15:37:55,927 - hik3d - INFO - Delaying start by 0ms... +2025-08-15 15:37:55,928 - hik3d - INFO - ʼ豸 00DA6823953 ͼƬ +2025-08-15 15:37:55,937 - hik3d - INFO - Delaying start by 0ms... +2025-08-15 15:37:56,225 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-15 15:37:56,430 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-15 15:37:58,020 - hik3d - INFO - 豸 00DA6823953 ɣʱ 2.093 룬ֿն: False +2025-08-15 15:37:58,468 - hik3d - INFO - 豸 00DA6823936 ɣʱ 2.555 룬ֿն: False +2025-08-15 15:37:58,482 - hik3d - INFO - ȫ豸ͼƬɣܺʱ 2.571 룬: False +2025-08-15 15:37:59,779 - hik3d - INFO - յȫ豸ͼƬ +2025-08-15 15:37:59,790 - hik3d - INFO - ʼ豸 00DA6823936 ͼƬ +2025-08-15 15:37:59,794 - hik3d - INFO - Delaying start by 0ms... +2025-08-15 15:37:59,799 - hik3d - INFO - ʼ豸 00DA6823953 ͼƬ +2025-08-15 15:37:59,810 - hik3d - INFO - Delaying start by 0ms... +2025-08-15 15:38:00,140 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-15 15:38:00,354 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-15 15:38:00,621 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\153757193_00DA6823953.pcd +2025-08-15 15:38:02,657 - hik3d - INFO - 豸 00DA6823953 ɣʱ 2.858 룬ֿն: True +2025-08-15 15:38:02,670 - hik3d - INFO - 豸 00DA6823953 ֿնֹͣ +2025-08-15 15:38:02,686 - hik3d - INFO - 豸 00DA6823936 ɣʱ 2.896 룬ֿն: False +2025-08-15 15:38:02,695 - hik3d - INFO - ȫ豸ͼƬɣܺʱ 2.91 룬: True +2025-08-15 15:38:03,478 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\153750469_00DA6823936_original.pcd +2025-08-15 15:38:04,460 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\153750102_00DA6823953_original.pcd +2025-08-15 15:38:06,804 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\153801589_00DA6823953.pcd +2025-08-15 15:38:07,354 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\153757607_00DA6823936.pcd +2025-08-15 15:38:11,996 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\153757201_00DA6823953_original.pcd +2025-08-15 15:38:12,311 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\153801613_00DA6823936.pcd +2025-08-15 15:38:13,728 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\153757647_00DA6823936_original.pcd +2025-08-15 15:38:15,130 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\153801599_00DA6823953_original.pcd +2025-08-15 15:38:15,862 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\153801622_00DA6823936_original.pcd +2025-08-15 15:39:37,573 - hik3d - INFO - յȫ豸ͼƬ +2025-08-15 15:39:37,574 - hik3d - INFO - ʼ豸 00DA6823936 ͼƬ +2025-08-15 15:39:37,574 - hik3d - INFO - Delaying start by 0ms... +2025-08-15 15:39:37,575 - hik3d - INFO - ʼ豸 00DA6823953 ͼƬ +2025-08-15 15:39:37,575 - hik3d - INFO - Delaying start by 0ms... +2025-08-15 15:39:37,812 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-15 15:39:37,996 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-15 15:39:39,036 - hik3d - INFO - 豸 00DA6823953 ɣʱ 1.461 룬ֿն: True +2025-08-15 15:39:39,039 - hik3d - INFO - 豸 00DA6823953 ֿնֹͣ +2025-08-15 15:39:39,232 - hik3d - INFO - 豸 00DA6823936 ɣʱ 1.658 룬ֿն: False +2025-08-15 15:39:39,234 - hik3d - INFO - ȫ豸ͼƬɣܺʱ 1.662 룬: True +2025-08-15 15:39:40,263 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\153938358_00DA6823953.pcd +2025-08-15 15:39:42,346 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\153938671_00DA6823936.pcd +2025-08-15 15:39:46,206 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\153938676_00DA6823936_original.pcd +2025-08-15 15:39:46,463 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\153938359_00DA6823953_original.pcd +2025-08-15 15:42:02,249 - hik3d - INFO - Found device [0]: Serial Number: 00DA6823936 +2025-08-15 15:42:03,473 - hik3d - INFO - Successfully added device 00DA6823936 to SN_MAP +2025-08-15 15:42:03,474 - hik3d - INFO - Found device [1]: Serial Number: 00DA6823953 +2025-08-15 15:42:04,712 - hik3d - INFO - Successfully added device 00DA6823953 to SN_MAP +2025-08-15 15:42:05,112 - hik3d - INFO - ... +2025-08-15 15:42:05,112 - hik3d - INFO - ɹַ: http://0.0.0.0:5000 +2025-08-15 15:42:06,533 - hik3d - INFO - յȫ豸ͼƬ +2025-08-15 15:42:06,534 - hik3d - INFO - ʼ豸 00DA6823936 ͼƬ +2025-08-15 15:42:06,535 - hik3d - INFO - Delaying start by 0ms... +2025-08-15 15:42:06,535 - hik3d - INFO - ʼ豸 00DA6823953 ͼƬ +2025-08-15 15:42:06,536 - hik3d - INFO - Delaying start by 0ms... +2025-08-15 15:42:06,771 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-15 15:42:06,922 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-15 15:42:08,164 - hik3d - INFO - 豸 00DA6823953 ɣʱ 1.629 룬ֿն: False +2025-08-15 15:42:08,582 - hik3d - INFO - 豸 00DA6823936 ɣʱ 2.048 룬ֿն: False +2025-08-15 15:42:08,669 - hik3d - INFO - ȫ豸ͼƬɣܺʱ 2.135 룬: False +2025-08-15 15:42:10,387 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\154207390_00DA6823953.pcd +2025-08-15 15:42:11,069 - hik3d - INFO - յȫ豸ͼƬ +2025-08-15 15:42:11,072 - hik3d - INFO - ʼ豸 00DA6823936 ͼƬ +2025-08-15 15:42:11,077 - hik3d - INFO - Delaying start by 0ms... +2025-08-15 15:42:11,077 - hik3d - INFO - ʼ豸 00DA6823953 ͼƬ +2025-08-15 15:42:11,086 - hik3d - INFO - Delaying start by 0ms... +2025-08-15 15:42:11,340 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-15 15:42:11,560 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-15 15:42:13,340 - hik3d - INFO - 豸 00DA6823953 ɣʱ 2.263 룬ֿն: False +2025-08-15 15:42:13,597 - hik3d - INFO - 豸 00DA6823936 ɣʱ 2.525 룬ֿն: False +2025-08-15 15:42:13,616 - hik3d - INFO - ȫ豸ͼƬɣܺʱ 2.547 룬: False +2025-08-15 15:42:14,486 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\154207737_00DA6823936.pcd +2025-08-15 15:42:15,688 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\154212842_00DA6823953.pcd +2025-08-15 15:42:20,353 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\154212845_00DA6823936.pcd +2025-08-15 15:42:21,444 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\154207750_00DA6823936_original.pcd +2025-08-15 15:42:21,700 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\154207485_00DA6823953_original.pcd +2025-08-15 15:42:25,242 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\154212848_00DA6823953_original.pcd +2025-08-15 15:42:25,928 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\154212853_00DA6823936_original.pcd +2025-08-15 17:46:24,253 - hik3d - INFO - Found device [0]: Serial Number: 00DA6823936 +2025-08-15 17:46:25,489 - hik3d - INFO - Successfully added device 00DA6823936 to SN_MAP +2025-08-15 17:46:25,489 - hik3d - INFO - Found device [1]: Serial Number: 00DA6823953 +2025-08-15 17:46:26,713 - hik3d - INFO - Successfully added device 00DA6823953 to SN_MAP +2025-08-15 17:46:27,162 - hik3d - INFO - ... +2025-08-15 17:46:27,163 - hik3d - INFO - ɹַ: http://0.0.0.0:5000 +2025-08-15 17:50:05,524 - hik3d - INFO - Found device [0]: Serial Number: 00DA6823936 +2025-08-15 17:50:06,758 - hik3d - INFO - Successfully added device 00DA6823936 to SN_MAP +2025-08-15 17:50:06,758 - hik3d - INFO - Found device [1]: Serial Number: 00DA6823953 +2025-08-15 17:50:07,990 - hik3d - INFO - Successfully added device 00DA6823953 to SN_MAP +2025-08-15 17:50:08,348 - hik3d - INFO - ... +2025-08-15 17:50:08,349 - hik3d - INFO - ɹַ: http://0.0.0.0:5000 +2025-08-15 17:50:33,128 - hik3d - INFO - յȫ豸ͼƬ +2025-08-15 17:50:33,129 - hik3d - INFO - ʼ豸 00DA6823936 ͼƬ +2025-08-15 17:50:33,129 - hik3d - INFO - Delaying start by 0ms... +2025-08-15 17:50:37,567 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (90) height(720) width(1280) len (11059200)! +2025-08-15 17:50:40,334 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\175038509_00DA6823936.pcd +2025-08-15 17:50:41,451 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\175038513_00DA6823936_original.pcd +2025-08-15 17:50:42,486 - hik3d - INFO - Point cloud data acquired but no color image found in frames +2025-08-15 17:50:42,578 - hik3d - INFO - 豸 00DA6823936 ɣʱ 9.449 룬ֿն: False +2025-08-15 17:50:42,579 - hik3d - INFO - ʼ豸 00DA6823953 ͼƬ +2025-08-15 17:50:42,579 - hik3d - INFO - Delaying start by 0ms... +2025-08-15 17:50:42,861 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-15 17:50:43,284 - hik3d - INFO - Point cloud data acquired but no color image found in frames +2025-08-15 17:50:43,403 - hik3d - INFO - : 2 : (np.float64(3.015873015873016), np.float64(18.261904761904763)) : 126 +2025-08-15 17:50:43,436 - hik3d - INFO - 豸 00DA6823953 ɣʱ 0.857 룬ֿն: True +2025-08-15 17:50:43,439 - hik3d - INFO - 豸 00DA6823953 ֿնֹͣ +2025-08-15 17:50:43,440 - hik3d - INFO - ȫ豸ͼƬɣܺʱ 10.311 룬: True +2025-08-15 17:50:44,119 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\175043283_00DA6823953.pcd +2025-08-15 17:50:45,877 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\175043283_00DA6823953_original.pcd +2025-08-15 17:52:55,797 - hik3d - INFO - Found device [0]: Serial Number: 00DA6823936 +2025-08-15 17:52:57,003 - hik3d - INFO - Successfully added device 00DA6823936 to SN_MAP +2025-08-15 17:52:57,004 - hik3d - INFO - Found device [1]: Serial Number: 00DA6823953 +2025-08-15 17:52:58,218 - hik3d - INFO - Successfully added device 00DA6823953 to SN_MAP +2025-08-15 17:52:58,595 - hik3d - INFO - ... +2025-08-15 17:52:58,595 - hik3d - INFO - ɹַ: http://0.0.0.0:5000 +2025-08-15 17:53:48,204 - hik3d - INFO - յȫ豸ͼƬ +2025-08-15 17:53:48,205 - hik3d - INFO - ʼ豸 00DA6823936 ͼƬ +2025-08-15 17:53:48,205 - hik3d - INFO - Delaying start by 0ms... +2025-08-15 17:53:48,467 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-15 17:53:50,800 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\175349071_00DA6823936.pcd +2025-08-15 17:53:52,037 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\175349073_00DA6823936_original.pcd +2025-08-15 17:55:39,217 - hik3d - ERROR - Error during frame capture for device 00DA6823936: _type_ must have storage info +2025-08-15 17:55:39,420 - hik3d - INFO - 豸 00DA6823936 ɣʱ 111.215 룬ֿն: False +2025-08-15 17:55:39,421 - hik3d - INFO - ʼ豸 00DA6823953 ͼƬ +2025-08-15 17:55:39,421 - hik3d - INFO - Delaying start by 0ms... +2025-08-15 17:55:39,681 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-15 17:55:41,181 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\175540199_00DA6823953.pcd +2025-08-15 17:55:43,090 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\175540200_00DA6823953_original.pcd +2025-08-15 17:57:37,611 - hik3d - ERROR - Error during frame capture for device 00DA6823953: _type_ must have storage info +2025-08-15 17:57:37,683 - hik3d - INFO - 豸 00DA6823953 ɣʱ 118.262 룬ֿն: False +2025-08-15 17:57:37,683 - hik3d - INFO - ȫ豸ͼƬɣܺʱ 229.479 룬: False +2025-08-15 18:00:03,885 - hik3d - INFO - Found device [0]: Serial Number: 00DA6823936 +2025-08-15 18:00:05,105 - hik3d - INFO - Successfully added device 00DA6823936 to SN_MAP +2025-08-15 18:00:05,105 - hik3d - INFO - Found device [1]: Serial Number: 00DA6823953 +2025-08-15 18:00:06,337 - hik3d - INFO - Successfully added device 00DA6823953 to SN_MAP +2025-08-15 18:00:06,699 - hik3d - INFO - ... +2025-08-15 18:00:06,699 - hik3d - INFO - ɹַ: http://0.0.0.0:5000 +2025-08-15 18:03:31,258 - hik3d - INFO - յȫ豸ͼƬ +2025-08-15 18:03:31,258 - hik3d - INFO - ʼ豸 00DA6823936 ͼƬ +2025-08-15 18:03:31,258 - hik3d - INFO - Delaying start by 0ms... +2025-08-15 18:03:31,515 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-15 18:03:33,852 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\180332128_00DA6823936.pcd +2025-08-15 18:03:36,009 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\180332130_00DA6823936_original.pcd +2025-08-15 18:04:15,069 - hik3d - ERROR - Error during frame capture for device 00DA6823936: 'NoneType' object has no attribute 'encode' +2025-08-15 18:04:15,199 - hik3d - INFO - 豸 00DA6823936 ɣʱ 43.94 룬ֿն: False +2025-08-15 18:04:15,200 - hik3d - INFO - ʼ豸 00DA6823953 ͼƬ +2025-08-15 18:04:15,200 - hik3d - INFO - Delaying start by 0ms... +2025-08-15 18:04:15,445 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-15 18:04:15,844 - hik3d - ERROR - Error during frame capture for device 00DA6823953: 'NoneType' object has no attribute 'encode' +2025-08-15 18:04:15,982 - hik3d - INFO - : 2 : (np.float64(3.015748031496063), np.float64(17.755905511811022)) : 127 +2025-08-15 18:04:16,016 - hik3d - INFO - 豸 00DA6823953 ɣʱ 0.817 룬ֿն: True +2025-08-15 18:04:16,018 - hik3d - INFO - 豸 00DA6823953 ֿնֹͣ +2025-08-15 18:04:16,021 - hik3d - INFO - ȫ豸ͼƬɣܺʱ 44.763 룬: True +2025-08-15 18:04:16,688 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\180415840_00DA6823953.pcd +2025-08-15 18:04:18,438 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\180415841_00DA6823953_original.pcd +2025-08-15 18:04:19,070 - hik3d - INFO - յȫ豸ͼƬ +2025-08-15 18:04:19,070 - hik3d - INFO - ʼ豸 00DA6823936 ͼƬ +2025-08-15 18:04:19,070 - hik3d - INFO - Delaying start by 0ms... +2025-08-15 18:04:19,284 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-15 18:04:19,748 - hik3d - ERROR - Error during frame capture for device 00DA6823936: 'NoneType' object has no attribute 'encode' +2025-08-15 18:04:20,001 - hik3d - INFO - 豸 00DA6823936 ɣʱ 0.931 룬ֿն: False +2025-08-15 18:04:20,004 - hik3d - INFO - ʼ豸 00DA6823953 ͼƬ +2025-08-15 18:04:20,006 - hik3d - INFO - Delaying start by 0ms... +2025-08-15 18:04:20,404 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-15 18:04:20,888 - hik3d - ERROR - Error during frame capture for device 00DA6823953: 'NoneType' object has no attribute 'encode' +2025-08-15 18:04:21,096 - hik3d - INFO - 豸 00DA6823953 ɣʱ 1.092 룬ֿն: False +2025-08-15 18:04:21,102 - hik3d - INFO - ȫ豸ͼƬɣܺʱ 2.032 룬: False +2025-08-15 18:04:22,477 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\180420876_00DA6823953.pcd +2025-08-15 18:04:22,775 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\180419746_00DA6823936.pcd +2025-08-15 18:04:26,212 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\180419747_00DA6823936_original.pcd +2025-08-15 18:04:27,027 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\180420879_00DA6823953_original.pcd +2025-08-15 18:10:39,234 - hik3d - INFO - Found device [0]: Serial Number: 00DA6823936 +2025-08-15 18:10:40,467 - hik3d - INFO - Successfully added device 00DA6823936 to SN_MAP +2025-08-15 18:10:40,468 - hik3d - INFO - Found device [1]: Serial Number: 00DA6823953 +2025-08-15 18:10:41,697 - hik3d - INFO - Successfully added device 00DA6823953 to SN_MAP +2025-08-15 18:10:42,091 - hik3d - INFO - ... +2025-08-15 18:10:42,091 - hik3d - INFO - ɹַ: http://0.0.0.0:5000 +2025-08-15 18:10:44,554 - hik3d - INFO - յȫ豸ͼƬ +2025-08-15 18:10:44,554 - hik3d - INFO - ʼ豸 00DA6823936 ͼƬ +2025-08-15 18:10:44,555 - hik3d - INFO - Delaying start by 0ms... +2025-08-15 18:10:44,831 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-15 18:10:45,486 - hik3d - ERROR - Error during frame capture for device 00DA6823936: unsupported operand type(s) for +: 'NoneType' and 'str' +2025-08-15 18:10:45,762 - hik3d - INFO - 豸 00DA6823936 ɣʱ 1.208 룬ֿն: False +2025-08-15 18:10:45,764 - hik3d - INFO - ʼ豸 00DA6823953 ͼƬ +2025-08-15 18:10:45,766 - hik3d - INFO - Delaying start by 0ms... +2025-08-15 18:10:46,024 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-15 18:10:46,428 - hik3d - ERROR - Error during frame capture for device 00DA6823953: unsupported operand type(s) for +: 'NoneType' and 'str' +2025-08-15 18:10:46,650 - hik3d - INFO - 豸 00DA6823953 ɣʱ 0.886 룬ֿն: False +2025-08-15 18:10:46,651 - hik3d - INFO - ȫ豸ͼƬɣܺʱ 2.097 룬: False +2025-08-15 18:10:48,189 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\181046397_00DA6823953.pcd +2025-08-15 18:10:48,746 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\181045458_00DA6823936.pcd +2025-08-15 18:10:50,855 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\181045461_00DA6823936_original.pcd +2025-08-15 18:10:51,277 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\181046399_00DA6823953_original.pcd +2025-08-15 18:16:38,887 - hik3d - INFO - Found device [0]: Serial Number: 00DA6823936 +2025-08-15 18:16:40,103 - hik3d - INFO - Successfully added device 00DA6823936 to SN_MAP +2025-08-15 18:16:40,103 - hik3d - INFO - Found device [1]: Serial Number: 00DA6823953 +2025-08-15 18:16:41,320 - hik3d - INFO - Successfully added device 00DA6823953 to SN_MAP +2025-08-15 18:16:41,661 - hik3d - INFO - ... +2025-08-15 18:16:41,661 - hik3d - INFO - ɹַ: http://0.0.0.0:5000 +2025-08-15 18:16:45,462 - hik3d - INFO - յȫ豸ͼƬ +2025-08-15 18:16:45,463 - hik3d - INFO - ʼ豸 00DA6823936 ͼƬ +2025-08-15 18:16:45,463 - hik3d - INFO - Delaying start by 0ms... +2025-08-15 18:16:45,701 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-15 18:16:46,339 - hik3d - INFO - Color image saved successfully: .\image\2025-08-15\color\181646336_00DA6823936_Color.bmp +2025-08-15 18:16:46,627 - hik3d - INFO - 豸 00DA6823936 ɣʱ 1.163 룬ֿն: False +2025-08-15 18:16:46,629 - hik3d - INFO - ʼ豸 00DA6823953 ͼƬ +2025-08-15 18:16:46,631 - hik3d - INFO - Delaying start by 0ms... +2025-08-15 18:16:46,903 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-15 18:16:47,323 - hik3d - INFO - Color image saved successfully: .\image\2025-08-15\color\181647323_00DA6823953_Color.bmp +2025-08-15 18:16:47,482 - hik3d - INFO - : 1 : (np.float64(3.1548387096774193), np.float64(16.929032258064517)) : 155 +2025-08-15 18:16:47,547 - hik3d - INFO - 豸 00DA6823953 ɣʱ 0.918 룬ֿն: True +2025-08-15 18:16:47,551 - hik3d - INFO - 豸 00DA6823953 ֿնֹͣ +2025-08-15 18:16:47,555 - hik3d - INFO - ȫ豸ͼƬɣܺʱ 2.092 룬: True +2025-08-15 18:16:48,974 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\181647310_00DA6823953.pcd +2025-08-15 18:16:49,964 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\181646329_00DA6823936.pcd +2025-08-15 18:16:54,723 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\181646331_00DA6823936_original.pcd +2025-08-15 18:16:54,887 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\181647312_00DA6823953_original.pcd +2025-08-15 18:18:58,924 - hik3d - INFO - Found device [0]: Serial Number: 00DA6823936 +2025-08-15 18:19:00,158 - hik3d - INFO - Successfully added device 00DA6823936 to SN_MAP +2025-08-15 18:19:00,158 - hik3d - INFO - Found device [1]: Serial Number: 00DA6823953 +2025-08-15 18:19:01,382 - hik3d - INFO - Successfully added device 00DA6823953 to SN_MAP +2025-08-15 18:19:01,782 - hik3d - INFO - ... +2025-08-15 18:19:01,782 - hik3d - INFO - ɹַ: http://0.0.0.0:5000 +2025-08-15 18:19:23,167 - hik3d - INFO - յȫ豸ͼƬ +2025-08-15 18:19:23,168 - hik3d - INFO - ʼ豸 00DA6823936 ͼƬ +2025-08-15 18:19:23,168 - hik3d - INFO - Delaying start by 0ms... +2025-08-15 18:19:23,433 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-15 18:19:24,043 - hik3d - INFO - Color image saved successfully: .\image\2025-08-15\color\181924040_00DA6823936_Color.bmp +2025-08-15 18:19:24,313 - hik3d - INFO - 豸 00DA6823936 ɣʱ 1.145 룬ֿն: False +2025-08-15 18:19:24,314 - hik3d - INFO - ʼ豸 00DA6823953 ͼƬ +2025-08-15 18:19:24,318 - hik3d - INFO - Delaying start by 0ms... +2025-08-15 18:19:24,592 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-15 18:19:25,026 - hik3d - INFO - Color image saved successfully: .\image\2025-08-15\color\181925024_00DA6823953_Color.bmp +2025-08-15 18:19:25,237 - hik3d - INFO - 豸 00DA6823953 ɣʱ 0.923 룬ֿն: False +2025-08-15 18:19:25,241 - hik3d - INFO - ȫ豸ͼƬɣܺʱ 2.073 룬: False +2025-08-15 18:19:26,553 - hik3d - INFO - յȫ豸ͼƬ +2025-08-15 18:19:26,559 - hik3d - INFO - ʼ豸 00DA6823936 ͼƬ +2025-08-15 18:19:26,566 - hik3d - INFO - Delaying start by 0ms... +2025-08-15 18:19:26,987 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-15 18:19:27,267 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\181925011_00DA6823953.pcd +2025-08-15 18:19:28,068 - hik3d - INFO - Color image saved successfully: .\image\2025-08-15\color\181928068_00DA6823936_Color.bmp +2025-08-15 18:19:28,673 - hik3d - INFO - 豸 00DA6823936 ɣʱ 2.114 룬ֿն: False +2025-08-15 18:19:28,674 - hik3d - INFO - ʼ豸 00DA6823953 ͼƬ +2025-08-15 18:19:28,679 - hik3d - INFO - Delaying start by 0ms... +2025-08-15 18:19:28,939 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\181924033_00DA6823936.pcd +2025-08-15 18:19:28,971 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-15 18:19:29,794 - hik3d - INFO - Color image saved successfully: .\image\2025-08-15\color\181929794_00DA6823953_Color.bmp +2025-08-15 18:19:30,064 - hik3d - INFO - 豸 00DA6823953 ɣʱ 1.39 룬ֿն: False +2025-08-15 18:19:30,069 - hik3d - INFO - ȫ豸ͼƬɣܺʱ 3.51 룬: False +2025-08-15 18:19:31,271 - hik3d - INFO - յȫ豸ͼƬ +2025-08-15 18:19:31,276 - hik3d - INFO - ʼ豸 00DA6823936 ͼƬ +2025-08-15 18:19:31,276 - hik3d - INFO - Delaying start by 0ms... +2025-08-15 18:19:31,542 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-15 18:19:32,607 - hik3d - INFO - Color image saved successfully: .\image\2025-08-15\color\181932607_00DA6823936_Color.bmp +2025-08-15 18:19:33,200 - hik3d - INFO - 豸 00DA6823936 ɣʱ 1.924 룬ֿն: False +2025-08-15 18:19:33,205 - hik3d - INFO - ʼ豸 00DA6823953 ͼƬ +2025-08-15 18:19:33,210 - hik3d - INFO - Delaying start by 0ms... +2025-08-15 18:19:33,482 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-15 18:19:34,339 - hik3d - INFO - Color image saved successfully: .\image\2025-08-15\color\181934339_00DA6823953_Color.bmp +2025-08-15 18:19:34,610 - hik3d - INFO - 豸 00DA6823953 ɣʱ 1.404 룬ֿն: False +2025-08-15 18:19:34,613 - hik3d - INFO - ȫ豸ͼƬɣܺʱ 3.338 룬: False +2025-08-15 18:19:35,691 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\181928053_00DA6823936.pcd +2025-08-15 18:19:36,188 - hik3d - INFO - յȫ豸ͼƬ +2025-08-15 18:19:36,197 - hik3d - INFO - ʼ豸 00DA6823936 ͼƬ +2025-08-15 18:19:36,206 - hik3d - INFO - Delaying start by 0ms... +2025-08-15 18:19:36,503 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-15 18:19:37,495 - hik3d - INFO - Color image saved successfully: .\image\2025-08-15\color\181937495_00DA6823936_Color.bmp +2025-08-15 18:19:38,204 - hik3d - INFO - 豸 00DA6823936 ɣʱ 2.007 룬ֿն: False +2025-08-15 18:19:38,213 - hik3d - INFO - ʼ豸 00DA6823953 ͼƬ +2025-08-15 18:19:38,219 - hik3d - INFO - Delaying start by 0ms... +2025-08-15 18:19:38,702 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-15 18:19:39,359 - hik3d - INFO - Color image saved successfully: .\image\2025-08-15\color\181939359_00DA6823953_Color.bmp +2025-08-15 18:19:39,387 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\181924035_00DA6823936_original.pcd +2025-08-15 18:19:39,577 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\181929774_00DA6823953.pcd +2025-08-15 18:19:39,684 - hik3d - INFO - 豸 00DA6823953 ɣʱ 1.472 룬ֿն: False +2025-08-15 18:19:39,694 - hik3d - INFO - ȫ豸ͼƬɣܺʱ 3.497 룬: False +2025-08-15 18:19:41,579 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\181925016_00DA6823953_original.pcd +2025-08-15 18:19:45,468 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\181928060_00DA6823936_original.pcd +2025-08-15 18:19:45,525 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\181932590_00DA6823936.pcd +2025-08-15 18:19:47,666 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\181934323_00DA6823953.pcd +2025-08-15 18:19:50,543 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\181929785_00DA6823953_original.pcd +2025-08-15 18:19:50,887 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\181937478_00DA6823936.pcd +2025-08-15 18:19:51,124 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\181932598_00DA6823936_original.pcd +2025-08-15 18:19:52,495 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\181939341_00DA6823953.pcd +2025-08-15 18:19:53,789 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\181934331_00DA6823953_original.pcd +2025-08-15 18:19:55,718 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\181937487_00DA6823936_original.pcd +2025-08-15 18:19:55,969 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\181939350_00DA6823953_original.pcd +2025-08-15 18:20:28,544 - hik3d - INFO - յȫ豸ͼƬ +2025-08-15 18:20:28,544 - hik3d - INFO - ʼ豸 00DA6823936 ͼƬ +2025-08-15 18:20:28,544 - hik3d - INFO - Delaying start by 0ms... +2025-08-15 18:20:28,763 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-15 18:20:29,247 - hik3d - INFO - Color image saved successfully: .\image\2025-08-15\color\182029247_00DA6823936_Color.bmp +2025-08-15 18:20:29,515 - hik3d - INFO - 豸 00DA6823936 ɣʱ 0.971 룬ֿն: False +2025-08-15 18:20:29,519 - hik3d - INFO - ʼ豸 00DA6823953 ͼƬ +2025-08-15 18:20:29,521 - hik3d - INFO - Delaying start by 0ms... +2025-08-15 18:20:29,756 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-15 18:20:30,185 - hik3d - INFO - Color image saved successfully: .\image\2025-08-15\color\182030185_00DA6823953_Color.bmp +2025-08-15 18:20:30,393 - hik3d - INFO - 豸 00DA6823953 ɣʱ 0.874 룬ֿն: False +2025-08-15 18:20:30,397 - hik3d - INFO - ȫ豸ͼƬɣܺʱ 1.852 룬: False +2025-08-15 18:20:31,892 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\182030178_00DA6823953.pcd +2025-08-15 18:20:32,965 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\182029244_00DA6823936.pcd +2025-08-15 18:20:37,227 - hik3d - INFO - յȫ豸ͼƬ +2025-08-15 18:20:37,229 - hik3d - INFO - ʼ豸 00DA6823936 ͼƬ +2025-08-15 18:20:37,231 - hik3d - INFO - Delaying start by 0ms... +2025-08-15 18:20:37,494 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-15 18:20:37,787 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\182029245_00DA6823936_original.pcd +2025-08-15 18:20:38,279 - hik3d - INFO - Color image saved successfully: .\image\2025-08-15\color\182038279_00DA6823936_Color.bmp +2025-08-15 18:20:38,473 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\182030181_00DA6823953_original.pcd +2025-08-15 18:20:38,666 - hik3d - INFO - 豸 00DA6823936 ɣʱ 1.437 룬ֿն: False +2025-08-15 18:20:38,666 - hik3d - INFO - ʼ豸 00DA6823953 ͼƬ +2025-08-15 18:20:38,667 - hik3d - INFO - Delaying start by 0ms... +2025-08-15 18:20:39,120 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-15 18:20:39,788 - hik3d - INFO - Color image saved successfully: .\image\2025-08-15\color\182039788_00DA6823953_Color.bmp +2025-08-15 18:20:40,061 - hik3d - INFO - : 1 : (np.float64(6.953488372093023), np.float64(5.005813953488372)) : 172 +2025-08-15 18:20:40,124 - hik3d - INFO - 豸 00DA6823953 ɣʱ 1.458 룬ֿն: True +2025-08-15 18:20:40,130 - hik3d - INFO - 豸 00DA6823953 ֿնֹͣ +2025-08-15 18:20:40,139 - hik3d - INFO - ȫ豸ͼƬɣܺʱ 2.91 룬: True +2025-08-15 18:20:42,058 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\182039776_00DA6823953.pcd +2025-08-15 18:20:43,158 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\182038265_00DA6823936.pcd +2025-08-15 18:20:47,244 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\182038269_00DA6823936_original.pcd +2025-08-15 18:20:47,958 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\182039781_00DA6823953_original.pcd +2025-08-15 18:20:54,497 - hik3d - INFO - յȫ豸ͼƬ +2025-08-15 18:20:54,498 - hik3d - INFO - ʼ豸 00DA6823936 ͼƬ +2025-08-15 18:20:54,498 - hik3d - INFO - Delaying start by 0ms... +2025-08-15 18:20:54,745 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-15 18:20:55,503 - hik3d - INFO - Color image saved successfully: .\image\2025-08-15\color\182055502_00DA6823936_Color.bmp +2025-08-15 18:20:55,764 - hik3d - INFO - : 4 : (np.float64(130.0084985835694), np.float64(10.51841359773371)) : 353 +2025-08-15 18:20:55,852 - hik3d - INFO - 豸 00DA6823936 ɣʱ 1.354 룬ֿն: True +2025-08-15 18:20:55,852 - hik3d - INFO - 豸 00DA6823936 ֿնֹͣ +2025-08-15 18:20:55,860 - hik3d - INFO - ȫ豸ͼƬɣܺʱ 1.361 룬: True +2025-08-15 18:20:58,111 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\182055494_00DA6823936.pcd +2025-08-15 18:21:00,396 - hik3d - INFO - Saved point cloud to .\image\2025-08-15\pcd\182055498_00DA6823936_original.pcd diff --git a/logs/app.log.2025-08-13 b/logs/app.log.2025-08-13 new file mode 100644 index 0000000..158447e --- /dev/null +++ b/logs/app.log.2025-08-13 @@ -0,0 +1,31 @@ +2025-08-13 16:12:20,821 - my_app - INFO - ??????????... +2025-08-13 16:12:20,822 - my_app - INFO - ????????????????????: http://0.0.0.0:5000 +2025-08-13 16:15:30,880 - my_app - INFO - ??????????????????? +2025-08-13 16:15:30,880 - my_app - INFO - ????????? 00DA6823953 ???? 46 ???????? +2025-08-13 16:15:32,037 - my_app - INFO - ?? 00DA6823953 ????????????????: True +2025-08-13 16:16:18,432 - my_app - INFO - ??????????????????? +2025-08-13 16:16:18,432 - my_app - INFO - ????????? 00DA6823953 ???? 46 ???????? +2025-08-13 16:18:41,293 - my_app - INFO - ?? 00DA6823953 ????????????????: True +2025-08-13 16:19:50,738 - my_app - INFO - ??????????????????? +2025-08-13 16:19:50,738 - my_app - INFO - ????????? 00DA6823953 ???? 46 ???????? +2025-08-13 16:22:36,790 - my_app - INFO - ?? 00DA6823953 ????????????????: True +2025-08-13 16:22:43,332 - my_app - INFO - ??????????????????? +2025-08-13 16:22:43,333 - my_app - INFO - ????????? 00DA6823953 ???? 46 ???????? +2025-08-13 16:32:29,290 - my_app - INFO - ?? 00DA6823953 ????????????????: True +2025-08-13 16:34:45,693 - my_app - INFO - ??????????... +2025-08-13 16:34:45,693 - my_app - INFO - ????????????????????: http://0.0.0.0:5000 +2025-08-13 16:34:48,018 - my_app - INFO - ??????????????????? +2025-08-13 16:34:48,019 - my_app - INFO - ????????? 00DA6823953 ???? 46 ???????? +2025-08-13 16:37:21,400 - my_app - INFO - ??????????... +2025-08-13 16:37:21,400 - my_app - INFO - ????????????????????: http://0.0.0.0:5000 +2025-08-13 16:37:25,853 - my_app - INFO - ??????????????????? +2025-08-13 16:37:25,853 - my_app - INFO - ????????? 00DA6823953 ???? 46 ???????? +2025-08-13 16:39:18,660 - my_app - INFO - ??????????... +2025-08-13 16:39:18,660 - my_app - INFO - ????????????????????: http://0.0.0.0:5000 +2025-08-13 16:39:20,967 - my_app - INFO - ??????????????????? +2025-08-13 16:39:20,967 - my_app - INFO - ????????? 00DA6823953 ???? 46 ???????? +2025-08-13 16:42:12,161 - my_app - INFO - ??????????... +2025-08-13 16:42:12,161 - my_app - INFO - ????????????????????: http://0.0.0.0:5000 +2025-08-13 16:42:12,686 - my_app - INFO - ??????????????????? +2025-08-13 16:42:12,686 - my_app - INFO - ????????? 00DA6823953 ???? 46 ???????? +2025-08-13 16:43:58,412 - my_app - INFO - ?? 00DA6823953 ????????????????: True diff --git a/logs/app.log.2025-08-14 b/logs/app.log.2025-08-14 new file mode 100644 index 0000000..2cb4831 --- /dev/null +++ b/logs/app.log.2025-08-14 @@ -0,0 +1,129 @@ +2025-08-14 10:53:41,032 - my_app - INFO - յȫ豸ͼƬ +2025-08-14 10:53:41,063 - my_app - INFO - ʼ豸 00DA6823936 ͼƬ +2025-08-14 10:53:42,203 - my_app - ERROR - δ쳣: 'NoneType' object has no attribute 'get' +2025-08-14 10:53:58,406 - my_app - ERROR - δ쳣: 405 Method Not Allowed: The method is not allowed for the requested URL. +2025-08-14 10:54:02,996 - my_app - INFO - յȫ豸ͼƬ +2025-08-14 10:54:02,997 - my_app - INFO - ʼ豸 00DA6823936 ͼƬ +2025-08-14 10:54:04,023 - my_app - ERROR - δ쳣: 'NoneType' object has no attribute 'get' +2025-08-14 11:08:48,337 - hik3d - INFO - Found device [0]: Serial Number: 00DA6823936 +2025-08-14 11:08:49,581 - hik3d - INFO - Successfully added device 00DA6823936 to SN_MAP +2025-08-14 11:08:49,582 - hik3d - INFO - Found device [1]: Serial Number: 00DA6823953 +2025-08-14 11:08:50,815 - hik3d - INFO - Successfully added device 00DA6823953 to SN_MAP +2025-08-14 11:08:51,290 - hik3d - INFO - ... +2025-08-14 11:08:51,290 - hik3d - INFO - ɹַ: http://0.0.0.0:5000 +2025-08-14 11:09:14,203 - hik3d - INFO - Found device [0]: Serial Number: 00DA6823936 +2025-08-14 11:09:15,432 - hik3d - INFO - Successfully added device 00DA6823936 to SN_MAP +2025-08-14 11:09:15,432 - hik3d - INFO - Found device [1]: Serial Number: 00DA6823953 +2025-08-14 11:09:16,673 - hik3d - INFO - Successfully added device 00DA6823953 to SN_MAP +2025-08-14 11:09:17,005 - hik3d - INFO - ... +2025-08-14 11:09:17,005 - hik3d - INFO - ɹַ: http://0.0.0.0:5000 +2025-08-14 11:09:30,806 - hik3d - INFO - Found device [0]: Serial Number: 00DA6823936 +2025-08-14 11:09:32,021 - hik3d - INFO - Successfully added device 00DA6823936 to SN_MAP +2025-08-14 11:09:32,021 - hik3d - INFO - Found device [1]: Serial Number: 00DA6823953 +2025-08-14 11:09:33,242 - hik3d - INFO - Successfully added device 00DA6823953 to SN_MAP +2025-08-14 11:09:33,563 - hik3d - INFO - ... +2025-08-14 11:09:33,563 - hik3d - INFO - ɹַ: http://0.0.0.0:5000 +2025-08-14 11:11:28,300 - hik3d - INFO - յȫ豸ͼƬ +2025-08-14 11:11:28,303 - hik3d - INFO - ʼ豸 00DA6823936 ͼƬ +2025-08-14 11:11:28,304 - hik3d - INFO - Delaying start by 0ms... +2025-08-14 11:11:28,304 - hik3d - INFO - ʼ豸 00DA6823953 ͼƬ +2025-08-14 11:11:28,304 - hik3d - INFO - Delaying start by 0ms... +2025-08-14 11:11:28,604 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-14 11:11:28,955 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-14 11:11:29,844 - hik3d - INFO - Single capture completed. +2025-08-14 11:11:29,890 - hik3d - INFO - Single capture completed. +2025-08-14 11:11:32,596 - hik3d - INFO - Saved point cloud to .\image\2025-08-14\pcd\111129675_00DA6823953.pcd +2025-08-14 11:11:32,999 - hik3d - INFO - Saved point cloud to .\image\2025-08-14\pcd\111129813_00DA6823936.pcd +2025-08-14 11:11:37,728 - hik3d - INFO - Saved point cloud to .\image\2025-08-14\pcd\111129826_00DA6823936_original.pcd +2025-08-14 11:11:37,912 - hik3d - INFO - Saved point cloud to .\image\2025-08-14\pcd\111129679_00DA6823953_original.pcd +2025-08-14 11:11:41,891 - hik3d - INFO - 豸 00DA6823936 ɣʱ 13.588 룬ֿն: False +2025-08-14 11:11:41,891 - hik3d - INFO - 豸 00DA6823953 ɣʱ 13.587 룬ֿն: False +2025-08-14 11:11:41,901 - hik3d - INFO - ȫ豸ͼƬɣܺʱ 13.601 룬: False +2025-08-14 11:11:48,424 - hik3d - INFO - յȫ豸ͼƬ +2025-08-14 11:11:48,425 - hik3d - INFO - ʼ豸 00DA6823936 ͼƬ +2025-08-14 11:11:48,425 - hik3d - INFO - Delaying start by 0ms... +2025-08-14 11:11:48,425 - hik3d - INFO - ʼ豸 00DA6823953 ͼƬ +2025-08-14 11:11:48,425 - hik3d - INFO - Delaying start by 0ms... +2025-08-14 11:11:48,680 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-14 11:11:48,738 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-14 11:11:49,370 - hik3d - INFO - Single capture completed. +2025-08-14 11:11:49,373 - hik3d - INFO - Single capture completed. +2025-08-14 11:11:49,679 - hik3d - INFO - 豸 00DA6823936 ɣʱ 1.254 룬ֿն: False +2025-08-14 11:11:49,684 - hik3d - INFO - 豸 00DA6823953 ɣʱ 1.259 룬ֿն: False +2025-08-14 11:11:49,693 - hik3d - INFO - ȫ豸ͼƬɣܺʱ 1.269 룬: False +2025-08-14 11:11:51,210 - hik3d - INFO - Saved point cloud to .\image\2025-08-14\pcd\111149339_00DA6823953.pcd +2025-08-14 11:11:51,587 - hik3d - INFO - Saved point cloud to .\image\2025-08-14\pcd\111149339_00DA6823936.pcd +2025-08-14 11:11:57,141 - hik3d - INFO - Saved point cloud to .\image\2025-08-14\pcd\111149341_00DA6823936_original.pcd +2025-08-14 11:11:57,405 - hik3d - INFO - Saved point cloud to .\image\2025-08-14\pcd\111149340_00DA6823953_original.pcd +2025-08-14 11:12:13,342 - hik3d - INFO - յȫ豸ͼƬ +2025-08-14 11:12:13,343 - hik3d - INFO - ʼ豸 00DA6823936 ͼƬ +2025-08-14 11:12:13,343 - hik3d - INFO - Delaying start by 0ms... +2025-08-14 11:12:13,344 - hik3d - INFO - ʼ豸 00DA6823953 ͼƬ +2025-08-14 11:12:13,344 - hik3d - INFO - Delaying start by 0ms... +2025-08-14 11:12:13,565 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-14 11:12:13,702 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-14 11:12:14,209 - hik3d - INFO - Single capture completed. +2025-08-14 11:12:14,244 - hik3d - INFO - Single capture completed. +2025-08-14 11:12:14,491 - hik3d - INFO - 豸 00DA6823936 ɣʱ 1.148 룬ֿն: False +2025-08-14 11:12:14,687 - hik3d - INFO - 豸 00DA6823953 ɣʱ 1.343 룬ֿն: True +2025-08-14 11:12:14,691 - hik3d - INFO - 豸 00DA6823953 ֿնֹͣ +2025-08-14 11:12:14,698 - hik3d - INFO - ȫ豸ͼƬɣܺʱ 1.355 룬: True +2025-08-14 11:12:15,847 - hik3d - INFO - Saved point cloud to .\image\2025-08-14\pcd\111214178_00DA6823953.pcd +2025-08-14 11:12:16,160 - hik3d - INFO - Saved point cloud to .\image\2025-08-14\pcd\111214178_00DA6823936.pcd +2025-08-14 11:12:21,519 - hik3d - INFO - Saved point cloud to .\image\2025-08-14\pcd\111214180_00DA6823936_original.pcd +2025-08-14 11:12:21,798 - hik3d - INFO - Saved point cloud to .\image\2025-08-14\pcd\111214182_00DA6823953_original.pcd +2025-08-14 11:13:01,133 - hik3d - INFO - յȫ豸ͼƬ +2025-08-14 11:13:01,134 - hik3d - INFO - ʼ豸 00DA6823936 ͼƬ +2025-08-14 11:13:01,135 - hik3d - INFO - Delaying start by 0ms... +2025-08-14 11:13:01,135 - hik3d - INFO - ʼ豸 00DA6823953 ͼƬ +2025-08-14 11:13:01,135 - hik3d - INFO - Delaying start by 0ms... +2025-08-14 11:13:01,356 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-14 11:13:01,508 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-14 11:13:02,036 - hik3d - INFO - Single capture completed. +2025-08-14 11:13:02,143 - hik3d - INFO - Single capture completed. +2025-08-14 11:13:02,325 - hik3d - INFO - 豸 00DA6823953 ɣʱ 1.19 룬ֿն: False +2025-08-14 11:13:02,376 - hik3d - INFO - 豸 00DA6823936 ɣʱ 1.242 룬ֿն: False +2025-08-14 11:13:02,390 - hik3d - INFO - ȫ豸ͼƬɣܺʱ 1.257 룬: False +2025-08-14 11:13:03,712 - hik3d - INFO - Saved point cloud to .\image\2025-08-14\pcd\111301877_00DA6823953.pcd +2025-08-14 11:13:04,157 - hik3d - INFO - Saved point cloud to .\image\2025-08-14\pcd\111302097_00DA6823936.pcd +2025-08-14 11:13:09,521 - hik3d - INFO - Saved point cloud to .\image\2025-08-14\pcd\111302102_00DA6823936_original.pcd +2025-08-14 11:13:09,693 - hik3d - INFO - Saved point cloud to .\image\2025-08-14\pcd\111301877_00DA6823953_original.pcd +2025-08-14 11:21:14,864 - hik3d - INFO - յȫ豸ͼƬ +2025-08-14 11:21:14,865 - hik3d - INFO - ʼ豸 00DA6823936 ͼƬ +2025-08-14 11:21:14,865 - hik3d - INFO - Delaying start by 0ms... +2025-08-14 11:21:14,865 - hik3d - INFO - ʼ豸 00DA6823953 ͼƬ +2025-08-14 11:21:14,866 - hik3d - INFO - Delaying start by 0ms... +2025-08-14 11:21:15,111 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-14 11:21:15,278 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-14 11:21:15,884 - hik3d - INFO - Single capture completed. +2025-08-14 11:21:16,011 - hik3d - INFO - Single capture completed. +2025-08-14 11:21:16,345 - hik3d - INFO - 豸 00DA6823953 ɣʱ 1.48 룬ֿն: False +2025-08-14 11:21:16,358 - hik3d - INFO - 豸 00DA6823936 ɣʱ 1.493 룬ֿն: False +2025-08-14 11:21:16,370 - hik3d - INFO - ȫ豸ͼƬɣܺʱ 1.506 룬: False +2025-08-14 11:21:17,908 - hik3d - INFO - Saved point cloud to .\image\2025-08-14\pcd\112115786_00DA6823953.pcd +2025-08-14 11:21:18,291 - hik3d - INFO - Saved point cloud to .\image\2025-08-14\pcd\112115958_00DA6823936.pcd +2025-08-14 11:21:24,472 - hik3d - INFO - Saved point cloud to .\image\2025-08-14\pcd\112115965_00DA6823936_original.pcd +2025-08-14 11:21:24,647 - hik3d - INFO - Saved point cloud to .\image\2025-08-14\pcd\112115786_00DA6823953_original.pcd +2025-08-14 11:25:19,160 - hik3d - INFO - Found device [0]: Serial Number: 00DA6823936 +2025-08-14 11:25:20,425 - hik3d - INFO - Successfully added device 00DA6823936 to SN_MAP +2025-08-14 11:25:20,425 - hik3d - INFO - Found device [1]: Serial Number: 00DA6823953 +2025-08-14 11:25:21,666 - hik3d - INFO - Successfully added device 00DA6823953 to SN_MAP +2025-08-14 11:25:22,165 - hik3d - INFO - ... +2025-08-14 11:25:22,165 - hik3d - INFO - ɹַ: http://0.0.0.0:5000 +2025-08-14 11:25:43,026 - hik3d - INFO - յȫ豸ͼƬ +2025-08-14 11:25:43,028 - hik3d - INFO - ʼ豸 00DA6823936 ͼƬ +2025-08-14 11:25:43,028 - hik3d - INFO - Delaying start by 0ms... +2025-08-14 11:25:43,029 - hik3d - INFO - ʼ豸 00DA6823953 ͼƬ +2025-08-14 11:25:43,029 - hik3d - INFO - Delaying start by 0ms... +2025-08-14 11:25:43,265 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-14 11:25:43,531 - hik3d - INFO - _MapDepthToPointCloud() Run Succeed: framenum (1) height(720) width(1280) len (11059200)! +2025-08-14 11:25:44,154 - hik3d - INFO - Single capture completed. +2025-08-14 11:25:44,277 - hik3d - INFO - Single capture completed. +2025-08-14 11:25:44,474 - hik3d - INFO - 豸 00DA6823953 ɣʱ 1.445 룬ֿն: False +2025-08-14 11:25:44,991 - hik3d - INFO - 豸 00DA6823936 ɣʱ 1.963 룬ֿն: True +2025-08-14 11:25:44,995 - hik3d - INFO - 豸 00DA6823936 ֿնֹͣ +2025-08-14 11:25:45,035 - hik3d - INFO - ȫ豸ͼƬɣܺʱ 2.009 룬: True +2025-08-14 11:25:45,852 - hik3d - INFO - Saved point cloud to .\image\2025-08-14\pcd\112543933_00DA6823953.pcd +2025-08-14 11:25:47,209 - hik3d - INFO - Saved point cloud to .\image\2025-08-14\pcd\112544229_00DA6823936.pcd +2025-08-14 11:25:49,519 - hik3d - INFO - Saved point cloud to .\image\2025-08-14\pcd\112544234_00DA6823936_original.pcd +2025-08-14 11:25:49,681 - hik3d - INFO - Saved point cloud to .\image\2025-08-14\pcd\112544008_00DA6823953_original.pcd diff --git a/main.py b/main.py index 1af8476..a57375b 100644 --- a/main.py +++ b/main.py @@ -1,52 +1,316 @@ # 这是一个示例 Python 脚本。 - +import json +import os # 按 Shift+F10 执行或将其替换为您的代码。 # 按 双击 Shift 在所有地方搜索类、文件、工具窗口、操作和设置。 import SimpleView_SaveImage as simple import config -from Point import tiff_depth_to_point_clouds +import image +import time # 在文件顶部导入 time 模块 from flask import Flask, jsonify, request +from logConfig import get_logger + app = Flask(__name__) +import concurrent.futures +from functools import partial +# 使用示例 +logger = get_logger() # 示例接口:GET 请求 @app.route("/config/update") def home(): + logger.info("配置更新请求") config.load_configs() - return "Hello, this service config update!" - -# 示例接口:返回 JSON 数据 -@app.route("/api/data") -def get_data(): - data = {"message": "This is some data", "status": "OK"} - return jsonify(data) - -# 示例接口:接收参数 -# 示例接口:接收参数 -@app.route("/api/compute/") -def compute(direction): - try: - sn = config.DIRECTION_CAMERA[direction] - except KeyError: - return jsonify({"message": "", "status": "ERROR", "error": f"Direction '{direction}' not found in DIRECTION_CAMERA"}), 400 + logger.info("配置更新完成") + return {"message": "Hello, this service config update!", "status": "OK"} + + +@app.route("/api/addTemplate", methods=["POST"]) +def save_template(): + logger.info("接收到添加模板请求") + data = request.get_json() + + # 验证必要字段 + if not data: + logger.error("添加模板失败:未提供数据") + return jsonify({"status": "ERROR", "message": "No data provided"}), 400 + template_type = data.get("type") + if not template_type: + logger.error("添加模板失败:缺少'type'字段") + return jsonify({"status": "ERROR", "message": "Missing 'type' field"}), 400 + CONFIG_DIR = "./config/template" + # 构造文件路径 + filename = f"{template_type}.json" + file_path = os.path.join(CONFIG_DIR, filename) + + # 写入文件 try: - tiff_paths = simple.pic(sn) + with open(file_path, "w", encoding="utf-8") as f: + json.dump(data, f, ensure_ascii=False, indent=4) + config.load_configs() + logger.info(f"模板 '{template_type}' 保存成功") + return jsonify({"status": "OK", "message": f"Template '{template_type}' saved successfully."}), 200 except Exception as e: - return jsonify({"message": "", "status": "ERROR", "error": f"Failed to get TIFF paths: {str(e)}"}), 500 + logger.error(f"保存模板失败: {str(e)}") + return jsonify({"status": "ERROR", "message": f"Failed to save template: {str(e)}"}), 500 + + +@app.route("/api/initDevice", methods=['POST']) +def initDevice(): + logger.info("设备初始化请求") + simple.initialize_devices() + logger.info("设备初始化完成") + +# +# @app.route("/api/picComputeAll", methods=['POST']) +# def picComputeAll(): +# logger.info("接收到全设备图片计算请求") +# start_time_total = time.time() +# +# # 输入参数 +# # sn:设备编号 +# # type:类型 +# +# # 获取 JSON 数据 +# data = request.get_json() +# type = data['type'] +# template = config.TEMPLATE_CONFIG_MAP.get(type) +# if not template: +# logger.error("缺少模板配置: 'type'") +# return jsonify({ +# "message": "", +# "status": "ERROR", +# "error": "Missing required parameter: 'type'" +# }), 400 +# all_sn_list = list(config.CAMERA_CONFIG_MAP.keys()) +# +# # 遍历每个 sn 并判断是否都有 hole +# all_have_holes = False +# color_list = [] # 新增:用于保存所有 sn 的 color +# +# count_assemble = 0 +# for sn in all_sn_list: +# start_time = time.time() # 开始计时 +# logger.info(f"开始处理设备 {sn} 的图片计算") +# pic_info = simple.enhanced_pic(sn, type) +# points = pic_info.get("point") +# if points is None: +# logger.warning(f"设备 {sn} 未返回点云数据") +# all_have_holes = True +# break +# +# # 提取 color 并加入列表 +# color = pic_info.get("color") +# if color is not None: +# color_list.append(color) +# +# try: +# real_holes, count = image.detect_large_holes(points, sn, type) +# # count_assemble += count +# +# if len(real_holes) != 0: +# all_have_holes = True +# # 计算耗时 +# elapsed_time = round(time.time() - start_time, 3) +# # 输出日志 +# logger.info(f"[INFO] picComputeAll executed in {elapsed_time} seconds {sn}") +# break # 判断到空洞就直接退出 +# except Exception as e: +# all_have_holes = True +# logger.error(f"Failed to process request: {str(e)} sn:{sn}") +# +# # 计算总耗时 +# total_elapsed_time = round(time.time() - start_time_total, 3) +# logger.info(f"全设备图片计算完成,总耗时 {total_elapsed_time} 秒,结果: {all_have_holes}") +# +# # 返回结果中包含 color 列表 +# return jsonify({ +# "message": all_have_holes, +# "lack": all_have_holes, +# "type": type, +# "count": count_assemble, +# "colors": color_list, # 添加 color 列表 +# "status": "OK" +# }) +# +@app.route("/api/picComputeAll", methods=['POST']) +def picComputeAll(): + logger.info("接收到全设备图片计算请求") + start_time_total = time.time() + + # 获取 JSON 数据 + data = request.get_json() + type = data['type'] + template = config.TEMPLATE_CONFIG_MAP.get(type) + if not template: + logger.error("缺少模板配置: 'type'") + return jsonify({ + "message": "", + "status": "ERROR", + "error": "Missing required parameter: 'type'" + }), 400 + all_sn_list = list(config.CAMERA_CONFIG_MAP.keys()) + + # 同步处理每个设备 + all_have_holes = False + color_list = [] + count_assemble = 0 + + # 逐个同步处理设备 + for sn in all_sn_list: + try: + start_time = time.time() + logger.info(f"开始处理设备 {sn} 的图片计算") + + # 同步采集图片信息 + pic_info = simple.enhanced_pic(sn, type) + points = pic_info.get("point") + + if points is None: + logger.warning(f"设备 {sn} 未返回点云数据") + all_have_holes = True + break + + # 提取 color 并加入列表 + if pic_info.get("color") is not None: + color_list.append(pic_info["color"]) + + # 检测空洞 + real_holes, count = image.detect_large_holes(points, sn, type) + + elapsed_time = round(time.time() - start_time, 3) + logger.info(f"设备 {sn} 处理完成,耗时 {elapsed_time} 秒,发现空洞: {len(real_holes) != 0}") + + # 检查是否发现空洞 + if len(real_holes) != 0: + all_have_holes = True + count_assemble += count + logger.info(f"设备 {sn} 发现空洞,停止其他任务") + break # 发现空洞就直接退出 + + except Exception as e: + logger.error(f"处理设备 {sn} 时发生异常: {str(e)}") + all_have_holes = True + break + + # 计算总耗时 + total_elapsed_time = round(time.time() - start_time_total, 3) + logger.info(f"全设备图片计算完成,总耗时 {total_elapsed_time} 秒,结果: {all_have_holes}") + + # 返回结果中包含 color 列表 + return jsonify({ + "message": all_have_holes, + "lack": all_have_holes, + "type": type, + "count": count_assemble, + "colors": color_list, + "status": "OK" + }) + + + +@app.route("/api/picBitCloudy", methods=['POST']) +def picBitCloudy(): + logger.info("接收到picBitCloudy请求") + + # 输入参数 + # sn:设备编号 + # type:类型 + + # 获取 JSON 数据 + data = request.get_json() + direction = data.get('direction') + type = data.get('type') + all_sn_list = list(config.CAMERA_CONFIG_MAP.keys()) + + # 遍历每个 sn 并判断是否都有 hole + all_have_holes = False + color_list = [] # 新增:用于保存所有 sn 的 color + + count_assemble = 0 + for sn in all_sn_list: + if direction and config.CAMERA_CONFIG_MAP[sn].get("direction") != direction: + logger.debug(f"设备 {sn} 方向不匹配,跳过") + continue + + start_time = time.time() # 开始计时 + logger.info(f"开始处理设备 {sn} 的图片计算") + pic_info = simple.enhanced_pic(sn, type) + points = pic_info.get("point") + if points is None or len(points) < 300: + logger.warning(f"设备 {sn} 点云数据不足") + all_have_holes = True + break + + # 提取 color 并加入列表 + color = pic_info.get("color") + if color is not None: + color_list.append(color) + + logger.info(f"picBitCloudy处理完成,结果: {all_have_holes}") + # 返回结果中包含 color 列表 + return jsonify({ + "message": all_have_holes, + "lack": all_have_holes, + "colors": color_list, # 添加 color 列表 + "status": "OK" + }) + +@app.route("/api/picCompute", methods=['POST']) +def picCompute(): + logger.info("接收到单设备图片计算请求") + + # 输入参数 + # sn:设备编号 + # type:类型 try: - rest = tiff_depth_to_point_clouds(tiff_paths, sn, dedup=True) + # 获取 JSON 数据 + data = request.get_json() + if not data or 'sn' not in data: + logger.error("缺少必需参数: 'sn'") + return jsonify({ + "message": "", + "status": "ERROR", + "error": "Missing required parameter: 'sn'" + }), 400 + + sn = data['sn'] + type = data['type'] + logger.info(f"开始处理设备 {sn} 类型 {type} 的图片计算") + + template = config.TEMPLATE_CONFIG_MAP.get(type) + if not template: + logger.error(f"缺少模板配置: {type}") + return jsonify({ + "message": "", + "status": "ERROR", + "error": "Missing required parameter: 'type'" + }), 400 + + pic_info = simple.enhanced_pic(sn, type) + real_holes, count = image.detect_large_holes(pic_info["point"], sn, type) + + result = len(real_holes) != 0 + logger.info(f"设备 {sn} 图片计算完成,检测到空洞: {result}") + + return jsonify({"message": result, + "lack": result, "status": "OK"}) + except Exception as e: - return jsonify({"message": "", "status": "ERROR", "error": f"Point cloud processing failed: {str(e)}"}), 500 + logger.error(f"图片计算失败: {str(e)}") + return jsonify({"message": "", "status": "ERROR", "error": f"Failed to get TIFF paths: {str(e)}"}), 500 + + return jsonify({"message": True, "lack": True, "status": "OK"}) - print(rest) - return jsonify({"message": rest, "status": "OK"}) @app.errorhandler(Exception) def handle_exception(e): # 处理所有未被捕获的异常 + logger.error(f"未捕获的异常: {str(e)}") return jsonify({ "message": "", "status": "ERROR", @@ -57,6 +321,7 @@ def handle_exception(e): if __name__ == "__main__": from waitress import serve + logger.info("服务启动中...") print("Serving on http://0.0.0.0:5000") + logger.info("服务启动成功,监听地址: http://0.0.0.0:5000") serve(app, host='0.0.0.0', port=5000) - diff --git a/thread_pool.py b/thread_pool.py new file mode 100644 index 0000000..0ed0e4e --- /dev/null +++ b/thread_pool.py @@ -0,0 +1,74 @@ +# thread_pool.py +import concurrent.futures +import threading +from typing import Callable, Any + + +class ThreadPoolManager: + _instance = None + _lock = threading.Lock() + + def __new__(cls): + if cls._instance is None: + with cls._lock: + if cls._instance is None: + cls._instance = super(ThreadPoolManager, cls).__new__(cls) + cls._instance._initialized = False + return cls._instance + + def __init__(self): + if not self._initialized: + # 创建线程池,最大4个线程 + self.executor = concurrent.futures.ThreadPoolExecutor(max_workers=4) + self._initialized = True + + def submit(self, fn: Callable, *args, **kwargs) -> concurrent.futures.Future: + """ + 提交任务到线程池执行 + + :param fn: 要执行的函数 + :param args: 函数的位置参数 + :param kwargs: 函数的关键字参数 + :return: Future对象 + """ + if kwargs: + # 如果有关键字参数,需要包装函数 + def wrapper(): + return fn(*args, **kwargs) + + return self.executor.submit(wrapper) + else: + return self.executor.submit(fn, *args) + + def shutdown(self, wait=True): + """ + 关闭线程池 + + :param wait: 是否等待所有任务完成 + """ + self.executor.shutdown(wait=wait) + + +# 创建全局线程池管理器实例 +_thread_pool_manager = ThreadPoolManager() + + +def get_thread_pool() -> ThreadPoolManager: + """ + 获取线程池管理器实例 + + :return: ThreadPoolManager实例 + """ + return _thread_pool_manager + + +def submit_task(fn: Callable, *args, **kwargs) -> concurrent.futures.Future: + """ + 提交任务到线程池执行的便捷函数 + + :param fn: 要执行的函数 + :param args: 函数的位置参数 + :param kwargs: 函数的关键字参数 + :return: Future对象 + """ + return _thread_pool_manager.submit(fn, *args, **kwargs)