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,否则无法正常展示结果。
相关推荐
澄澈青空~15 分钟前
Unity3D VR 游戏开发 — 技术路线与学习路线完整大纲
学习·vr
sheeta19983 小时前
苍穹外卖Day05笔记
笔记
想搞艺术的程序员3 小时前
Java Survivor区学习笔记
java·笔记·学习·垃圾回收
吃杠碰小鸡3 小时前
学习英语的思路性问题
学习
不能隔夜的咖喱3 小时前
all-in-rag零散的笔记(自存/持续更新)
笔记
-Springer-3 小时前
STM32 学习 —— 个人学习笔记9-2(USART串口数据包 & 串口收发 HEX 及 文本 数据包)
笔记·stm32·学习
celeste03103 小时前
Redis Summary
linux·运维·服务器·redis·笔记
会编程的李较瘦3 小时前
【C语言程序设计学习】一、C语法基础
c语言·开发语言·学习
zzh0813 小时前
nginx安全笔记
笔记·nginx·安全
困死,根本不会3 小时前
【C 语言】指针学习笔记:从底层原理到实战应用
c语言·开发语言·笔记·学习·算法