Opencv 学习笔记:距离变换(DIST_L1 算法实战 + 归一化)

距离变换是图像分割、前景提取的核心预处理技术,能计算每个前景像素到最近背景像素的距离。本文以DIST_L1(曼哈顿距离)为例,演示 OpenCV 距离变换全流程,重点讲解归一化的关键作用,新手可直接复用。

核心代码实现

python 复制代码
import cv2 as cv
import numpy as np

# 1. 读取图像并预处理(补充完整流程)
src = cv.imread('./image/test.bmp')  # 替换为你的图像路径
if src is None:
    print('图像读取失败,请检查路径!')
    exit()

# 转为灰度图→二值化(距离变换需输入单通道二值图)
gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
ret, result2 = cv.threshold(gray, 127, 255, cv.THRESH_BINARY)

# 2. 执行距离变换(核心操作)
# 参数说明:二值图、距离类型(DIST_L1)、掩码尺寸(3×3)
result3 = cv.distanceTransform(result2, cv.DIST_L1, cv.DIST_MASK_3)

# 3. 归一化(关键:将距离值缩放到[0,1],适配显示)
cv.normalize(result3, result3, 0, 1, cv.NORM_MINMAX, -1)

# 4. 可视化结果(距离值映射为灰度图)
# 归一化后的值×255转为uint8,便于显示
result_show = (result3 * 255).astype(np.uint8)

cv.namedWindow('原始二值图', cv.WINDOW_NORMAL)
cv.resizeWindow('原始二值图', 600, 600)
cv.imshow('原始二值图', result2)

cv.namedWindow('距离变换结果', cv.WINDOW_NORMAL)
cv.resizeWindow('距离变换结果', 600, 600)
cv.imshow('距离变换结果', result_show)

cv.waitKeyEx(0)
cv.destroyAllWindows()

关键知识点解析

1. 距离变换核心参数

参数 说明 作用
cv.DIST_L1 曼哈顿距离(L1 距离) 计算方式:` x1-x2 + y1-y2 `,计算速度快,无开方运算
cv.DIST_MASK_3 3×3 掩码尺寸 掩码越大,距离计算越精准,但速度稍慢(常用 3/5/7)
cv.NORM_MINMAX 最值归一化 将距离值缩放到[0,1],消除不同图像距离值范围差异

2. 核心逻辑与避坑点

  • 输入要求 :距离变换仅支持单通道二值图(非 0 为前景,0 为背景),需先完成灰度 + 二值化预处理,否则报错;
  • 归一化必要性 :距离变换输出的原始值范围与图像尺寸相关(如 500×500 图像最大距离约 500),归一化后可统一到[0,1],既便于显示,也利于后续阈值筛选;
  • 显示转换 :归一化后的float32类型值(0~1)需 ×255 转为uint8(0~255),否则 OpenCV 无法正确显示(会被识别为 0 值全黑)。

3. 常见距离类型对比

距离类型 计算方式 特点
DIST_L1(曼哈顿) $ x1-x2 + y1-y2 $ 速度最快,无浮点运算
DIST_L2(欧氏) (x1−x2)2+(y1−y2)2​ 精度最高,符合人眼距离感知
DIST_C(切比雪夫) $max( x1-x2 , y1-y2 )$ 适用于棋盘格距离计算场景

总结

  1. 距离变换核心是cv.distanceTransform(),输入必须为单通道二值图,DIST_L1是速度优先的选择;
  2. 归一化(cv.normalize)是距离变换后必做步骤,可统一数值范围、便于可视化;
  3. 显示时需将归一化后的float32值 ×255 转为uint8,否则无法正常展示结果。
相关推荐
sulikey1 分钟前
个人Linux操作系统学习笔记11 - 环境变量
linux·笔记·学习
小保CPP41 分钟前
OpenCV C++将多张图像合并为webp动图
c++·人工智能·opencv·计算机视觉
治愈系贝壳44 分钟前
ARM --- day 6 时钟
linux·arm开发·学习
依然范特东1 小时前
强化学习笔记2--bellman equation
人工智能·笔记
minglie11 小时前
zynq高频小数据量PS闭环的三个实验-第0课:目的和目标
学习
乐观勇敢坚强的老彭1 小时前
信奥C++一维数组笔记
开发语言·c++·笔记
昕光xg2 小时前
Istio笔记04-基于Jaeger的分布式链路追踪
笔记·分布式·istio
劈星斩月2 小时前
监督学习算法 之 决策树
学习·算法·决策树
学计算机的计算基2 小时前
操作系统内存管理全解:虚拟内存、页表、COW、malloc、OOM一篇搞定
java·笔记·算法
AOwhisky2 小时前
Python 学习笔记(第五期)——组合数据类型:列表、元组、集合与字典精讲——核心知识点自测与详解
开发语言·笔记·python·学习·云计算