272 lines
9.2 KiB
Python
272 lines
9.2 KiB
Python
![]() |
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()
|