diff --git a/bim_im.png b/bim_im.png index d6fc3f2..41436a8 100644 Binary files a/bim_im.png and b/bim_im.png differ diff --git a/data_sub/test_1/output.jpg b/data_sub/test_1/output.jpg new file mode 100644 index 0000000..e6c3410 Binary files /dev/null and b/data_sub/test_1/output.jpg differ diff --git a/data_sub/test_1/roi_conners.txt b/data_sub/test_1/roi_conners.txt new file mode 100644 index 0000000..9d7e06a --- /dev/null +++ b/data_sub/test_1/roi_conners.txt @@ -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 diff --git a/data_sub/test_3/data_sub.json b/data_sub/test_3/data_sub.json index 8b57942..76a57da 100644 --- a/data_sub/test_3/data_sub.json +++ b/data_sub/test_3/data_sub.json @@ -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 } ] \ No newline at end of file diff --git a/data_sub/test_3/wide_image.png b/data_sub/test_3/wide_image.png index e1a54fb..ed2a99f 100644 Binary files a/data_sub/test_3/wide_image.png and b/data_sub/test_3/wide_image.png differ diff --git a/data_sub/test_4/data_sub.json b/data_sub/test_4/data_sub.json deleted file mode 100644 index ce79eb3..0000000 --- a/data_sub/test_4/data_sub.json +++ /dev/null @@ -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 - } -] \ No newline at end of file diff --git a/data_sub/test_4/wide_image.png b/data_sub/test_4/wide_image.png deleted file mode 100644 index 1f2d907..0000000 Binary files a/data_sub/test_4/wide_image.png and /dev/null differ diff --git a/readme.md b/readme.md index a63d407..d1a75de 100644 --- a/readme.md +++ b/readme.md @@ -1,3 +1,11 @@ ```bash conda env create -f environment.yaml ``` + +bim定位锁定bim区域xx +画出高清摄像头应该在的区域,是固定的比例,适当的等比例放大一些。xx +获取高清摄像头识别出来的ROI坐标数据 +高清摄像头的ROI坐标转换为bim下的坐标 +遍历范围内的完整的矩形,对比高清摄像头ROI矩形的中心点是否在 bim中矩形的内部 +如果在内部说明是同一个编号的预埋件。 + diff --git a/search.py b/search.py index f174b50..8ebdc06 100644 --- a/search.py +++ b/search.py @@ -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"] diff --git a/test.py b/test.py new file mode 100644 index 0000000..fad0626 --- /dev/null +++ b/test.py @@ -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) + diff --git a/utils.py b/utils.py index 106ebce..b2b7557 100644 --- a/utils.py +++ b/utils.py @@ -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) \ No newline at end of file +# filter_rectangle("data_sub/test_1/wide_image.png",cnts)