import os import shutil import sys import threading import time from ctypes import * import logging from logging import makeLogRecord from clog import logger import cv2 import numpy as np from imgProcess import detectionResProcessing from util import change_config_ini image_framework_sdk = None data_callback = None SYS_OK = 0 bStop = False # 全局 msg 缓存 g_msg_cache = [] # 全局 frame 缓存 g_frame_cache = [] # 运行模式 RUNNING_MODE_NONE = -1 # 停止状态 RUNNING_MODE_LOCATION = 0 # 广角相机运行模式 RUNNING_MODE_DETECTION = 1 # 高清检测运行模式 g_running_mode = RUNNING_MODE_NONE # 默认是广角相机运行模式 TO_CLIENT_NOTIFY_BASE = 1000 # emit的结构体 MSG_ONLY_RECORD = -1 MSG_LOCATION_RECORD = 0 MSG_DETECTION_RECORD = 1 # 获取消息 def _get_msg_info(code) -> str: global MSG_LIST for msg in MSG_LIST: for key, value in msg.items(): if code == key: return value.encode("utf-8") return "未知错误".encode("utf-8") class Msg: def __init__(self, msg_type, record, im2D): self.msg_type = msg_type # 0:刷新广角图片, 1:刷新高清, -1:不刷新图片,纯消息 self.record = record self.im2D = im2D class _SubRoiData_(Structure): _fields_ = [ ('mPparentId', c_long), ('mId', c_long), ('mInfo', c_char * 256), ('isGood', c_bool), ('vpOffset', c_float * 2), ('mRoiPoints', c_float * 8), # 4 * 2 ('mInnerConners', c_float * 8), # 4 * 2 ('mInnerConners3D', c_float * 12), # 4 * 3 ('edges', c_float * 4), ('center', c_float * 2), ('cloud_size', c_int), ('mVc2D', POINTER(c_float)), ('mVc3D', POINTER(c_float)), ('H', c_float * 9), ] SubRoiData = _SubRoiData_ class _CallbackInfo_(Structure): _fields_ = [ ('code', c_int), ('errorInfo', c_char * 256), ('bGetData', c_bool), ('mId', c_long), ('mInfo', c_char * 256), ('mImPath', c_char * 256), ('mIm2D3DPtr', c_char * 256), ('roi_size', c_int), ('subRois', SubRoiData * 16), ] CallbackInfo = _CallbackInfo_ # 回调函数类型定义 CallbackType = CFUNCTYPE(None, POINTER(CallbackInfo)) def _copy_record(record): new_record = CallbackInfo() new_record.code = record.code new_record.errorInfo = record.errorInfo new_record.bGetData = record.bGetData new_record.roi_size = record.roi_size for i in range(record.roi_size): if i > 15: # 超过16个ROI,返回 break subRois = record.subRois[i] newSubRois = new_record.subRois[i] for j in range(8): newSubRois.mRoiPoints[j] = subRois.mRoiPoints[j] newSubRois.mInnerConners[j] = subRois.mInnerConners[j] for j in range(12): newSubRois.mInnerConners3D[j] = subRois.mInnerConners3D[j] return new_record def init_callback(): global data_callback, bStop def _callback(data): print("_callback回调执行") global g_msg_cache, g_frame_cache, g_running_mode, bStop record = CallbackInfo(code=SYS_OK, errorInfo=b"", bGetData=False) frame = None ret = SYS_OK msg = None # 获取数据 data_type = CallbackInfo data_ptr = cast(data, POINTER(data_type)) ckinfoCache = data_ptr.contents record = _copy_record(ckinfoCache) print(str(g_running_mode) + " : " + str(record.code) + " : " + bytes.decode(record.errorInfo)) # 当定位模式下,接收到【定位完成】消息 if g_running_mode == RUNNING_MODE_LOCATION and record.code == (6 + TO_CLIENT_NOTIFY_BASE): if len(g_frame_cache) == 0: print("当前没有广角数据") return frame = g_frame_cache.pop() # 从图像缓存中去除图像 g_frame_cache = [] # 清空缓存,避免无限增长 msg = Msg(MSG_LOCATION_RECORD, _copy_record(record), frame) # 当检测模式下,接收到【拍照完成】消息 elif record.code == (8 + TO_CLIENT_NOTIFY_BASE): bStop = True time.sleep(1) elif record.code == (12 + TO_CLIENT_NOTIFY_BASE): msg = Msg(MSG_DETECTION_RECORD, _copy_record(record), None) detectionResProcessing(msg,data_img_path,data_detect_res_save_path) bStop = True time.sleep(1) # # frame = np.zeros((7000, 9344, 3), np.uint8) # # # frame.zeros(9344, 7000, cv2.CV_8UC3) # # # src_frame_ptr = c_char_p(frame.data.tobytes()) # # mv = memoryview(frame.data) # # buffer_pointer = cast(mv.obj.ctypes.data, c_void_p) # # ret = image_framework_sdk.LibapiGetHQImage( # # buffer_pointer, frame.shape[1], frame.shape[0], 3, c_char_p(b"PythonProcessing")) # if ret != SYS_OK: # print("ret != SYS_OK:" + str(ret)) # record = CallbackInfo(code=ret, errorInfo=_get_msg_info(ret), bGetData=False) # msg = Msg(MSG_DETECTION_RECORD, record, None) # g_msg_cache.append(msg) # # emit msg # return # msg = Msg(MSG_DETECTION_RECORD, _copy_record(record), frame) # elif g_running_mode == RUNNING_MODE_LOCATION: # msg = Msg(MSG_LOCATION_RECORD, _copy_record(record), None) # elif g_running_mode == RUNNING_MODE_DETECTION: # msg = Msg(MSG_DETECTION_RECORD, _copy_record(record), None) # else: # print("未知回调") # return data_callback = CallbackType(_callback) def init_image_framework_sdk(): global image_framework_sdk try: # 加载C++库 current_file_dir = os.path.dirname(os.path.abspath(__file__)) image_framework_sdk = CDLL(os.path.join(current_file_dir, f'./image_framework.dll')) print("Load Image framework sdk success") except Exception as e: print(f"Load Image framework sdk failed: {str(e)}") def adjust(): global image_framework_sdk record = CallbackInfo(code=SYS_OK, errorInfo=b"", bGetData=False) ret = image_framework_sdk.LibapiStartDetection() if ret != SYS_OK: print(f"image_framework_sdk.LibapiStartDetection():执行失败 :{ret}") return record def check(): print("check====================") global image_framework_sdk record = CallbackInfo(code=SYS_OK, errorInfo=b"", bGetData=False) ret = image_framework_sdk.LibapiContinuetDetection("{}") if ret != SYS_OK: print("image_framework_sdk.LibapiContinuetDetection:执行失败") return record def start(): global bStop # 开始检测 logger.debug("开始adjust") adjust() while not bStop: logger.debug("adjust等待回调") time.sleep(1) logger.debug("开始check") check() bStop = False while not bStop: logger.debug("check等待回调") time.sleep(1) if __name__ == '__main__': # 加载驱动 init_image_framework_sdk() if image_framework_sdk is None: raise RuntimeError("Image framework SDK未正确加载!") # 设置回调函数 init_callback() ret = image_framework_sdk.LibapiInit(1, "", data_callback) if ret != 0: raise RuntimeError(f"设置回调函数始设置失败, 错误码: {ret}") dataPath = "./result/hy_1" # 数据路径 data_img_path = None # 检测的图片路径 data_detect_res_save_path = None # 检测结果的保存路径 # 遍历目录 for root, dirs, files in os.walk(dataPath): for dir in dirs: logger.debug(f"开始处理子目录:{dir}") data_detect_res_save_path = os.path.join(root, dir) # 目录下的所有文件路径 for file in os.listdir(os.path.join(root, dir)): file_path = os.path.join(root, dir, file) # 将反斜杠替换为正斜杠 file_path = file_path.replace('\\', '/') logger.debug(f"文件路径:{file_path}") # 如果是jpg图片 if file.endswith("output.jpg"): # 将文件路径修改到ini配置中 data_img_path = file_path change_config_ini("sys", "fake_image_fpath", file_path) if file.endswith(".ply"): # 将文件路径修改到ini配置中 change_config_ini("sys", "fake_lidar_fpath", file_path) if file.endswith(".txt"): # txt roi坐标复制到更目录,曹总懒得修改c代码,只能从根目录读取。 shutil.copy(file_path, os.path.join("./", file)) logger.info(f"roi坐标文件已复制到更目录") time.sleep(1) # ... # 开始检测 bStop = False logger.debug("开始检测") start() exit()