首先使用canny或其他方法将图片边缘轮廓提取:
(下图为mask处理后的图像)
参考论文
《A Sub-Pixel Edge Detector: an Implementation of theCanny/Devernay Algorithm》
提取后的亚像素级边缘散点如下:
由于亚像素级别的点太小,肉眼可能不好辨识,这边放一下局部效果图:
之后根据八邻域算法进行改进,提出了一种边缘亚像素点连线的方法:
import random import cv2 from tqdm import tqdm from json_open_close import open_json, save_json # 获取两点间距离 def get_dis(x1, y1, x2, y2): return ((x1 - x2) ** 2 + (y1 - y2) ** 2) ** 0.5 # 获取相邻最近的三个结点 def get_nearest_nodes(x, y, new_locs): tem_dis = [] for loc in new_locs: if not loc['visited']: tem_dis.append(((x - loc['loc'][0]) ** 2 + (y - loc['loc'][1]) ** 2) ** 0.5) else: tem_dis.append(1e5) _min = min(tem_dis) if _min > 200: return -1, -1, -1 else: _index1 = tem_dis.index(_min) tem_dis[_index1] += 1e5 _min = min(tem_dis) _index2 = tem_dis.index(_min) tem_dis[_index2] += 1e5 _min = min(tem_dis) _index3 = tem_dis.index(_min) tem_dis[_index3] += 1e5 return _index1, _index2, _index3 # 打开json格式存储的点位置文件 f = open_json("Pic1-3board.json") locs = f['2'] length = len(locs) new_locs = [] # 设置新的字典存储点位置 for i in range(length): tem = { "visited": False, "loc": locs[i], "id": 0, "end": False } new_locs.append(tem) # 随机访问结点 start = random.randint(0, length - 1) now_id = 0 new_locs[start]['id'] = now_id new_locs[start]['visited'] = True for i in tqdm(range(len(new_locs) - 1)): now_id += 1 _index1, _index2, _index3 = get_nearest_nodes(new_locs[start]['loc'][0], new_locs[start]['loc'][1], new_locs) if _index1 == -1: new_locs[start]['id'] = now_id new_locs[start]['visited'] = True new_locs[start]['end'] = True count = 0 for loc in new_locs: if not loc['visited']: start = count break count += 1 else: _grad1 = (new_locs[start]['loc'][0] - new_locs[_index1]['loc'][0]) / ( new_locs[start]['loc'][1] - new_locs[_index1]['loc'][1] + 1e-6) _grad2 = (new_locs[start]['loc'][0] - new_locs[_index2]['loc'][0]) / ( new_locs[start]['loc'][1] - new_locs[_index2]['loc'][1] + 1e-6) _grad3 = (new_locs[start]['loc'][0] - new_locs[_index3]['loc'][0]) / ( new_locs[start]['loc'][1] - new_locs[_index3]['loc'][1] + 1e-6) dis1 = (new_locs[start]['loc'][0] - new_locs[_index1]['loc'][0]) ** 2 + ( new_locs[start]['loc'][1] - new_locs[_index1]['loc'][1]) ** 2 dis2 = (new_locs[start]['loc'][0] - new_locs[_index2]['loc'][0]) ** 2 + ( new_locs[start]['loc'][1] - new_locs[_index2]['loc'][1]) ** 2 dis3 = (new_locs[start]['loc'][0] - new_locs[_index3]['loc'][0]) ** 2 + ( new_locs[start]['loc'][1] - new_locs[_index3]['loc'][1]) ** 2 _grad1, _grad2, _grad3 = abs(_grad1), abs(_grad2), abs(_grad3) # 为每个结点打分 score1 = dis1 * 0.9 score2 = dis2 * 0.9 score3 = dis3 * 0.9 scores = (score1, score2, score3) # 选取最优结点 _min = min(scores) _index = scores.index(_min) # 更新索引 if _index == 0: start = _index1 elif _index == 1: start = _index2 else: start = _index3 new_locs[start]['id'] = now_id new_locs[start]['visited'] = True # 储存结果 save_json("new_loc.json", new_locs)
其中提取出的的数据格式为:
{ "visited": true, "loc": [12931, 911], "id": 901, "end": false }
使用cv.line进行连线,为了方便观察,这里用较粗线条进行连接。
效果图:
效果较为满意。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)