370 lines
17 KiB
Python
370 lines
17 KiB
Python
# -- coding: utf-8 --
|
||
from ctypes import *
|
||
import numpy as np
|
||
from numpy.ctypeslib import as_array
|
||
import cv2
|
||
from clog import logger
|
||
|
||
TO_CLIENT_NOTIFY_BASE = 1000
|
||
|
||
|
||
def process(msg):
|
||
record = msg.record
|
||
if msg.msg_type == 0 and record.code == (6 + TO_CLIENT_NOTIFY_BASE):
|
||
return doLocationProcessing(msg)
|
||
elif msg.msg_type == 1 and (
|
||
record.code == (2 + TO_CLIENT_NOTIFY_BASE) or record.code == (8 + TO_CLIENT_NOTIFY_BASE) or record.code == (
|
||
12 + TO_CLIENT_NOTIFY_BASE)):
|
||
return doDetectionProcessing(msg)
|
||
else:
|
||
pass
|
||
return msg
|
||
|
||
|
||
def _darw_rect(im):
|
||
cv2.rectangle(im, (130, 135), (430, 375), (0, 255, 0), 5)
|
||
|
||
|
||
# 处理图像
|
||
def doLocationProcessing(msg):
|
||
if msg is None:
|
||
return msg
|
||
im = msg.im2D
|
||
record = msg.record
|
||
ptsRoiPoints = None
|
||
ptsInnerConners = None
|
||
ptsInnerConners3D = None
|
||
if record.roi_size > 16:
|
||
return msg
|
||
for i in range(record.roi_size):
|
||
roi = record.subRois[i]
|
||
# if not roi.isGood: continue
|
||
roiPoints = roi.mRoiPoints
|
||
innerConners = roi.mInnerConners
|
||
innerConners3D = roi.mInnerConners3D
|
||
ptsRoiPoints = np.array([
|
||
[roiPoints[0], roiPoints[1]],
|
||
[roiPoints[2], roiPoints[3]],
|
||
[roiPoints[4], roiPoints[5]],
|
||
[roiPoints[6], roiPoints[7]]], dtype=np.int32)
|
||
|
||
# ptsInnerConners = np.array([
|
||
# [innerConners[0],innerConners[1]],
|
||
# [innerConners[2],innerConners[3]],
|
||
# [innerConners[4],innerConners[5]],s
|
||
# [innerConners[6],innerConners[7]]], dtype=np.int32)
|
||
|
||
# ptsInnerConners3D = np.array([
|
||
# [innerConners3D[0],innerConners3D[1],innerConners3D[2]],
|
||
# [innerConners3D[3],innerConners3D[4],innerConners3D[5]],
|
||
# [innerConners3D[6],innerConners3D[7],innerConners3D[8]],
|
||
# [innerConners3D[9],innerConners3D[10],innerConners3D[11]]])
|
||
|
||
cv2.polylines(im, [ptsRoiPoints], True, (255, 0, 0), 2)
|
||
# cv2.polylines(im, [ptsInnerConners], True, (255,0,0) , 2)
|
||
_darw_rect(im)
|
||
|
||
return msg
|
||
|
||
|
||
def doDetectionProcessing(msg):
|
||
if msg is None:
|
||
return msg
|
||
if msg.im2D is not None:
|
||
im = cv2.resize(msg.im2D, (int(msg.im2D.shape[1] / 16), int(msg.im2D.shape[0] / 16)))
|
||
record = msg.record
|
||
ptsRoiPoints = None
|
||
ptsInnerConners = None
|
||
ptsInnerConners3D = None
|
||
ptsRoiPointslist = []
|
||
ptsInnerConnerslist = []
|
||
ptsInnerConners3Dlist = []
|
||
if record.roi_size > 16:
|
||
return msg
|
||
for i in range(record.roi_size):
|
||
roi = record.subRois[i]
|
||
if not roi.isGood: continue
|
||
roiPoints = roi.mRoiPoints
|
||
innerConners = roi.mInnerConners
|
||
innerConners3D = roi.mInnerConners3D
|
||
ptsRoiPoints = np.array([
|
||
[roiPoints[0], roiPoints[1]],
|
||
[roiPoints[2], roiPoints[3]],
|
||
[roiPoints[4], roiPoints[5]],
|
||
[roiPoints[6], roiPoints[7]]], dtype=np.int32)
|
||
|
||
ptsInnerConners = np.array([
|
||
[innerConners[0], innerConners[1]],
|
||
[innerConners[2], innerConners[3]],
|
||
[innerConners[4], innerConners[5]],
|
||
[innerConners[6], innerConners[7]]], dtype=np.int32)
|
||
|
||
ptsInnerConners3D = np.array([
|
||
[innerConners3D[0], innerConners3D[1], innerConners3D[2]],
|
||
[innerConners3D[3], innerConners3D[4], innerConners3D[5]],
|
||
[innerConners3D[6], innerConners3D[7], innerConners3D[8]],
|
||
[innerConners3D[9], innerConners3D[10], innerConners3D[11]]])
|
||
print(ptsInnerConners3D)
|
||
|
||
for i in range(4):
|
||
ptsRoiPoints[i][0] = int(ptsRoiPoints[i][0] / 16)
|
||
ptsRoiPoints[i][1] = int(ptsRoiPoints[i][1] / 16)
|
||
ptsInnerConners[i][0] = int(ptsInnerConners[i][0] / 16)
|
||
ptsInnerConners[i][1] = int(ptsInnerConners[i][1] / 16)
|
||
ptsRoiPointslist.append(ptsRoiPoints)
|
||
ptsInnerConnerslist.append(ptsInnerConners)
|
||
ptsInnerConners3Dlist.append(ptsInnerConners3D)
|
||
|
||
cv2.polylines(im, ptsRoiPointslist, True, (0, 255, 0), 1)
|
||
cv2.polylines(im, ptsInnerConnerslist, True, (0, 255, 255), 1)
|
||
cv2.imwrite("result.png", im)
|
||
print("================== cv2.imwrite success =================")
|
||
|
||
if record.code == 12 + TO_CLIENT_NOTIFY_BASE:
|
||
bim_result = []
|
||
for i in range(record.roi_size):
|
||
roi2 = record.subRois[i]
|
||
if not roi2.isGood: continue
|
||
|
||
mInfo = roi2.mInfo.decode('utf-8')
|
||
mInnerConners3D = list(roi2.mInnerConners3D)
|
||
mInnerLineCenter = list(roi2.mInnerLineCenter)
|
||
mInnerLineCenter3D = list(roi2.mInnerLineCenter3D)
|
||
mInnerCenter = list(roi2.mInnerCenter)
|
||
mInnerCenter3D = list(roi2.mInnerCenter3D)
|
||
mEdgesLen = list(roi2.mEdgesLen)
|
||
print(f"mEdgesLen={mEdgesLen}")
|
||
print(f"ℹ️ℹ️mInfo={mInfo}")
|
||
# 单位换算
|
||
for i in range(3):
|
||
mInnerCenter3D[i] = mInnerCenter3D[i] * 1000
|
||
mInnerCenter3D[i] = round(mInnerCenter3D[i], 2)
|
||
for i in range(12):
|
||
# 米 单位 换算成毫米。# 留下小数
|
||
mInnerConners3D[i] = mInnerConners3D[i] * 1000
|
||
mInnerConners3D[i] = round(mInnerConners3D[i], 2)
|
||
mInnerLineCenter3D[i] = mInnerLineCenter3D[i] * 1000
|
||
mInnerLineCenter3D[i] = round(mInnerLineCenter3D[i], 2)
|
||
# mEdgesLen换算
|
||
for i in range(4):
|
||
# 米 单位 换算成毫米
|
||
mEdgesLen[i] = mEdgesLen[i] * 1000
|
||
# 留下小数
|
||
mEdgesLen[i] = round(mEdgesLen[i], 2)
|
||
|
||
# 从bim数据数组中获取code等于mInfo的元素
|
||
# this_bim_data = None
|
||
# for bim_data_item in bim_data:
|
||
# if str(bim_data_item["code"]) == mInfo:
|
||
# this_bim_data = bim_data_item
|
||
# break
|
||
|
||
# if this_bim_data is None:
|
||
# print(f"🟡返回的值为mInfo={mInfo},无法在bim数据中找到code相同的")
|
||
# continue
|
||
# else:
|
||
# print(f"🟢{mInfo}预埋件匹配成功")
|
||
|
||
# 临时测试
|
||
bim_data = [
|
||
{'code': 'BFX1101VBPT003', 'type': '300x248', 'x': '778', 'y': '250', 'center': '0.317', 'w': '300',
|
||
'h': '248', 'angle': '0°', 'm_x': '0', 'm_y': '0', 'm_z': '0', 'base': '3'}]
|
||
this_bim_data = bim_data[0]
|
||
print(f"🟢{mInfo}预埋件匹配成功")
|
||
|
||
# bim的长度 和 计算出来的长度进行计算,取优的值
|
||
bim_data_width = float(this_bim_data["w"])
|
||
bim_data_height = float(this_bim_data["h"])
|
||
print(f"bim_data_width:{bim_data_width}")
|
||
print(f"bim_data_height:{bim_data_height}")
|
||
# 上右下左
|
||
cal_up_width = mEdgesLen[0] # 上边宽度
|
||
cal_down_width = mEdgesLen[2] # 下边宽度
|
||
cal_left_height = mEdgesLen[3] # 左边高度
|
||
cal_right_height = mEdgesLen[1] # 右边宽度
|
||
print("mEdgesLen:==", mEdgesLen)
|
||
# 取差值最小width 和 height的值
|
||
if abs(cal_up_width - bim_data_width) < abs(cal_down_width - bim_data_width):
|
||
best_cal_width = cal_up_width
|
||
else:
|
||
best_cal_width = cal_down_width
|
||
|
||
if abs(cal_left_height - bim_data_height) < abs(cal_right_height - bim_data_height):
|
||
best_cal_height = cal_left_height
|
||
else:
|
||
best_cal_height = cal_right_height
|
||
|
||
print("best_cal_width:==", best_cal_width)
|
||
print("best_cal_height:==", best_cal_height)
|
||
# 画到图上
|
||
cv2.putText(im, "w:" + str(best_cal_width), \
|
||
(int((ptsInnerConners[0][0] + ptsInnerConners[(0 + 1) % 4][0]) / 2), \
|
||
int((ptsInnerConners[0][1] + ptsInnerConners[(0 + 1) % 4][1]) / 2 + 0 * 20)), \
|
||
cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, (255, 0, 0), 2)
|
||
|
||
cv2.putText(im, "h:" + str(best_cal_height), \
|
||
(int((ptsInnerConners[0][0] + ptsInnerConners[(0 + 1) % 4][0]) / 2), \
|
||
int((ptsInnerConners[0][1] + ptsInnerConners[(0 + 1) % 4][1]) / 2 + 1 * 20)), \
|
||
cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, (255, 0, 0), 2)
|
||
|
||
# 预埋件基础数据
|
||
dict = this_bim_data
|
||
# 四个点的3d坐标
|
||
dict["x1"] = mInnerConners3D[0]
|
||
dict["y1"] = mInnerConners3D[1]
|
||
dict["z1"] = mInnerConners3D[2]
|
||
dict["x2"] = mInnerConners3D[3]
|
||
dict["y2"] = mInnerConners3D[4]
|
||
dict["z2"] = mInnerConners3D[5]
|
||
dict["x3"] = mInnerConners3D[6]
|
||
dict["y3"] = mInnerConners3D[7]
|
||
dict["z3"] = mInnerConners3D[8]
|
||
dict["x4"] = mInnerConners3D[9]
|
||
dict["y4"] = mInnerConners3D[10]
|
||
dict["z4"] = mInnerConners3D[11]
|
||
# 四条边中各自中点的3d坐标
|
||
dict["top_line_center_x"] = mInnerLineCenter3D[0]
|
||
dict["top_line_center_y"] = mInnerLineCenter3D[1]
|
||
dict["top_line_center_z"] = mInnerLineCenter3D[2]
|
||
dict["right_line_center_x"] = mInnerLineCenter3D[3]
|
||
dict["right_line_center_y"] = mInnerLineCenter3D[4]
|
||
dict["right_line_center_z"] = mInnerLineCenter3D[5]
|
||
dict["bottom_line_center_x"] = mInnerLineCenter3D[6]
|
||
dict["bottom_line_center_y"] = mInnerLineCenter3D[7]
|
||
dict["bottom_line_center_z"] = mInnerLineCenter3D[8]
|
||
dict["left_line_center_x"] = mInnerLineCenter3D[9]
|
||
dict["left_line_center_y"] = mInnerLineCenter3D[10]
|
||
dict["left_line_center_z"] = mInnerLineCenter3D[11]
|
||
# 计算出的宽度和高度
|
||
dict["best_cal_width"] = best_cal_width
|
||
dict["best_cal_height"] = best_cal_height
|
||
# 中心点3d坐标
|
||
dict["x_center"] = mInnerCenter3D[0]
|
||
dict["y_center"] = mInnerCenter3D[1]
|
||
dict["z_center"] = mInnerCenter3D[2]
|
||
|
||
|
||
dict["actual_value"] = ""
|
||
dict["status"] = "good"
|
||
dict["base"] = "5"
|
||
# dict["x_center"] = mInnerConners3D[0]
|
||
# dict["y_center"] = mInnerConners3D[1]
|
||
# dict["z_center"] = mInnerConners3D[2]
|
||
bim_result.append(dict)
|
||
print(f"bim_result🟠={bim_result}")
|
||
# for j in range(record.roi_size):
|
||
# roi = record.subRois[j]
|
||
# if not roi.isGood: continue
|
||
# ptsInnerConners = ptsInnerConnerslist[j]
|
||
# ptsInnerConners3D = ptsInnerConners3Dlist[j]
|
||
# if len(ptsInnerConners) == 4:
|
||
# for i in range(4):
|
||
# p3d = ptsInnerConners3D[i]
|
||
# p3d_next = ptsInnerConners3D[(i + 1) % 4]
|
||
# p2d = ptsInnerConners[i]
|
||
# p2d_next = ptsInnerConners[(i + 1) % 4]
|
||
# edge = np.sqrt(pow((p3d[0] - p3d_next[0]), 2)
|
||
# + pow((p3d[1] - p3d_next[1]), 2)
|
||
# + pow((p3d[2] - p3d_next[2]), 2))
|
||
# cv2.putText(im, str(edge)[:6], \
|
||
# (int((ptsInnerConners[0][0] + ptsInnerConners[(0 + 1) % 4][0]) / 2), \
|
||
# int((ptsInnerConners[0][1] + ptsInnerConners[(0 + 1) % 4][1]) / 2 + i * 20)), \
|
||
# cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, (255, 0, 0), 2)
|
||
print("================== draw =================")
|
||
msg.im2D = im
|
||
# cv2.imshow("HQImage", im)
|
||
# cv2.waitKey(1)
|
||
return msg
|
||
|
||
|
||
# detect结果处理
|
||
def detectionResProcessing(msg,data_img_path,data_detect_res_save_path):
|
||
# im = cv2.resize(msg.im2D, (int(msg.im2D.shape[1] / 16), int(msg.im2D.shape[0] / 16)))
|
||
# Read the image from the local directory
|
||
im = cv2.imread(data_img_path)
|
||
|
||
# Resize the image
|
||
im = cv2.resize(im, (int(im.shape[1] / 16), int(im.shape[0] / 16)))
|
||
record = msg.record
|
||
ptsRoiPoints = None
|
||
ptsInnerConners = None
|
||
ptsInnerConners3D = None
|
||
ptsRoiPointslist = []
|
||
ptsInnerConnerslist = []
|
||
ptsInnerConners3Dlist = []
|
||
logger.debug(f"record.roi_size:{record.roi_size}")
|
||
if record.roi_size > 16:
|
||
logger.warn(f"roi_size大于:{record.roi_size}个,请检查!")
|
||
for i in range(record.roi_size):
|
||
roi = record.subRois[i]
|
||
logger.debug(f"roi=====:{roi.isGood}")
|
||
# if not roi.isGood: continue
|
||
roiPoints = roi.mRoiPoints
|
||
innerConners = roi.mInnerConners
|
||
innerConners3D = roi.mInnerConners3D
|
||
ptsRoiPoints = np.array([
|
||
[roiPoints[0], roiPoints[1]],
|
||
[roiPoints[2], roiPoints[3]],
|
||
[roiPoints[4], roiPoints[5]],
|
||
[roiPoints[6], roiPoints[7]]], dtype=np.int32)
|
||
|
||
ptsInnerConners = np.array([
|
||
[innerConners[0], innerConners[1]],
|
||
[innerConners[2], innerConners[3]],
|
||
[innerConners[4], innerConners[5]],
|
||
[innerConners[6], innerConners[7]]], dtype=np.int32)
|
||
|
||
ptsInnerConners3D = np.array([
|
||
[innerConners3D[0], innerConners3D[1], innerConners3D[2]],
|
||
[innerConners3D[3], innerConners3D[4], innerConners3D[5]],
|
||
[innerConners3D[6], innerConners3D[7], innerConners3D[8]],
|
||
[innerConners3D[9], innerConners3D[10], innerConners3D[11]]])
|
||
print(ptsInnerConners3D)
|
||
|
||
for i in range(4):
|
||
ptsRoiPoints[i][0] = int(ptsRoiPoints[i][0] / 16)
|
||
ptsRoiPoints[i][1] = int(ptsRoiPoints[i][1] / 16)
|
||
ptsInnerConners[i][0] = int(ptsInnerConners[i][0] / 16)
|
||
ptsInnerConners[i][1] = int(ptsInnerConners[i][1] / 16)
|
||
ptsRoiPointslist.append(ptsRoiPoints)
|
||
ptsInnerConnerslist.append(ptsInnerConners)
|
||
ptsInnerConners3Dlist.append(ptsInnerConners3D)
|
||
# 打印三个list
|
||
# for i in range(len(ptsRoiPointslist)):
|
||
# logger.debug("ptsRoiPointslist:", ptsRoiPointslist[i])
|
||
# logger.debug(("ptsInnerConnerslist:", ptsInnerConnerslist[i]))
|
||
# logger.debug(("ptsInnerConners3Dlist:", ptsInnerConners3Dlist[i]))
|
||
|
||
cv2.polylines(im, ptsRoiPointslist, True, (0, 255, 0), 1)
|
||
cv2.polylines(im, ptsInnerConnerslist, True, (0, 255, 255), 1)
|
||
cv2.imwrite(f"{data_detect_res_save_path}/result.jpg", im)
|
||
logger.success("================== cv2.imwrite result.jpg success =================")
|
||
|
||
if record.code == 12 + TO_CLIENT_NOTIFY_BASE:
|
||
for i in range(record.roi_size):
|
||
roi2 = record.subRois[i]
|
||
if not roi2.isGood: continue
|
||
mInfo = roi2.mInfo
|
||
print(f"mInfo====={mInfo}")
|
||
for j in range(record.roi_size):
|
||
roi = record.subRois[j]
|
||
# if not roi.isGood: continue
|
||
ptsInnerConners = ptsInnerConnerslist[j]
|
||
ptsInnerConners3D = ptsInnerConners3Dlist[j]
|
||
if len(ptsInnerConners) == 4:
|
||
for i in range(4):
|
||
p3d = ptsInnerConners3D[i]
|
||
p3d_next = ptsInnerConners3D[(i + 1) % 4]
|
||
p2d = ptsInnerConners[i]
|
||
p2d_next = ptsInnerConners[(i + 1) % 4]
|
||
edge = np.sqrt(pow((p3d[0] - p3d_next[0]), 2)
|
||
+ pow((p3d[1] - p3d_next[1]), 2)
|
||
+ pow((p3d[2] - p3d_next[2]), 2))
|
||
cv2.putText(im, str(edge)[:6], \
|
||
(int((ptsInnerConners[0][0] + ptsInnerConners[(0 + 1) % 4][0]) / 2), \
|
||
int((ptsInnerConners[0][1] + ptsInnerConners[(0 + 1) % 4][1]) / 2 + i * 20)), \
|
||
cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, (255, 0, 0), 2)
|
||
cv2.imwrite(f"{data_detect_res_save_path}/result2.jpg", im)
|
||
logger.success("================== cv2.imwrite result2.jpg success =================")
|
||
|