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,否则无法正常展示结果。
相关推荐
生信碱移11 分钟前
PACells:这个方法可以鉴定疾病/预后相关的重要细胞亚群,作者提供的代码流程可以学习起来了,甚至兼容转录组与 ATAC 两种数据类型!
人工智能·学习·算法·机器学习·数据挖掘·数据分析·r语言
智者知已应修善业31 分钟前
【51单片机中的打飞机设计】2023-8-25
c++·经验分享·笔记·算法·51单片机
星幻元宇VR2 小时前
VR航空航天科普设备【VR时空直升机】
科技·学习·安全·生活·vr
_李小白2 小时前
【android opencv学习笔记】Day 2: Mat类(图片数据结构体)
android·opencv·学习
智者知已应修善业3 小时前
【51单片机按键调节占空比3位数码管显示】2023-8-24
c++·经验分享·笔记·算法·51单片机
JasmineX-13 小时前
数据结构(笔记)——双向链表
c语言·数据结构·笔记·链表
harder3213 小时前
RMP模式的创新突破
开发语言·学习·ios·swift·策略模式
程序猿乐锅4 小时前
【Tilas|第三篇】多表SQL语句
数据库·经验分享·笔记·学习·mysql
徐某人..4 小时前
基于i.MX6ULL平台的智能网关系统开发
arm开发·c++·单片机·qt·物联网·学习·arm
AOwhisky5 小时前
Kubernetes 学习笔记:集群管理、命名空间与 Pod 基础
linux·运维·笔记·学习·云原生·kubernetes