栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

【python】【边缘提取】 亚像素轮廓跟踪

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【python】【边缘提取】 亚像素轮廓跟踪

首先使用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进行连线,为了方便观察,这里用较粗线条进行连接。
效果图:

效果较为满意。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/618815.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号