first commit
This commit is contained in:
commit
5ca747feed
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
result/
|
||||
.idea/
|
||||
.vscode/
|
BIN
1_roi_image.png
Normal file
BIN
1_roi_image.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 983 KiB |
BIN
2_roi_image.png
Normal file
BIN
2_roi_image.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 783 KiB |
BIN
Open3D.dll
Normal file
BIN
Open3D.dll
Normal file
Binary file not shown.
5
app.log
Normal file
5
app.log
Normal file
@ -0,0 +1,5 @@
|
||||
2025-02-20 17:05:14 - clog.py:53 - DEBUG:my_logger:This is a debug message
|
||||
2025-02-20 17:05:14 - clog.py:54 - INFO:my_logger:This is an info message
|
||||
2025-02-20 17:05:14 - clog.py:55 - WARNING:my_logger:This is a warning message
|
||||
2025-02-20 17:05:14 - clog.py:56 - ERROR:my_logger:This is an error message
|
||||
2025-02-20 17:05:14 - clog.py:57 - CRITICAL:my_logger:This is a critical message
|
272
bm_struct_array.json
Normal file
272
bm_struct_array.json
Normal file
@ -0,0 +1,272 @@
|
||||
[
|
||||
{
|
||||
"code": "1",
|
||||
"type": "250x1450",
|
||||
"x": "196.0",
|
||||
"y": 0,
|
||||
"center": "351",
|
||||
"w": "1450",
|
||||
"h": "250",
|
||||
"angle": "0\u00b0"
|
||||
},
|
||||
{
|
||||
"code": "2",
|
||||
"type": "300x300",
|
||||
"x": "174.0",
|
||||
"y": 0,
|
||||
"center": "754",
|
||||
"w": "300",
|
||||
"h": "300",
|
||||
"angle": "0\u00b0"
|
||||
},
|
||||
{
|
||||
"code": "3",
|
||||
"type": "501x500",
|
||||
"x": "889.5",
|
||||
"y": 0,
|
||||
"center": "1054.5",
|
||||
"w": "500",
|
||||
"h": "501",
|
||||
"angle": "0\u00b0"
|
||||
},
|
||||
{
|
||||
"code": "4",
|
||||
"type": "250x648",
|
||||
"x": "-32.0",
|
||||
"y": 0,
|
||||
"center": "1149",
|
||||
"w": "648",
|
||||
"h": "250",
|
||||
"angle": "0\u00b0"
|
||||
},
|
||||
{
|
||||
"code": "5",
|
||||
"type": "250x250",
|
||||
"x": "588.0",
|
||||
"y": 0,
|
||||
"center": "1543",
|
||||
"w": "250",
|
||||
"h": "250",
|
||||
"angle": "0\u00b0"
|
||||
},
|
||||
{
|
||||
"code": "6",
|
||||
"type": "249x249",
|
||||
"x": "1031.5",
|
||||
"y": 0,
|
||||
"center": "1750.5",
|
||||
"w": "249",
|
||||
"h": "249",
|
||||
"angle": "0\u00b0"
|
||||
},
|
||||
{
|
||||
"code": "7",
|
||||
"type": "400x399",
|
||||
"x": "-199.5",
|
||||
"y": 0,
|
||||
"center": "1955",
|
||||
"w": "399",
|
||||
"h": "400",
|
||||
"angle": "0\u00b0"
|
||||
},
|
||||
{
|
||||
"code": "8",
|
||||
"type": "300x302",
|
||||
"x": "394.0",
|
||||
"y": 0,
|
||||
"center": "2159",
|
||||
"w": "302",
|
||||
"h": "300",
|
||||
"angle": "0\u00b0"
|
||||
},
|
||||
{
|
||||
"code": "9",
|
||||
"type": "300x302",
|
||||
"x": "996.0",
|
||||
"y": 0,
|
||||
"center": "2157",
|
||||
"w": "302",
|
||||
"h": "300",
|
||||
"angle": "0\u00b0"
|
||||
},
|
||||
{
|
||||
"code": "10",
|
||||
"type": "248x1447",
|
||||
"x": "2190.0",
|
||||
"y": 0,
|
||||
"center": "345",
|
||||
"w": "1447",
|
||||
"h": "248",
|
||||
"angle": "0\u00b0"
|
||||
},
|
||||
{
|
||||
"code": "11",
|
||||
"type": "298x297",
|
||||
"x": "2198.5",
|
||||
"y": 0,
|
||||
"center": "747",
|
||||
"w": "297",
|
||||
"h": "298",
|
||||
"angle": "0\u00b0"
|
||||
},
|
||||
{
|
||||
"code": "12",
|
||||
"type": "499x499",
|
||||
"x": "2891.0",
|
||||
"y": 0,
|
||||
"center": "1040.5",
|
||||
"w": "499",
|
||||
"h": "499",
|
||||
"angle": "0\u00b0"
|
||||
},
|
||||
{
|
||||
"code": "13",
|
||||
"type": "245x648",
|
||||
"x": "1994.5",
|
||||
"y": 0,
|
||||
"center": "1146.5",
|
||||
"w": "648",
|
||||
"h": "245",
|
||||
"angle": "0\u00b0"
|
||||
},
|
||||
{
|
||||
"code": "14",
|
||||
"type": "247x247",
|
||||
"x": "2589.5",
|
||||
"y": 0,
|
||||
"center": "1550.5",
|
||||
"w": "247",
|
||||
"h": "247",
|
||||
"angle": "0\u00b0"
|
||||
},
|
||||
{
|
||||
"code": "15",
|
||||
"type": "246x247",
|
||||
"x": "2998.5",
|
||||
"y": 0,
|
||||
"center": "1757",
|
||||
"w": "247",
|
||||
"h": "246",
|
||||
"angle": "0\u00b0"
|
||||
},
|
||||
{
|
||||
"code": "16",
|
||||
"type": "398x392",
|
||||
"x": "1799.5",
|
||||
"y": 0,
|
||||
"center": "1955",
|
||||
"w": "392",
|
||||
"h": "398",
|
||||
"angle": "0\u00b0"
|
||||
},
|
||||
{
|
||||
"code": "17",
|
||||
"type": "300x293",
|
||||
"x": "2394.5",
|
||||
"y": 0,
|
||||
"center": "2147",
|
||||
"w": "293",
|
||||
"h": "300",
|
||||
"angle": "0\u00b0"
|
||||
},
|
||||
{
|
||||
"code": "18",
|
||||
"type": "298x297",
|
||||
"x": "3001.5",
|
||||
"y": 0,
|
||||
"center": "2144",
|
||||
"w": "297",
|
||||
"h": "298",
|
||||
"angle": "0\u00b0"
|
||||
},
|
||||
{
|
||||
"code": "19",
|
||||
"type": "245x1447",
|
||||
"x": "4191.5",
|
||||
"y": 0,
|
||||
"center": "344.5",
|
||||
"w": "1447",
|
||||
"h": "245",
|
||||
"angle": "0\u00b0"
|
||||
},
|
||||
{
|
||||
"code": "20",
|
||||
"type": "295x300",
|
||||
"x": "4175.0",
|
||||
"y": 0,
|
||||
"center": "743.5",
|
||||
"w": "300",
|
||||
"h": "295",
|
||||
"angle": "0\u00b0"
|
||||
},
|
||||
{
|
||||
"code": "21",
|
||||
"type": "498x495",
|
||||
"x": "4897.5",
|
||||
"y": 0,
|
||||
"center": "1030",
|
||||
"w": "495",
|
||||
"h": "498",
|
||||
"angle": "0\u00b0"
|
||||
},
|
||||
{
|
||||
"code": "22",
|
||||
"type": "245x648",
|
||||
"x": "3977.0",
|
||||
"y": 0,
|
||||
"center": "1150.5",
|
||||
"w": "648",
|
||||
"h": "245",
|
||||
"angle": "0\u00b0"
|
||||
},
|
||||
{
|
||||
"code": "23",
|
||||
"type": "245x246",
|
||||
"x": "4547.5",
|
||||
"y": 0,
|
||||
"center": "1541.5",
|
||||
"w": "246",
|
||||
"h": "245",
|
||||
"angle": "0\u00b0"
|
||||
},
|
||||
{
|
||||
"code": "24",
|
||||
"type": "245x245",
|
||||
"x": "4992.5",
|
||||
"y": 0,
|
||||
"center": "1735.5",
|
||||
"w": "245",
|
||||
"h": "245",
|
||||
"angle": "0\u00b0"
|
||||
},
|
||||
{
|
||||
"code": "25",
|
||||
"type": "398x392",
|
||||
"x": "3796.5",
|
||||
"y": 0,
|
||||
"center": "1955",
|
||||
"w": "392",
|
||||
"h": "398",
|
||||
"angle": "0\u00b0"
|
||||
},
|
||||
{
|
||||
"code": "26",
|
||||
"type": "298x296",
|
||||
"x": "4392.5",
|
||||
"y": 0,
|
||||
"center": "2142",
|
||||
"w": "296",
|
||||
"h": "298",
|
||||
"angle": "0\u00b0"
|
||||
},
|
||||
{
|
||||
"code": "27",
|
||||
"type": "297x295",
|
||||
"x": "4991.5",
|
||||
"y": 0,
|
||||
"center": "2146.5",
|
||||
"w": "295",
|
||||
"h": "297",
|
||||
"angle": "0\u00b0"
|
||||
}
|
||||
]
|
167
capture_img_ply.py
Normal file
167
capture_img_ply.py
Normal file
@ -0,0 +1,167 @@
|
||||
# -- coding: utf-8 --
|
||||
import time
|
||||
import os
|
||||
import paramiko
|
||||
from scp import SCPClient
|
||||
import threading
|
||||
from os import abort
|
||||
from pathlib import Path
|
||||
from clog import logger
|
||||
|
||||
HOST = "192.168.100.254"
|
||||
PORT = 22
|
||||
USERNAME = "root"
|
||||
PASSWORD = "ebaina"
|
||||
|
||||
CLOUD_COUNTS = [400000, 500000, 600000]
|
||||
DEFAULT_COUNT = 300000
|
||||
EXPS = [200 * 1000, 300 * 1000, 400 * 1000]
|
||||
DEFAULT_EXP = 100 * 1000
|
||||
PARENT_DIR_NAME = "test_2"
|
||||
SAVE_DIR_NAME = ""
|
||||
|
||||
|
||||
def ssh_execute_command(host, port, username, password, command):
|
||||
ret = False
|
||||
# 创建SSH客户端
|
||||
client = paramiko.SSHClient()
|
||||
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
client.connect(host, port, username, password)
|
||||
|
||||
# 执行命令
|
||||
stdin, stdout, stderr = client.exec_command(command)
|
||||
# 读取输出结果
|
||||
output = stdout.read().decode()
|
||||
error = stderr.read().decode()
|
||||
|
||||
if output:
|
||||
logger.info(f"{output}")
|
||||
if error:
|
||||
logger.error(f"{error}")
|
||||
|
||||
# 关闭连接
|
||||
client.close()
|
||||
return True
|
||||
|
||||
|
||||
def scp_get_file(host, port, username, password, remote_path, local_path):
|
||||
ret = False
|
||||
# 创建SSH客户端
|
||||
client = paramiko.Transport((host, port))
|
||||
client.connect(username=username, password=password)
|
||||
|
||||
# 创建SCP客户端
|
||||
scp_client = SCPClient(client)
|
||||
|
||||
# 拉取文件
|
||||
try:
|
||||
scp_client.get(remote_path, local_path)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return False
|
||||
|
||||
# 关闭连接
|
||||
scp_client.close()
|
||||
client.close()
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def cameraCap(exp):
|
||||
start_time = time.time()
|
||||
ret = ssh_execute_command(
|
||||
host=HOST,
|
||||
port=PORT,
|
||||
username=USERNAME,
|
||||
password=PASSWORD,
|
||||
command="cd /root/app/detect-gui/ \n" +
|
||||
f"/root/miniconda3/bin/python cap.py --exp={exp}\n"
|
||||
)
|
||||
if not ret:
|
||||
return False
|
||||
end_time = time.time() # 记录结束时间
|
||||
execution_time = end_time - start_time # 计算执行时间
|
||||
print(f"ssh_execute_command 程序执行时间:{execution_time}秒")
|
||||
time.sleep(1) # 等待操作系统保存图像完毕
|
||||
ret = scp_get_file(
|
||||
host=HOST,
|
||||
port=PORT,
|
||||
username=USERNAME,
|
||||
password=PASSWORD,
|
||||
remote_path="/root/app/detect-gui/output.jpg",
|
||||
local_path=Path(__file__).parent / "result" / PARENT_DIR_NAME / SAVE_DIR_NAME
|
||||
)
|
||||
if not ret:
|
||||
return False
|
||||
end_time = time.time() # 记录结束时间
|
||||
execution_time = end_time - start_time # 计算执行时间
|
||||
print(f"cameraCap 程序执行时间:{execution_time}秒")
|
||||
|
||||
|
||||
def lidarCap(cloud_count):
|
||||
start_time = time.time()
|
||||
print(f"./lidar_driver {cloud_count}\n")
|
||||
ret = ssh_execute_command(
|
||||
host=HOST,
|
||||
port=PORT,
|
||||
username=USERNAME,
|
||||
password=PASSWORD,
|
||||
command="cd /root/calibration_tools \n" +
|
||||
f"./lidar_driver {cloud_count}\n"
|
||||
)
|
||||
ret = scp_get_file(
|
||||
host=HOST,
|
||||
port=PORT,
|
||||
username=USERNAME,
|
||||
password=PASSWORD,
|
||||
remote_path="/root/calibration_tools/output.ply",
|
||||
local_path=Path(__file__).parent / "result" / PARENT_DIR_NAME / SAVE_DIR_NAME
|
||||
)
|
||||
ret = ssh_execute_command(
|
||||
host=HOST,
|
||||
port=PORT,
|
||||
username=USERNAME,
|
||||
password=PASSWORD,
|
||||
command="cd /root/calibration_tools \n " +
|
||||
"rm output.ply \n"
|
||||
)
|
||||
end_time = time.time() # 记录结束时间
|
||||
execution_time = end_time - start_time # 计算执行时间
|
||||
print(f"lidarCap 程序执行时间:{execution_time}秒")
|
||||
|
||||
|
||||
def cap(exp=DEFAULT_EXP, cloud_count=DEFAULT_COUNT):
|
||||
global SAVE_DIR_NAME
|
||||
print(f"曝光时间{exp}")
|
||||
print(f"点云数量:{cloud_count}")
|
||||
SAVE_DIR_NAME = f"exp_{exp}_cn_{cloud_count}"
|
||||
# 如果文件夹不存在则创建
|
||||
if not os.path.exists(Path(__file__).parent / "result" / PARENT_DIR_NAME / SAVE_DIR_NAME):
|
||||
os.makedirs(Path(__file__).parent / "result" / PARENT_DIR_NAME / SAVE_DIR_NAME)
|
||||
# 雷达线程
|
||||
t_lidar = threading.Thread(target=lidarCap, args=(cloud_count,))
|
||||
t_lidar.start()
|
||||
# 相机
|
||||
cameraCap(exp)
|
||||
|
||||
# 等待雷达线程结束
|
||||
t_lidar.join()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# 加载驱动
|
||||
ssh_execute_command(
|
||||
host=HOST,
|
||||
port=PORT,
|
||||
username=USERNAME,
|
||||
password=PASSWORD,
|
||||
command="/opt/HuarayTech/MVviewer/module/loadAllDrv.sh \n"
|
||||
)
|
||||
for cloud_count in CLOUD_COUNTS:
|
||||
logger.info("开始采集")
|
||||
cap(cloud_count = cloud_count)
|
||||
logger.info("采集完毕===========")
|
||||
for exp in EXPS:
|
||||
logger.info("开始采集")
|
||||
cap(exp = exp)
|
||||
logger.info("采集完毕===========")
|
258
capture_img_ply_txt.py
Normal file
258
capture_img_ply_txt.py
Normal file
@ -0,0 +1,258 @@
|
||||
# -- coding: utf-8 --
|
||||
import sys
|
||||
import time
|
||||
import os
|
||||
import paramiko
|
||||
from scp import SCPClient
|
||||
import threading
|
||||
from os import abort
|
||||
from pathlib import Path
|
||||
from clog import logger, set_logger_file_handler
|
||||
|
||||
HOST = "192.168.100.254"
|
||||
PORT = 22
|
||||
USERNAME = "root"
|
||||
PASSWORD = "ebaina"
|
||||
|
||||
# CLOUD_COUNTS = [600000,800000,1000000,1500000,2000000]
|
||||
CLOUD_COUNTS = [1500000]
|
||||
DEFAULT_COUNT = 1500000
|
||||
EXPS = [2*1000,3*1000]
|
||||
# EXPS = [100 * 1000]
|
||||
DEFAULT_EXP = int(3 * 1000)
|
||||
PARENT_DIR_NAME = "拼接测试_位置3_1平角度_天气_晴天大太阳下午_driverV2_om3"
|
||||
# PARENT_DIR_NAME = "test_1"
|
||||
SAVE_DIR_NAME = ""
|
||||
TEST_CLOUD = False
|
||||
TEST_EXP = True
|
||||
|
||||
|
||||
def ssh_execute_command(host, port, username, password, command):
|
||||
ret = False
|
||||
# 创建SSH客户端
|
||||
client = paramiko.SSHClient()
|
||||
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
client.connect(host, port, username, password)
|
||||
|
||||
# 执行命令
|
||||
stdin, stdout, stderr = client.exec_command(command)
|
||||
# 实时读取标准输出
|
||||
for line in iter(stdout.readline, ""):
|
||||
print(line, end="") # 实时打印
|
||||
sys.stdout.flush() # 刷新缓冲区,确保立即输出到终端
|
||||
|
||||
# 实时读取标准错误(如果有)
|
||||
for line in iter(stderr.readline, ""):
|
||||
print(f"ERROR: {line}", end="")
|
||||
sys.stdout.flush()
|
||||
|
||||
# 关闭连接
|
||||
client.close()
|
||||
return True
|
||||
|
||||
|
||||
def scp_get_file(host, port, username, password, remote_path, local_path):
|
||||
ret = False
|
||||
# 创建SSH客户端
|
||||
client = paramiko.Transport((host, port))
|
||||
client.connect(username=username, password=password)
|
||||
|
||||
# 创建SCP客户端
|
||||
scp_client = SCPClient(client)
|
||||
|
||||
# 拉取文件
|
||||
try:
|
||||
scp_client.get(remote_path, local_path)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return False
|
||||
|
||||
# 关闭连接
|
||||
scp_client.close()
|
||||
client.close()
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def scp_get_multi_file(host, port, username, password, remote_path, local_path):
|
||||
ret = False
|
||||
# 创建SSH客户端
|
||||
client = paramiko.Transport((host, port))
|
||||
client.connect(username=username, password=password)
|
||||
|
||||
# 创建SCP客户端
|
||||
scp_client = SCPClient(client)
|
||||
|
||||
# 拉取文件
|
||||
try:
|
||||
for rp in remote_path:
|
||||
scp_client.get(rp, local_path)
|
||||
except Exception as e:
|
||||
logger.error(f"拉取文件失败:{e}")
|
||||
return False
|
||||
|
||||
# 关闭连接
|
||||
scp_client.close()
|
||||
client.close()
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def cap(exp=DEFAULT_EXP, cloud_count=DEFAULT_COUNT):
|
||||
global SAVE_DIR_NAME
|
||||
logger.debug(f"===================开处理============================")
|
||||
# 先删除旧数据
|
||||
logger.debug("删除旧数据")
|
||||
ssh_execute_command(
|
||||
host=HOST,
|
||||
port=PORT,
|
||||
username=USERNAME,
|
||||
password=PASSWORD,
|
||||
command="cd /root/app/detect-gui/ \n " +
|
||||
"rm output.jpg \n" +
|
||||
"rm output.ply \n" +
|
||||
"rm roi_conners.txt \n"
|
||||
)
|
||||
logger.debug("删除旧数据完成")
|
||||
|
||||
logger.debug(f"曝光时间设置为:{exp}")
|
||||
logger.debug(f"点云数量设置为:{cloud_count}")
|
||||
SAVE_DIR_NAME = f"exp_{exp}_cn_{cloud_count}"
|
||||
logger.debug(f"保存路径为:{SAVE_DIR_NAME}")
|
||||
|
||||
# 如果文件夹不存在则创建
|
||||
if not os.path.exists(Path(__file__).parent / "result" / PARENT_DIR_NAME / SAVE_DIR_NAME):
|
||||
os.makedirs(Path(__file__).parent / "result" / PARENT_DIR_NAME / SAVE_DIR_NAME)
|
||||
|
||||
# ssh调用远程 borad_image_framework_tmp.py 进行拍摄图片,雷达点云数据采集,角点ROI数据生成
|
||||
start_time = time.time()
|
||||
command = "export LD_LIBRARY_PATH=/root/app/ss928_codec/mpp/out/lib:/root/app/detect-gui/vendors/image-framework/linux_arm64:/root/app/detect-gui/vendors/image-framework/linux_arm64/lib:/root/app/detect-gui/vendors/image-framework/linux_arm64/lib/npu:/root/app/detect-gui/vendors/image-framework/linux_arm64/lib/svp_npu:$LD_LIBRARY_PATH \n" + \
|
||||
"cd /root/app/detect-gui/ \n" + \
|
||||
f"/root/miniconda3/bin/python borad_image_framework_tmp.py --exp={exp} --count={cloud_count}\n"
|
||||
logger.debug(f"ssh_execute_command 命令:{command}")
|
||||
ssh_execute_command(
|
||||
host=HOST,
|
||||
port=PORT,
|
||||
username=USERNAME,
|
||||
password=PASSWORD,
|
||||
command=command,
|
||||
)
|
||||
end_time = time.time() # 记录结束时间
|
||||
execution_time = end_time - start_time # 计算执行时间
|
||||
logger.debug(f"borad_image_framework_tmp.py 程序执行时间:{execution_time}秒")
|
||||
time.sleep(1) # 等待操作系统保存数据完毕
|
||||
|
||||
logger.debug("开始保存文件到本地")
|
||||
start_time2 = time.time()
|
||||
local_path = Path(__file__).parent / "result" / PARENT_DIR_NAME / SAVE_DIR_NAME
|
||||
logger.debug(f"本地文件保存路径为:{local_path}")
|
||||
scp_get_multi_file(
|
||||
host=HOST,
|
||||
port=PORT,
|
||||
username=USERNAME,
|
||||
password=PASSWORD,
|
||||
remote_path=[
|
||||
"/root/app/detect-gui/output.jpg",
|
||||
"/root/app/detect-gui/output.ply",
|
||||
"/root/app/detect-gui/roi_conners.txt",
|
||||
],
|
||||
local_path=local_path
|
||||
)
|
||||
end_time2 = time.time() # 记录结束时间
|
||||
execution_time2 = end_time2 - start_time2
|
||||
logger.debug("文件到本地结束")
|
||||
logger.debug(f"scp_get_file获取文件到本地 程序执行时间:{execution_time2}秒")
|
||||
logger.debug(f"===================开处理结束============================")
|
||||
|
||||
|
||||
def cap_wide():
|
||||
logger.debug(f"===================广角开始处理============================")
|
||||
|
||||
# 先删除旧数据
|
||||
logger.debug("删除旧数据")
|
||||
ssh_execute_command(
|
||||
host=HOST,
|
||||
port=PORT,
|
||||
username=USERNAME,
|
||||
password=PASSWORD,
|
||||
command="cd /root/app/detect-gui/ \n " +
|
||||
"rm wide_image_processed.png \n" +
|
||||
"rm wide_image.png \n" +
|
||||
"rm wide_image_roi.json \n"
|
||||
)
|
||||
logger.debug("删除旧数据完成")
|
||||
|
||||
start_time = time.time()
|
||||
command = "export LD_LIBRARY_PATH=/root/app/ss928_codec/mpp/out/lib:/root/app/detect-gui/vendors/image-framework/linux_arm64:/root/app/detect-gui/vendors/image-framework/linux_arm64/lib:/root/app/detect-gui/vendors/image-framework/linux_arm64/lib/npu:/root/app/detect-gui/vendors/image-framework/linux_arm64/lib/svp_npu:$LD_LIBRARY_PATH \n" + \
|
||||
"cd /root/app/detect-gui/ \n" + \
|
||||
f"/root/miniconda3/bin/python cap_wide_camera.py \n"
|
||||
logger.debug(f"ssh_execute_command 命令:{command}")
|
||||
ssh_execute_command(
|
||||
host=HOST,
|
||||
port=PORT,
|
||||
username=USERNAME,
|
||||
password=PASSWORD,
|
||||
command=command,
|
||||
)
|
||||
end_time = time.time() # 记录结束时间
|
||||
execution_time = end_time - start_time # 计算执行时间
|
||||
logger.debug(f"cap_wide_camera.py 程序执行时间:{execution_time}秒")
|
||||
time.sleep(1) # 等待操作系统保存数据完毕
|
||||
|
||||
logger.debug("开始保存文件到本地")
|
||||
start_time2 = time.time()
|
||||
local_path = Path(__file__).parent / "result" / PARENT_DIR_NAME
|
||||
logger.debug(f"本地文件保存路径为:{local_path}")
|
||||
scp_get_multi_file(
|
||||
host=HOST,
|
||||
port=PORT,
|
||||
username=USERNAME,
|
||||
password=PASSWORD,
|
||||
remote_path=[
|
||||
"/root/app/detect-gui/wide_image_processed.png",
|
||||
"/root/app/detect-gui/wide_image.png",
|
||||
"/root/app/detect-gui/wide_image_roi.json",
|
||||
],
|
||||
local_path=local_path
|
||||
)
|
||||
end_time2 = time.time() # 记录结束时间
|
||||
execution_time2 = end_time2 - start_time2
|
||||
logger.debug("文件到本地结束")
|
||||
logger.debug(f"scp_get_file获取文件到本地 程序执行时间:{execution_time2}秒")
|
||||
logger.debug(f"===================广角开处理结束============================")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
|
||||
# 如果路径不存在则创建
|
||||
if not os.path.exists(Path(__file__).parent / "result" / PARENT_DIR_NAME):
|
||||
os.makedirs(Path(__file__).parent / "result" / PARENT_DIR_NAME)
|
||||
# 设置日志保存路径
|
||||
set_logger_file_handler(Path(__file__).parent / "result" / PARENT_DIR_NAME)
|
||||
# 加载驱动
|
||||
ssh_execute_command(
|
||||
host=HOST,
|
||||
port=PORT,
|
||||
username=USERNAME,
|
||||
password=PASSWORD,
|
||||
command="/opt/HuarayTech/MVviewer/module/loadAllDrv.sh \n"
|
||||
)
|
||||
|
||||
if (TEST_CLOUD):
|
||||
for cloud_count in CLOUD_COUNTS:
|
||||
logger.debug("开始采集")
|
||||
start_time = time.time() # 记录开始时间
|
||||
cap(cloud_count=cloud_count)
|
||||
end_time = time.time() # 记录结束时间
|
||||
elapsed_time = end_time - start_time # 计算总时间
|
||||
logger.success(f"采集完毕=========== 耗时: {elapsed_time:.2f} 秒")
|
||||
if (TEST_EXP):
|
||||
for exp in EXPS:
|
||||
logger.debug("开始采集")
|
||||
start_time = time.time() # 记录开始时间
|
||||
cap(exp=exp)
|
||||
end_time = time.time() # 记录结束时间
|
||||
elapsed_time = end_time - start_time # 计算总时间
|
||||
logger.success(f"采集完毕=========== 耗时: {elapsed_time:.2f} 秒")
|
||||
cap_wide()
|
92
clog.py
Normal file
92
clog.py
Normal file
@ -0,0 +1,92 @@
|
||||
import logging
|
||||
import sys
|
||||
from fileinput import filename
|
||||
|
||||
from colorlog import ColoredFormatter
|
||||
|
||||
# 创建一个 logger
|
||||
logger = logging.getLogger('my_logger')
|
||||
logger.setLevel(logging.DEBUG)
|
||||
|
||||
# 创建一个控制台处理器
|
||||
console_handler = logging.StreamHandler()
|
||||
|
||||
# 定义 SUCCESS 级别的数值 (INFO=20, WARNING=30,所以 SUCCESS 可以设为 25)
|
||||
SUCCESS = 25
|
||||
logging.addLevelName(SUCCESS, "SUCCESS")
|
||||
|
||||
# 定义一个 success 方法
|
||||
def success(self, message, *args, **kwargs):
|
||||
if self.isEnabledFor(SUCCESS):
|
||||
self._log(SUCCESS, message, args, **kwargs)
|
||||
|
||||
# 绑定到 Logger 类上
|
||||
logging.Logger.success = success
|
||||
|
||||
|
||||
# 创建带颜色的格式化器(用于控制台输出)
|
||||
console_formatter = ColoredFormatter(
|
||||
"%(log_color)s%(asctime)s - %(filename)s:%(lineno)d - [%(levelname)s]:%(message)s",
|
||||
datefmt="%Y-%m-%d %H:%M:%S",
|
||||
reset=True,
|
||||
log_colors={
|
||||
'SUCCESS': 'green', # 这里定义 SUCCESS 级别的颜色
|
||||
'DEBUG': 'cyan',
|
||||
'INFO': 'white',
|
||||
'WARNING': 'yellow',
|
||||
'ERROR': 'red',
|
||||
'CRITICAL': 'red,bg_black',
|
||||
},
|
||||
secondary_log_colors={
|
||||
'message': {
|
||||
'SUCCESS': 'green', # 这里定义 SUCCESS 级别的消息颜色
|
||||
'DEBUG': 'cyan',
|
||||
'INFO': 'white',
|
||||
'WARNING': 'yellow',
|
||||
'ERROR': 'red',
|
||||
'CRITICAL': 'red,bg_black',
|
||||
}
|
||||
},
|
||||
style='%'
|
||||
)
|
||||
|
||||
# 创建普通格式的格式化器(用于日志文件)
|
||||
file_formatter = logging.Formatter(
|
||||
"%(asctime)s - %(filename)s:%(lineno)d - %(levelname)s:%(name)s:%(message)s",
|
||||
datefmt="%Y-%m-%d %H:%M:%S"
|
||||
)
|
||||
|
||||
# 设置格式化器
|
||||
console_handler.setFormatter(console_formatter)
|
||||
|
||||
# 将处理器添加到 logger
|
||||
logger.addHandler(console_handler)
|
||||
|
||||
def set_logger_file_handler(p):
|
||||
# 创建一个文件处理器,保存日志到本地文件
|
||||
file_handler = logging.FileHandler(f'{p}/run.log', encoding='utf-8')
|
||||
file_handler.setFormatter(file_formatter)
|
||||
logger.addHandler(file_handler)
|
||||
|
||||
# 重定向 stdout 和 stderr 到日志系统
|
||||
class LoggerWriter:
|
||||
def __init__(self, level):
|
||||
self.level = level
|
||||
|
||||
def write(self, message):
|
||||
if message.strip(): # 过滤掉空行
|
||||
self.level(message.strip()) # 去掉首尾空白字符
|
||||
|
||||
def flush(self):
|
||||
pass
|
||||
|
||||
sys.stdout = LoggerWriter(logger.info)
|
||||
sys.stderr = LoggerWriter(logger.error)
|
||||
|
||||
# 测试日志
|
||||
# logger.success("This is a debug message")
|
||||
# logger.debug("This is a debug message")
|
||||
# logger.info("This is an info message")
|
||||
# logger.warning("This is a warning message")
|
||||
# logger.error("This is an error message")
|
||||
# logger.critical("This is a critical message")
|
48
config.ini
Normal file
48
config.ini
Normal file
@ -0,0 +1,48 @@
|
||||
[2D]
|
||||
w = 9344
|
||||
h = 7000
|
||||
fx = 11550.4192
|
||||
fy = 11546.8773
|
||||
cx = 4672.28001
|
||||
cy = 3499.29103
|
||||
k1 = -0.0198130409
|
||||
k2 = 0.0446498961
|
||||
p1 = 0.000332909840
|
||||
p2 = -0.000424586368
|
||||
k3 = 0.371045956
|
||||
yolo_label = 0
|
||||
yolo_prob = 0.601
|
||||
yolo_modol_path = ./best_ep23_small_lab.om
|
||||
save_image = true
|
||||
roi_y_offset = 20
|
||||
edge_min_line_len = 400
|
||||
edge_max_line_gap = 120
|
||||
edge_min_angle_th = 33
|
||||
kk = 0.0
|
||||
|
||||
[3D]
|
||||
r = 1.572895519320505
|
||||
p = -1.5570521101629837
|
||||
y = 0.024731696602587224
|
||||
tx = 0.109253
|
||||
ty = 0.0710213
|
||||
tz = 0.0175978
|
||||
dminx = -2.5
|
||||
dmaxx = 2.5
|
||||
dminy = -2.5
|
||||
dmaxy = 2.5
|
||||
dminz = 0.0
|
||||
dmaxz = 3.6
|
||||
kk = 0.0
|
||||
cloud_need_points_size = 600000
|
||||
save_cload = true
|
||||
|
||||
[sys]
|
||||
fake = false
|
||||
camera_cap_fake = true
|
||||
lidar_cap_fake = true
|
||||
npu_fake = true
|
||||
conners_detect_fake = false
|
||||
fake_image_fpath = ./result/test_1/ep_100000_count_600000/output.jpg
|
||||
fake_lidar_fpath = ./result/test_1/ep_100000_count_600000/output.ply
|
||||
|
271
detect.py
Normal file
271
detect.py
Normal file
@ -0,0 +1,271 @@
|
||||
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()
|
80
draw_ymj.py
Normal file
80
draw_ymj.py
Normal file
@ -0,0 +1,80 @@
|
||||
import pandas as pd
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib.patches import Rectangle
|
||||
|
||||
def col(char):
|
||||
return ord(char) - ord('A') + 0
|
||||
|
||||
# 读取Excel文件,指定表格路径
|
||||
file_path = '预埋件位置.xlsx'
|
||||
|
||||
# 使用pandas读取Excel
|
||||
df = pd.read_excel(file_path, sheet_name='测量结果') # 根据你的Excel表格来设置sheet_name
|
||||
|
||||
# 打印列名
|
||||
print("DataFrame 列名:", df.columns)
|
||||
|
||||
# 创建一个图形和坐标轴
|
||||
fig, ax = plt.subplots()
|
||||
|
||||
# 初始化边界变量
|
||||
x_min, x_max = float('inf'), float('-inf')
|
||||
y_min, y_max = float('inf'), float('-inf')
|
||||
|
||||
|
||||
x_max_original = 0
|
||||
for index, row in df.iloc[2:30].iterrows():
|
||||
original_x = row[col('K')] - row[col('D')] / 2
|
||||
if(original_x > x_max_original):
|
||||
x_max_original = original_x
|
||||
|
||||
|
||||
for index, row in df.iloc[2:30].iterrows():
|
||||
# 打印B列和C列的值
|
||||
print(f"行 {index+2} -> A列-编号: {row[col('A')]}, D列-测量宽度: {row[col('D')]}, E列-测量高度: {row[col('E')]},K列-测量中心x: {row[col('K')]}, L列-测量中心y: {row[col('L')]}")
|
||||
|
||||
# 转换x坐标
|
||||
x_original = row[col('K')]
|
||||
x = x_max_original - x_original - row[col('D')] / 2
|
||||
y = row[col('L')] - row[col('E')] / 2
|
||||
|
||||
# 更新边界
|
||||
x_min = min(x_min, x)
|
||||
x_max = max(x_max, x + row[col('D')])
|
||||
y_min = min(y_min, y)
|
||||
y_max = max(y_max, y + row[col('E')])
|
||||
|
||||
# 绘制矩形
|
||||
rect = Rectangle((x, y), row[col('D')], row[col('E')], linewidth=1, edgecolor='r', facecolor='none')
|
||||
ax.add_patch(rect)
|
||||
|
||||
# 在矩形中心绘制编号(A列)
|
||||
ax.text(
|
||||
x + row[col('D')] / 2, y + row[col('E')] / 2, str(row[col('A')]),
|
||||
ha='center', va='center',
|
||||
fontsize=12, color='blue' # 编号字体大小为12,颜色为蓝色
|
||||
)
|
||||
|
||||
# 在矩形上边绘制宽度(D列)
|
||||
ax.text(
|
||||
x + row[col('D')] / 2, y + row[col('E')], str(row[col('D')]),
|
||||
ha='center', va='bottom',
|
||||
fontsize=6, color='green' # 宽度字体大小为10,颜色为绿色
|
||||
)
|
||||
|
||||
# 在矩形右边绘制高度(E列)
|
||||
ax.text(
|
||||
x + row[col('D')], y + row[col('E')] / 2, str(row[col('E')]),
|
||||
ha='left', va='center',
|
||||
fontsize=6, color='red' # 高度字体大小为10,颜色为红色
|
||||
)
|
||||
|
||||
# 设置坐标轴的范围,外扩100左右
|
||||
ax.set_xlim(x_min, x_max ) # 留出一些边距
|
||||
ax.set_ylim(y_min, y_max ) # 留出一些边距
|
||||
|
||||
# 设置坐标轴的比例
|
||||
ax.set_aspect('equal')
|
||||
|
||||
# 显示图形
|
||||
plt.show()
|
60
environment.yaml
Normal file
60
environment.yaml
Normal file
@ -0,0 +1,60 @@
|
||||
name: ymj_test
|
||||
channels:
|
||||
- defaults
|
||||
- https://repo.anaconda.com/pkgs/main
|
||||
- https://repo.anaconda.com/pkgs/r
|
||||
- https://repo.anaconda.com/pkgs/msys2
|
||||
dependencies:
|
||||
- ca-certificates=2024.12.31=haa95532_0
|
||||
- openssl=3.0.15=h827c3e9_0
|
||||
- pip=25.0=py39haa95532_0
|
||||
- python=3.9.20=h8205438_1
|
||||
- setuptools=75.8.0=py39haa95532_0
|
||||
- sqlite=3.45.3=h2bbff1b_0
|
||||
- vc=14.42=haa95532_4
|
||||
- vs2015_runtime=14.42.34433=he0abc0d_4
|
||||
- wheel=0.45.1=py39haa95532_0
|
||||
- pip:
|
||||
- bcrypt==4.2.1
|
||||
- cffi==1.17.1
|
||||
- colorama==0.4.6
|
||||
- colorlog==6.9.0
|
||||
- contourpy==1.3.0
|
||||
- cryptography==44.0.1
|
||||
- cycler==0.12.1
|
||||
- et-xmlfile==2.0.0
|
||||
- fonttools==4.56.0
|
||||
- imageio==2.37.0
|
||||
- importlib-resources==6.5.2
|
||||
- joblib==1.4.2
|
||||
- kiwisolver==1.4.7
|
||||
- lazy-loader==0.4
|
||||
- markdown-it-py==3.0.0
|
||||
- matplotlib==3.9.4
|
||||
- mdurl==0.1.2
|
||||
- networkx==3.2.1
|
||||
- numpy==2.0.2
|
||||
- opencv-python==4.11.0.86
|
||||
- openpyxl==3.1.5
|
||||
- packaging==24.2
|
||||
- pandas==2.2.3
|
||||
- paramiko==3.5.1
|
||||
- pillow==11.1.0
|
||||
- pycparser==2.22
|
||||
- pygments==2.19.1
|
||||
- pynacl==1.5.0
|
||||
- pyparsing==3.2.1
|
||||
- python-dateutil==2.9.0.post0
|
||||
- pytz==2025.1
|
||||
- rich==13.9.4
|
||||
- scikit-image==0.24.0
|
||||
- scikit-learn==1.6.1
|
||||
- scipy==1.13.1
|
||||
- scp==0.15.0
|
||||
- six==1.17.0
|
||||
- threadpoolctl==3.5.0
|
||||
- tifffile==2024.8.30
|
||||
- typing-extensions==4.12.2
|
||||
- tzdata==2025.1
|
||||
- zipp==3.21.0
|
||||
prefix: C:\Users\leon\miniconda3\envs\ymj_test
|
115
excel_point_to_bm_json_.py
Normal file
115
excel_point_to_bm_json_.py
Normal file
@ -0,0 +1,115 @@
|
||||
import pandas as pd
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib.patches import Rectangle
|
||||
|
||||
def col(char):
|
||||
return ord(char) - ord('A') + 0
|
||||
|
||||
# 读取Excel文件,指定表格路径
|
||||
file_path = '预埋件位置.xlsx'
|
||||
|
||||
# 使用pandas读取Excel
|
||||
df = pd.read_excel(file_path, sheet_name='测量结果') # 根据你的Excel表格来设置sheet_name
|
||||
|
||||
# 打印列名
|
||||
print("DataFrame 列名:", df.columns)
|
||||
|
||||
# 创建一个图形和坐标轴
|
||||
fig, ax = plt.subplots()
|
||||
|
||||
# 初始化边界变量
|
||||
x_min, x_max = float('inf'), float('-inf')
|
||||
y_min, y_max = float('inf'), float('-inf')
|
||||
|
||||
|
||||
x_max_original = 0
|
||||
for index, row in df.iloc[2:30].iterrows():
|
||||
original_x = row[col('K')] - row[col('D')] / 2
|
||||
if(original_x > x_max_original):
|
||||
x_max_original = original_x
|
||||
|
||||
|
||||
bm_struct_array = []
|
||||
|
||||
for index, row in df.iloc[2:30].iterrows():
|
||||
# 打印B列和C列的值
|
||||
print(f"行 {index+2} -> A列-编号: {row[col('A')]}, D列-测量宽度: {row[col('D')]}, E列-测量高度: {row[col('E')]},K列-测量中心x: {row[col('K')]}, L列-测量中心y: {row[col('L')]}")
|
||||
|
||||
# 转换x坐标
|
||||
x_original = row[col('K')]
|
||||
x = x_max_original - x_original - row[col('D')] / 2
|
||||
y = row[col('L')] - row[col('E')] / 2
|
||||
|
||||
# 转换中心点坐标
|
||||
center_x = x_max_original - x_original
|
||||
center_y = row[col('L')]
|
||||
|
||||
# [{
|
||||
# "code": "PT001",
|
||||
# "type": "250x1450",
|
||||
# "x": "905",
|
||||
# "y": "0",
|
||||
# "center": "0.350",
|
||||
# "w": "1450",
|
||||
# "h": "250",
|
||||
# "angle": "90\""
|
||||
# },
|
||||
bm_struct_array.append({
|
||||
"code": str(row[col('A')]),
|
||||
"type": f"{str(row[col('E')])}x{str(row[col('D')])}",# w x h
|
||||
"x": str(center_x),
|
||||
"y": 0,
|
||||
"center": str(center_y),
|
||||
"w": str(row[col('D')]),
|
||||
"h": str(row[col('E')]),
|
||||
"angle" : "0°"
|
||||
})
|
||||
|
||||
# 画出中心点
|
||||
ax.scatter(center_x, center_y, color='red', marker='o', s=10)
|
||||
|
||||
# 更新边界
|
||||
x_min = min(x_min, x)
|
||||
x_max = max(x_max, x + row[col('D')])
|
||||
y_min = min(y_min, y)
|
||||
y_max = max(y_max, y + row[col('E')])
|
||||
|
||||
# 绘制矩形
|
||||
rect = Rectangle((x, y), row[col('D')], row[col('E')], linewidth=1, edgecolor='r', facecolor='none')
|
||||
ax.add_patch(rect)
|
||||
|
||||
# 在矩形中心绘制编号(A列)
|
||||
ax.text(
|
||||
center_x+60, center_y, str(row[col('A')]),
|
||||
ha='center', va='center',
|
||||
fontsize=8, color='blue' # 编号字体大小为12,颜色为蓝色
|
||||
)
|
||||
|
||||
# 在矩形上边绘制宽度(D列)
|
||||
ax.text(
|
||||
x + row[col('D')] / 2, y + row[col('E')], str(row[col('D')]),
|
||||
ha='center', va='bottom',
|
||||
fontsize=6, color='green' # 宽度字体大小为10,颜色为绿色
|
||||
)
|
||||
|
||||
# 在矩形右边绘制高度(E列)
|
||||
ax.text(
|
||||
x + row[col('D')], y + row[col('E')] / 2, str(row[col('E')]),
|
||||
ha='left', va='center',
|
||||
fontsize=6, color='red' # 高度字体大小为10,颜色为红色
|
||||
)
|
||||
|
||||
# 设置坐标轴的范围,外扩100左右
|
||||
ax.set_xlim(x_min, x_max ) # 留出一些边距
|
||||
ax.set_ylim(y_min, y_max ) # 留出一些边距
|
||||
|
||||
# 设置坐标轴的比例
|
||||
ax.set_aspect('equal')
|
||||
|
||||
# 显示图形
|
||||
plt.show()
|
||||
|
||||
# 保存bm_struct_array 为json到本地
|
||||
import json
|
||||
with open('bm_struct_array.json', 'w') as f:
|
||||
json.dump(bm_struct_array, f)
|
BIN
image_framework.dll
Normal file
BIN
image_framework.dll
Normal file
Binary file not shown.
233
imgProcess.py
Normal file
233
imgProcess.py
Normal file
@ -0,0 +1,233 @@
|
||||
# -- 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:
|
||||
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 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 =================")
|
||||
|
BIN
myplot.png
Normal file
BIN
myplot.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 23 KiB |
BIN
myplot_2.png
Normal file
BIN
myplot_2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
BIN
myplot_3.png
Normal file
BIN
myplot_3.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
BIN
opencv_videoio_ffmpeg420.dll
Normal file
BIN
opencv_videoio_ffmpeg420.dll
Normal file
Binary file not shown.
BIN
opencv_videoio_ffmpeg420_64.dll
Normal file
BIN
opencv_videoio_ffmpeg420_64.dll
Normal file
Binary file not shown.
BIN
opencv_world420d.dll
Normal file
BIN
opencv_world420d.dll
Normal file
Binary file not shown.
27
points.txt
Normal file
27
points.txt
Normal file
@ -0,0 +1,27 @@
|
||||
[(4366.0, 226.0), (5816.0, 226.0), (5816.0, 476.0), (4366.0, 476.0)]
|
||||
[(4963.0, 604.0), (5263.0, 604.0), (5263.0, 904.0), (4963.0, 904.0)]
|
||||
[(4147.5, 804.0), (4647.5, 804.0), (4647.5, 1305.0), (4147.5, 1305.0)]
|
||||
[(4995.0, 1024.0), (5643.0, 1024.0), (5643.0, 1274.0), (4995.0, 1274.0)]
|
||||
[(4574.0, 1418.0), (4824.0, 1418.0), (4824.0, 1668.0), (4574.0, 1668.0)]
|
||||
[(4131.0, 1626.0), (4380.0, 1626.0), (4380.0, 1875.0), (4131.0, 1875.0)]
|
||||
[(5287.0, 1755.0), (5686.0, 1755.0), (5686.0, 2155.0), (5287.0, 2155.0)]
|
||||
[(4742.0, 2009.0), (5044.0, 2009.0), (5044.0, 2309.0), (4742.0, 2309.0)]
|
||||
[(4140.0, 2007.0), (4442.0, 2007.0), (4442.0, 2307.0), (4140.0, 2307.0)]
|
||||
[(2373.5, 221.0), (3820.5, 221.0), (3820.5, 469.0), (2373.5, 469.0)]
|
||||
[(2940.0, 598.0), (3237.0, 598.0), (3237.0, 896.0), (2940.0, 896.0)]
|
||||
[(2146.5, 791.0), (2645.5, 791.0), (2645.5, 1290.0), (2146.5, 1290.0)]
|
||||
[(2968.5, 1024.0), (3616.5, 1024.0), (3616.5, 1269.0), (2968.5, 1269.0)]
|
||||
[(2574.0, 1427.0), (2821.0, 1427.0), (2821.0, 1674.0), (2574.0, 1674.0)]
|
||||
[(2165.0, 1634.0), (2412.0, 1634.0), (2412.0, 1880.0), (2165.0, 1880.0)]
|
||||
[(3291.5, 1756.0), (3683.5, 1756.0), (3683.5, 2154.0), (3291.5, 2154.0)]
|
||||
[(2746.0, 1997.0), (3039.0, 1997.0), (3039.0, 2297.0), (2746.0, 2297.0)]
|
||||
[(2137.0, 1995.0), (2434.0, 1995.0), (2434.0, 2293.0), (2137.0, 2293.0)]
|
||||
[(372.0, 222.0), (1819.0, 222.0), (1819.0, 467.0), (372.0, 467.0)]
|
||||
[(962.0, 596.0), (1262.0, 596.0), (1262.0, 891.0), (962.0, 891.0)]
|
||||
[(142.0, 781.0), (637.0, 781.0), (637.0, 1279.0), (142.0, 1279.0)]
|
||||
[(986.0, 1028.0), (1634.0, 1028.0), (1634.0, 1273.0), (986.0, 1273.0)]
|
||||
[(616.5, 1419.0), (862.5, 1419.0), (862.5, 1664.0), (616.5, 1664.0)]
|
||||
[(172.0, 1613.0), (417.0, 1613.0), (417.0, 1858.0), (172.0, 1858.0)]
|
||||
[(1294.5, 1756.0), (1686.5, 1756.0), (1686.5, 2154.0), (1294.5, 2154.0)]
|
||||
[(746.5, 1993.0), (1042.5, 1993.0), (1042.5, 2291.0), (746.5, 2291.0)]
|
||||
[(148.0, 1998.0), (443.0, 1998.0), (443.0, 2295.0), (148.0, 2295.0)]
|
7
readme.md
Normal file
7
readme.md
Normal file
@ -0,0 +1,7 @@
|
||||
```pycon
|
||||
self.image_framework = ImageFramework()
|
||||
self.image_framework.signals.on_image_detect_result.connect(
|
||||
lambda data: self.image_result(data))
|
||||
self.image_framework.configure()
|
||||
self.image_framework.start()
|
||||
```
|
24
roi_conners.txt
Normal file
24
roi_conners.txt
Normal file
@ -0,0 +1,24 @@
|
||||
1131
|
||||
2007
|
||||
5900
|
||||
2007
|
||||
5900
|
||||
5376
|
||||
1131
|
||||
5376
|
||||
2004
|
||||
2958
|
||||
3142
|
||||
2958
|
||||
3142
|
||||
3948
|
||||
2004
|
||||
3948
|
||||
3887
|
||||
2919
|
||||
4839
|
||||
2919
|
||||
4839
|
||||
3902
|
||||
3887
|
||||
3902
|
28
util.py
Normal file
28
util.py
Normal file
@ -0,0 +1,28 @@
|
||||
import configparser
|
||||
from clog import logger
|
||||
|
||||
"""
|
||||
修改配置文件中的指定参数。
|
||||
|
||||
参数:
|
||||
s (str): 配置文件中的节(section)名称。
|
||||
o (str): 配置文件中的选项(option)名称。
|
||||
v (str): 要设置的新值。
|
||||
|
||||
返回值:
|
||||
无
|
||||
"""
|
||||
def change_config_ini(s, o, v):
|
||||
|
||||
# 读取配置文件
|
||||
config = configparser.ConfigParser()
|
||||
config.read("config.ini", encoding="utf-8") # 解决可能的编码问题
|
||||
|
||||
# 修改参数
|
||||
config.set(s, o, v)
|
||||
|
||||
# 将修改后的配置写回文件
|
||||
with open("config.ini", "w", encoding="utf-8") as configfile:
|
||||
config.write(configfile)
|
||||
|
||||
logger.info(f"{s}.{o} 参数已更新为 {v}")
|
BIN
预埋件位置.xlsx
Normal file
BIN
预埋件位置.xlsx
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user