高清定位

This commit is contained in:
leon 2025-03-02 16:25:35 +08:00
parent d471a04c4c
commit d4ed1a8bf2
11 changed files with 225 additions and 248 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 115 KiB

After

Width:  |  Height:  |  Size: 144 KiB

BIN
data_sub/test_1/output.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 MiB

View File

@ -0,0 +1,48 @@
5257
903
6328
903
6328
1952
5257
1952
6761
218
7819
218
7819
1274
6761
1274
5819
2345
7892
2345
7892
4400
5819
4400
3538
3764
4866
3764
4866
5085
3538
5085
2165
2303
4853
2303
4853
3510
2165
3510
8936
5442
9341
5442
9341
6534
8936
6534

View File

@ -1,90 +1,98 @@
[
{
"label": 0,
"prob": 0.917050302028656,
"x": 189,
"y": 415,
"width": 196,
"prob": 0.9319185018539429,
"x": 210,
"y": 111,
"width": 55,
"height": 52
},
{
"label": 0,
"prob": 0.9214611649513245,
"x": 337,
"y": 214,
"width": 66,
"height": 66
},
{
"label": 0,
"prob": 0.9198867082595825,
"x": 262,
"y": 262,
"width": 45,
"height": 42
},
{
"label": 0,
"prob": 0.9190443158149719,
"x": 288,
"y": 95,
"width": 42,
"height": 40
},
{
"label": 0,
"prob": 0.9155016541481018,
"x": 214,
"prob": 0.8733175992965698,
"x": 314,
"y": 168,
"width": 37,
"height": 34
},
{
"label": 0,
"prob": 0.8678057193756104,
"x": 359,
"y": 97,
"width": 41,
"height": 38
},
{
"label": 0,
"prob": 0.8506720662117004,
"x": 216,
"y": 212,
"width": 53,
"height": 48
"width": 89,
"height": 38
},
{
"label": 0,
"prob": 0.9061460494995117,
"x": 338,
"y": 309,
"width": 68,
"height": 71
"prob": 0.8226487636566162,
"x": 362,
"y": 146,
"width": 36,
"height": 35
},
{
"label": 0,
"prob": 0.9045385122299194,
"x": 92,
"y": 309,
"prob": 0.5786533355712891,
"x": 55,
"y": 98,
"width": 42,
"height": 39
},
{
"label": 0,
"prob": 0.5088553428649902,
"x": 93,
"y": 215,
"width": 70,
"height": 69
},
{
"label": 0,
"prob": 0.8958920240402222,
"x": 262,
"y": 358,
"width": 46,
"height": 45
},
{
"label": 0,
"prob": 0.8823522329330444,
"x": 219,
"y": 311,
"width": 85,
"height": 37
},
{
"label": 0,
"prob": 0.8750882744789124,
"x": 289,
"y": 197,
"width": 39,
"prob": 0.3739035725593567,
"x": 191,
"y": 314,
"width": 188,
"height": 36
},
{
"label": 0,
"prob": 0.7151791453361511,
"prob": 0.3039762079715729,
"x": 0,
"y": 212,
"width": 48,
"height": 48
},
{
"label": 0,
"prob": 0.569022536277771,
"x": 354,
"y": 198,
"width": 42,
"height": 36
},
{
"label": 0,
"prob": 0.4601861834526062,
"x": 314,
"y": 265,
"width": 36,
"height": 36
},
{
"label": 0,
"prob": 0.3012613356113434,
"x": 360,
"y": 244,
"width": 35,
"height": 33
"y": 117,
"width": 37,
"height": 54
}
]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 414 KiB

After

Width:  |  Height:  |  Size: 445 KiB

View File

@ -1,162 +0,0 @@
[
{
"label": 0,
"prob": 0.895011305809021,
"x": 536,
"y": 127,
"width": 49,
"height": 53
},
{
"label": 0,
"prob": 0.8946242332458496,
"x": 547,
"y": 224,
"width": 70,
"height": 37
},
{
"label": 0,
"prob": 0.8866094946861267,
"x": 198,
"y": 216,
"width": 67,
"height": 63
},
{
"label": 0,
"prob": 0.8786224126815796,
"x": 435,
"y": 222,
"width": 63,
"height": 66
},
{
"label": 0,
"prob": 0.873380720615387,
"x": 83,
"y": 115,
"width": 54,
"height": 53
},
{
"label": 0,
"prob": 0.8712457418441772,
"x": 597,
"y": 117,
"width": 36,
"height": 39
},
{
"label": 0,
"prob": 0.8656917810440063,
"x": 583,
"y": 268,
"width": 37,
"height": 41
},
{
"label": 0,
"prob": 0.718810498714447,
"x": 526,
"y": 316,
"width": 112,
"height": 39
},
{
"label": 0,
"prob": 0.6975097060203552,
"x": 621,
"y": 185,
"width": 17,
"height": 32
},
{
"label": 0,
"prob": 0.6963123083114624,
"x": 314,
"y": 119,
"width": 53,
"height": 55
},
{
"label": 0,
"prob": 0.5993771553039551,
"x": 286,
"y": 319,
"width": 194,
"height": 40
},
{
"label": 0,
"prob": 0.2692039906978607,
"x": 386,
"y": 101,
"width": 46,
"height": 48
},
{
"label": 0,
"prob": 0.21311397850513458,
"x": 321,
"y": 221,
"width": 86,
"height": 40
},
{
"label": 0,
"prob": 0.1731298416852951,
"x": 531,
"y": 121,
"width": 98,
"height": 47
},
{
"label": 0,
"prob": 0.1717808097600937,
"x": 69,
"y": 310,
"width": 172,
"height": 37
},
{
"label": 0,
"prob": 0.14592395722866058,
"x": 87,
"y": 217,
"width": 81,
"height": 35
},
{
"label": 0,
"prob": 0.14323937892913818,
"x": 179,
"y": 171,
"width": 38,
"height": 38
},
{
"label": 0,
"prob": 0.10391232371330261,
"x": 156,
"y": 94,
"width": 46,
"height": 47
},
{
"label": 0,
"prob": 0.08634057641029358,
"x": 414,
"y": 176,
"width": 39,
"height": 37
},
{
"label": 0,
"prob": 0.0807800367474556,
"x": 361,
"y": 269,
"width": 51,
"height": 42
}
]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 412 KiB

View File

@ -1,3 +1,11 @@
```bash
conda env create -f environment.yaml
```
bim定位锁定bim区域xx
画出高清摄像头应该在的区域是固定的比例适当的等比例放大一些。xx
获取高清摄像头识别出来的ROI坐标数据
高清摄像头的ROI坐标转换为bim下的坐标
遍历范围内的完整的矩形对比高清摄像头ROI矩形的中心点是否在 bim中矩形的内部
如果在内部说明是同一个编号的预埋件。

View File

@ -1,6 +1,6 @@
import cv2
from utils import filter_rectangle
from utils import filter_rectangle, get_hd_cam_rect
print(cv2.__version__) # 4.9.0
import json
@ -137,7 +137,7 @@ def gen_im_from_params(params, type="lines"):
max_y = param["center"] + param["h"] / 2
max_y_idx = i
padding_value = 0 # 内边距,避免整个bim图片贴着边缘展示
padding_value = 1000 # 内边距,避免整个bim图片贴着边缘展示
bim_width = int(max_x) + padding_value
print(f"[bim_width] ====== [{bim_width}]")
bim_height = int(max_y) + padding_value
@ -324,6 +324,12 @@ if __name__ == "__main__":
data_sub["type"] = 0
data_sub["params"] = []
# 广角相机拍照照片之后左右边界的裁剪比例。
wide_cam_left_cut_rate = 0.1
wide_cam_right_cut_rate = 0.1
# 高清相机的视场矩形在广角相机里面的坐标。cv2下的图片坐标系以左上角为坐标原点
hd_cam_x, hd_cam_y,hd_cam_w, hd_cam_h, = get_hd_cam_rect(wide_cam_left_cut_rate)
# 创建测试子集
# sub_im = cv2.imread("wide_image.png")
# sub_zero = np.zeros_like(sub_im)
@ -342,7 +348,7 @@ if __name__ == "__main__":
# 过滤矩形
# cnts 过滤之后的矩形
# sub_im 裁剪之后的图像
cnts,sub_im = filter_rectangle("data_sub/test_1/wide_image.png", original_rectangle)
cnts,sub_im = filter_rectangle("data_sub/test_1/wide_image.png", original_rectangle,wide_cam_left_cut_rate,wide_cam_right_cut_rate)
sub_zero = np.zeros_like(sub_im)
for contour in cnts:
# x, y, w, h = cv2.boundingRect(contour)
@ -445,6 +451,7 @@ if __name__ == "__main__":
cv2.circle(sub_im, (p[0], p[1]), 2, (0, 255, 255), -1)
# 写编号
cv2.putText(sub_im, str(i), (p[0], p[1]), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)
cv2.rectangle(sub_im,(hd_cam_x,hd_cam_y),(hd_cam_x+hd_cam_w,hd_cam_y+hd_cam_h), (0, 255, 0), 4)
cv2.imshow("sub_im_points", sub_im)
# cv2.waitKey(0)
polar_list = []
@ -485,6 +492,13 @@ if __name__ == "__main__":
tmp_roi_start_y = int(param['y1'] - scale * polar_origin_y)
tmp_roi_end_y = tmp_roi_start_y + tmp_roi_height
# 计算高清矩形在bim上面的坐标。相当于被scale一起放大了
hd_cam_x_bim = int(scale * hd_cam_x + tmp_roi_start_x)
hd_cam_y_bim = int(scale * hd_cam_y + tmp_roi_start_y)
hd_cam_w_bim = int(scale * hd_cam_w)
hd_cam_h_bim = int(scale * hd_cam_h)
tmp_roi_conners = [[tmp_roi_start_x, tmp_roi_start_y],
[tmp_roi_end_x, tmp_roi_start_y],
[tmp_roi_end_x, tmp_roi_end_y],
@ -537,6 +551,11 @@ if __name__ == "__main__":
param["end_point"] = (tmp_roi_end_x, tmp_roi_end_y)
param["score"] = (score, tmp_count, tmp_sum_r*tmp_roi_w_base_len, tmp_sum_theta)
param['match_score'] = match_score
# 高清相机的矩形数据
param['hd_cam_x_bim'] = hd_cam_x_bim
param['hd_cam_y_bim'] = hd_cam_y_bim
param['hd_cam_w_bim'] = hd_cam_w_bim
param['hd_cam_h_bim'] = hd_cam_h_bim
if min_match_score > match_score:
min_match_score = match_score
print(f"[start_point] ====== [{param["start_point"]}]")
@ -552,7 +571,10 @@ if __name__ == "__main__":
if abs(score[0] / match_score) > max_score:
max_score = abs(score[0] / match_score)
max_index = i
bim_im = cv2.rectangle(bim_im,rst_params[max_index]["start_point"], rst_params[max_index]["end_point"], 100 * (i + 1), 50)
rst_p = rst_params[max_index]
bim_im = cv2.rectangle(bim_im,rst_p["start_point"], rst_p["end_point"], 100 * (i + 1), 50)
# 画出高清相机矩形框
bim_im = cv2.rectangle(bim_im, (rst_p["hd_cam_x_bim"], rst_p["hd_cam_y_bim"]),(rst_p["hd_cam_x_bim"] + rst_p["hd_cam_w_bim"], rst_p["hd_cam_y_bim"] + rst_p["hd_cam_h_bim"],), (0, 0, 255), 40)
# # 预埋件匹配
# for i, param in enumerate(rst_params):
# score = param["score"]

18
test.py Normal file
View File

@ -0,0 +1,18 @@
import cv2
from utils import get_hd_cam_rect
def _darw_rect(im):
x, y, w, h = get_hd_cam_rect(0)
print(w)
print(h)
cv2.rectangle(im, (x, y), (x + w, y + h), (0, 255, 0), 5)
sub_im = cv2.imread("data_sub/test_1/wide_image.png")
_darw_rect(sub_im)
cv2.imshow("sub_zero", sub_im)
cv2.waitKey(0)

View File

@ -3,39 +3,43 @@ import logging
import cv2
"""
根据裁剪之后的图片,每个点的坐标需要重新计算,以新的图片的宽高作为坐标系
"""
def re_cal_point(point,offset):
def re_cal_point(point, offset):
# 相当于所有的x坐标向左平移了offset个距离
point['x'] = point['x'] - offset
"""
过滤矩形
根据左右裁剪之后的图像过滤矩形在裁剪之后整个矩形已经不在图片里面的就去掉
1 高度过大的不要
2 整个矩形全部身体都在裁剪区域之外的不要
image_path:图片路径
points要过滤的点
wide_cam_left_cut_rate# 左边界的裁剪比例,从左边开始裁剪百分之多少
wide_cam_right_cut_rate # 右边界的裁剪比例,从右边开始裁剪百分之多少
返回值:
1 过滤之后的矩形
2 裁剪之后的图片
"""
def filter_rectangle(image_path, points):
def filter_rectangle(image_path, points, wide_cam_left_cut_rate, wide_cam_right_cut_rate):
# 高度过大矩形过滤参数
max_height_rate = 0.5 # 矩形高度占整个画面高度的最大比例,如果超过该比例,则认为是无效矩形
max_height_rate = 0.5 # 矩形高度占整个画面高度的最大比例,如果超过该比例,则认为是无效矩形
# 裁剪参数
left_x_cut_rate=0.1 # 左边界的裁剪比例,从左边开始裁剪百分之多少
right_x_cut_rate=0.1# 右边界的裁剪比例,从右边开始裁剪百分之多少
image = cv2.imread(image_path)
image_height = image.shape[0] # 获取图片高度
image_width = image.shape[1] # 获取图片宽度
image_x_min = int(image_width * left_x_cut_rate) # 左边界的裁剪点
image_x_max = int(image_width * (1 - right_x_cut_rate)) # 右边界的裁剪点
image_height = image.shape[0] # 获取图片高度
image_width = image.shape[1] # 获取图片宽度
image_x_min = int(image_width * wide_cam_left_cut_rate) # 左边界的裁剪点
image_x_max = int(image_width * (1 - wide_cam_right_cut_rate)) # 右边界的裁剪点
#开始过滤矩形
# 开始过滤矩形
bad_point_index = []
print(f'开始过滤矩形,原有矩形数为{len(points)}')
for index in range(len(points)):
@ -47,8 +51,8 @@ def filter_rectangle(image_path, points):
continue
# x坐标范围过滤,整个矩形全部身体都在裁剪区域之外的不要
x_min = point['x'] # 矩形四个矩形坐标中x的最小值
x_max = point['x'] + point['width'] # 矩形四个矩形坐标中x的最大值
x_min = point['x'] # 矩形四个矩形坐标中x的最小值
x_max = point['x'] + point['width'] # 矩形四个矩形坐标中x的最大值
# 如果矩形x的 最大值 小于 左边界,去除这个矩形
if x_max < image_x_min:
bad_point_index.append(index)
@ -64,7 +68,7 @@ def filter_rectangle(image_path, points):
# 如果当前矩形的索引在bad_point_index中则去除这个矩形
if i not in bad_point_index:
# 重新计算点的坐标
re_cal_point(point,image_x_min)
re_cal_point(point, image_x_min)
# 塞入结果
filtered_points.append(point)
print(f'过滤矩形结束,过滤之后的矩形数为{len(filtered_points)}')
@ -85,6 +89,37 @@ def filter_rectangle(image_path, points):
return filtered_points, cropped_image
"""
获取高清相机的视场矩形在广角相机里面的坐标cv2下的图片坐标系以左上角为坐标原点
wide_cam_left_cut_rate# 广角相机,左边界的裁剪比例,从左边开始裁剪百分之多少
wide_cam_right_cut_rate # 广角相机,右边界的裁剪比例,从右边开始裁剪百分之多少
"""
def get_hd_cam_rect(wide_cam_left_cut_rate):
# 下面参数是几乎标准无偏差的高清相机在广角相机里面的视场角矩形 广角为640x480
x = 128
y = 140
w = 312
h = 234
# 按照k比例放大,因为高清在bim图上面定位的区域不一定是准确的可能比广角的原宽度要小。 所以适当放大高清相机的矩形框,
# 广角左边右边,裁剪之前,放大之后的矩形框
k = 0
width_scale_pixel = k * w
height_scale_pixel = k * h
scale_x = x - width_scale_pixel
scale_y = y - height_scale_pixel
scale_w = w + 2 * width_scale_pixel
scale_h = h + 2 * height_scale_pixel
# 广角裁剪之后,高清矩形在新的广角图片里面的坐标。
original_wide_cam_image_width = 640 # 原本广角图片的宽度
cut_image_x_min = int(original_wide_cam_image_width * wide_cam_left_cut_rate) # 左边界的裁剪点
scale_x = scale_x - cut_image_x_min # 因为只是左右裁剪只影响左上角坐标的x值
return int(scale_x), int(scale_y), int(scale_w), int(scale_h)
# 测试代码
# def read_from_json(file_path):
@ -92,4 +127,4 @@ def filter_rectangle(image_path, points):
# loaded_array = json.load(f)
# return loaded_array
# cnts = read_from_json("data_sub/test_1/data_sub.json")
# filter_rectangle("data_sub/test_1/wide_image.png",cnts)
# filter_rectangle("data_sub/test_1/wide_image.png",cnts)