【主动轮廓模型(二)】《GVF Snake》算法原理与OpenCV实现

article/2025/11/7 14:59:16

文章目录

  • 1 问题引入
    • 1.1 传统Snake模型的缺陷
    • 1.2 亥姆霍兹定理(Helmholtz theorem)
  • 2 GVF Snake
    • 2.1 边缘图(Edge Map)
    • 2.2 梯度矢量流(Gradient Vector Flow,GVF)
    • 2.3 数值求解方法
  • 3 OpenCV实现


1 问题引入

1.1 传统Snake模型的缺陷

传统的Snake算法(参考博客)存在以下两个主要缺陷,在《Snakes, Shapes, and Gradient Vector Flow》这篇文章中提出的GVF Snake模型解决了这两个问题:

  1. 初始轮廓必须在真实轮廓附近,或对初始位置敏感;
  2. 很难进入凹陷的边界。

在这里插入图片描述

如图1所示,文章中作者用一个U形轮廓作为示例来直观解释传统Snake的缺陷。在图(c)中可以看到,U形轮廓凹陷处的力达到了左右平衡即方向相反大小相同,无法使轮廓再继续向凹陷处移动。

我们知道,Snake算法的解就是将轮廓点移动到某个确定位置,使得以下等式成立:

F i n t + F e x t ( g ) = 0 (1) F_{int} + F_{ext}^{(g)} = 0 \tag{1} Fint+Fext(g)=0(1)

其中外部力 F e x t ( g ) F_{ext}^{(g)} Fext(g)的选取对于Snake模型的表现有巨大影响,外部力又可以被分为两种:静态(static)和动态(dynamic)。其中静态力从图像数据计算并且不随模型的更新改变,动态力是随着模型更新而改变的力。传统的Snake模型外部力就是一种静态力,GVF Snake中所描述的外部力也是一种静态力,它不会随时间变化或依赖于Snake模型轮廓的位置

1.2 亥姆霍兹定理(Helmholtz theorem)

GVF Snake中所描述外部力的数学原理来自于亥姆霍兹定理,即最一般的静态向量场可以被分解为两个分量:无旋(无旋度)分量和无散(无散度)分量

由于传统Snake模型的变分公式长生的外力是势函数的梯度,因此它必须作为静态无旋场加入力平衡方程(公式(1))。因此,可以通过允许包括无旋分量和无散分量来获得更一般的静态场。文章中,设计了一个外力场,使其具有大的捕获范围的同时又具有指向边界凹陷的力。

2 GVF Snake

GVF Snake中定义 F e x t ( g ) = v ( x , y ) F_{ext}^{(g)}=\mathbf{v}(x,y) Fext(g)=v(x,y),仅这里与传统的Snake不同,称为梯度矢量流(Gradient Vector Flow,GVF)

x t ( s , t ) = α x ′ ′ ( s , t ) − β x ′ ′ ′ ′ ( s , t ) + v (2) x_t(s,t)=\alpha x^{''}(s,t)-\beta x^{''''}(s,t)+\mathbf{v} \tag{2} xt(s,t)=αx′′(s,t)βx′′′′(s,t)+v(2)

求解上述方程的参数曲线即为GVF Snake,求解方式与传统的Snake相同。由于 v ( x , y ) \mathbf{v}(x,y) v(x,y)通常不是一个无旋场,因此该方程通常不表示(1)中的能量最小化问题的欧拉方程。

2.1 边缘图(Edge Map)

方法很多,比如可以用:

f ( x , y ) = − E e x t ( i ) ( x , y ) (3) f(x,y)=-E_{ext}^{(i)}(x,y) \tag{3} f(x,y)=Eext(i)(x,y)(3)

2.2 梯度矢量流(Gradient Vector Flow,GVF)

定义GVF为使以下能量函数最小化的矢量场 v ( x , y ) = [ u ( x , y ) , v ( x , y ) ] \mathbf{v}(x,y)=[u(x,y),v(x,y)] v(x,y)=[u(x,y),v(x,y)]

ε = ∫ ∫ μ ( u x 2 + u y 2 + v x 2 + v y 2 ) + ∣ ∇ f ∣ 2 ∣ v − ∇ f ∣ 2 d x d y (4) \varepsilon = \int \int \mu (u_x^2+u_y^2+v_x^2+v_y^2)+| \nabla f |^2| \mathbf{v} - \nabla f |^2 dxdy \tag{4} ε=∫∫μ(ux2+uy2+vx2+vy2)+∣∇f2vf2dxdy(4)

其中, ∇ f = [ f x , f y ] \nabla f=[f_x,f_y] f=[fx,fy],表示边缘图像(edge map)的梯度,任何图像梯度算子都可以被用来计算这个变量。 u x / u y u_x/u_y ux/uy v x / v y v_x/v_y vx/vy为GVF得到的梯度场在 ( x , y ) (x,y) (x,y)位置上 x x x y y y方向上的梯度值,由拉普拉斯方程计算得到,且其初始值定义为 ∇ f \nabla f f,即原图像的二阶导。可以看到:

  • ∇ f \nabla f f很小时,能量由矢量场偏导数的平方和决定,从而产生一个缓慢变化的场;
  • ∇ f \nabla f f很大时,第二项占被积函数的主导地位,通过设置 v = ∇ f \mathbf{v}=\nabla f v=f可将其最小化,这可以再边缘图较大时保持几乎等于边缘图的梯度,而在均匀区域中缓慢变化。

参数 μ \mu μ是控制被积函数中第一项和第二项之间权衡的正则化参数,应根据图像中存在的噪声量来设置(噪声越大 μ \mu μ应越大)。可以预期由此最小化产生的矢量场既不是完全无旋场也不是完全无散场。可以通过求解以下欧拉方程来求解GVF场(公式(4)):

{ μ ∇ 2 u − ( u − f x ) ( f x 2 + f y 2 ) = 0 μ ∇ 2 v − ( v − f y ) ( f x 2 + f y 2 ) = 0 (5) \begin{cases} \mu \nabla ^2 u - (u-f_x)(f_x^2+f_y^2) = 0 \\ \mu \nabla ^2 v - (v-f_y)(f_x^2+f_y^2) = 0 \end{cases} \tag{5} {μ2u(ufx)(fx2+fy2)=0μ2v(vfy)(fx2+fy2)=0(5)

其中 ∇ 2 \nabla ^2 2为拉普拉斯算子。

2.3 数值求解方法

u u u v v v看作时间的函数,可以将公示(5)(对应原文中公式(13a)、(13b))转化为:

{ u t ( x , y , t ) = μ ∇ 2 u ( x , y , t ) − [ u ( x , y , t ) − f x ( x , y ) ] ⋅ [ f x ( x , y ) 2 + f y ( x , y ) 2 ] v t ( x , y , t ) = μ ∇ 2 v ( x , y , t ) − [ v ( x , y , t ) − f y ( x , y ) ] ⋅ [ f x ( x , y ) 2 + f y ( x , y ) 2 ] (6) \begin{cases} u_t(x,y,t)=\mu \nabla^2 u(x,y,t)-[u(x,y,t)-f_x(x,y)]\cdot[f_x(x,y)^2+f_y(x,y)^2] \\ v_t(x,y,t)=\mu \nabla^2 v(x,y,t)-[v(x,y,t)-f_y(x,y)]\cdot[f_x(x,y)^2+f_y(x,y)^2] \end{cases} \tag{6} {ut(x,y,t)=μ2u(x,y,t)[u(x,y,t)fx(x,y)][fx(x,y)2+fy(x,y)2]vt(x,y,t)=μ2v(x,y,t)[v(x,y,t)fy(x,y)][fx(x,y)2+fy(x,y)2](6)

上式进一步简化:

{ u t ( x , y , t ) = μ ∇ 2 u ( x , y , t ) − b ( x , y ) u ( x , y , t ) + c 1 ( x , y ) v t ( x , y , t ) = μ ∇ 2 v ( x , y , t ) − b ( x , y ) v ( x , y , t ) + c 2 ( x , y ) (7) \begin{cases} u_t(x,y,t)=\mu \nabla^2 u(x,y,t)-b(x,y)u(x,y,t)+c^1(x,y) \\ v_t(x,y,t)=\mu \nabla^2 v(x,y,t)-b(x,y)v(x,y,t)+c^2(x,y) \end{cases} \tag{7} {ut(x,y,t)=μ2u(x,y,t)b(x,y)u(x,y,t)+c1(x,y)vt(x,y,t)=μ2v(x,y,t)b(x,y)v(x,y,t)+c2(x,y)(7)

其中,

{ b ( x , y ) = f x ( x , y ) 2 + f y ( x , y ) 2 c 1 ( x , y ) = b ( x , y ) f x ( x , y ) c 2 ( x , y ) = b ( x , y ) f y ( x , y ) (8) \begin{cases} b(x,y)=f_x(x,y)^2+f_y(x,y)^2 \\ c^1(x,y)=b(x,y)f_x(x,y) \\ c^2(x,y)=b(x,y)f_y(x,y) \end{cases} \tag{8} b(x,y)=fx(x,y)2+fy(x,y)2c1(x,y)=b(x,y)fx(x,y)c2(x,y)=b(x,y)fy(x,y)(8)

公式(7)中的系数 b ( x , y ) b(x,y) b(x,y) c 1 ( x , y ) c^1(x,y) c1(x,y) c 2 ( x , y ) c^2(x,y) c2(x,y)在整个迭代过程中是固定的,只需要计算一次。为方便计算,作以下假设:

{ i , j , n : 对应 x 、 y 、 t Δ x 、 Δ y : 像素间隔 s p a c i n g Δ t : 每次迭代的时间间隔 \begin{cases} i,j,n: 对应x、y、t \\ \Delta x、\Delta y: 像素间隔spacing \\ \Delta t: 每次迭代的时间间隔 \end{cases} i,j,n:对应xytΔxΔy:像素间隔spacingΔt:每次迭代的时间间隔

则每次迭代的偏微分方程可以写为:

{ u t = 1 Δ t ( u i , j n + 1 − u i , j n ) v t = 1 Δ t ( v i , j n + 1 − v i , j n ) ∇ 2 u = 1 Δ x Δ y ( u i + 1 , j + u i , j + 1 + u i − 1 , j + u i , j − 1 − 4 u i , j ) ∇ 2 v = 1 Δ x Δ y ( v i + 1 , j + v i , j + 1 + v i − 1 , j + v i , j − 1 − 4 v i , j ) (9) \begin{cases} u_t=\frac{1}{\Delta t} (u_{i,j}^{n+1} - u_{i,j}^n) \\ v_t=\frac{1}{\Delta t} (v_{i,j}^{n+1} - v_{i,j}^n) \\ \nabla^2u = \frac{1}{\Delta x \Delta y}(u_{i+1,j}+u_{i,j+1}+u_{i-1,j}+u_{i,j-1}-4u_{i,j}) \\ \nabla^2v = \frac{1}{\Delta x \Delta y}(v_{i+1,j}+v_{i,j+1}+v_{i-1,j}+v_{i,j-1}-4v_{i,j}) \end{cases} \tag{9} ut=Δt1(ui,jn+1ui,jn)vt=Δt1(vi,jn+1vi,jn)2u=ΔxΔy1(ui+1,j+ui,j+1+ui1,j+ui,j14ui,j)2v=ΔxΔy1(vi+1,j+vi,j+1+vi1,j+vi,j14vi,j)(9)

将这些近似值带入公式(7)可以得出GVF的迭代解:

{ u i , j n + 1 = ( 1 − b i , j Δ t ) u i , j n + r ( u i + 1 n + u i , j + 1 n + u i − 1 , j n + u i , j − 1 n − 4 u i , j n ) + c i , j 1 Δ t v i , j n + 1 = ( 1 − b i , j Δ t ) v i , j n + r ( v i + 1 n + v i , j + 1 n + v i − 1 , j n + v i , j − 1 n − 4 v i , j n ) + c i , j 2 Δ t (10) \begin{cases} u_{i,j}^{n+1}=(1-b_{i,j}\Delta t)u_{i,j}^n+r(u_{i+1}^n+u_{i,j+1}^n+u_{i-1,j}^n+u_{i,j-1}^n-4u_{i,j}^n)+c_{i,j}^1 \Delta t \\ v_{i,j}^{n+1}=(1-b_{i,j}\Delta t)v_{i,j}^n+r(v_{i+1}^n+v_{i,j+1}^n+v_{i-1,j}^n+v_{i,j-1}^n-4v_{i,j}^n)+c_{i,j}^2 \Delta t \end{cases} \tag{10} {ui,jn+1=(1bi,jΔt)ui,jn+r(ui+1n+ui,j+1n+ui1,jn+ui,j1n4ui,jn)+ci,j1Δtvi,jn+1=(1bi,jΔt)vi,jn+r(vi+1n+vi,j+1n+vi1,jn+vi,j1n4vi,jn)+ci,j2Δt(10)

其中:

r = μ Δ t Δ x Δ y (11) r=\frac{\mu \Delta t}{\Delta x \Delta y} \tag{11} r=ΔxΔyμΔt(11)

为了保证收敛,必须确保 Δ t ≤ Δ x Δ y 4 μ \Delta t \leq \frac{\Delta x \Delta y}{4\mu} Δt4μΔxΔy

3 OpenCV实现

这里给出作为外力的梯度矢量流(GVF)的OpenCV实现。

std::vector<cv::Mat> GVFSnake::GVF(cv::Mat edgeImg, double mu, int iterNum)
{cv::Mat fImg = edgeImg.clone();fImg.convertTo(fImg, CV_32FC1);// a.Calculate the gradient of the edge mapqDebug() << "Calculate the gradient of the edge map";cv::Mat fx, fy;cv::Sobel(fImg, fx, fImg.depth(), 1, 0, 1, 0.5, 0, cv::BORDER_CONSTANT); // fImg must be CV_32FC1 formatcv::Sobel(fImg, fy, fImg.depth(), 0, 1, 1, 0.5, 0, cv::BORDER_CONSTANT);// b.Squared magnitude of the gradient fieldqDebug() << "Squared magnitude of the gradient field";cv::Mat SqrMagf = fx.mul(fx) + fy.mul(fy);// c.Initialize GVF to the gradientqDebug() << "Initialize GVF to the gradient";cv::Mat u = fx.clone();cv::Mat v = fy.clone();// d.Iteratively solve for the GVF u,vqDebug() << "Iteratively solve for the GVF u,v";for (int i = 0; i < iterNum; i++){// equal to del2 in matlabcv::Mat mKernal = (cv::Mat_<float>(3, 3) << 0, 1 / 4, 0,1 / 4, -1, 1 / 4,0, 1 / 4, 0);cv::Mat uLap, vLap;cv::filter2D(u, uLap, u.depth(), mKernal);cv::filter2D(v, vLap, v.depth(), mKernal);// why *4 ? ref: https://blog.csdn.net/qq_41634276/article/details/80659218u += mu * 4 * uLap - SqrMagf.mul(u - fx);v += mu * 4 * vLap - SqrMagf.mul(v - fy);}std::vector<cv::Mat> uvMatVector;uvMatVector.push_back(u);uvMatVector.push_back(v);return uvMatVector;
}

http://chatgpt.dhexx.cn/article/EIJjlwmX.shtml

相关文章

用于实时实例分割的Deep Snake算法

第一部分&#xff1a;创新及其优点 第二部分&#xff1a;算法原理 第三部分&#xff1a;实验过程 第四部分&#xff1a;程序逻辑 1 创新及其优点 Deep Snake算法建立在传统Snake算法的基础上&#xff0c;将snake算法做成了轮廓结构化特征学习的方法&#xff0c;使用了循环卷积…

KMeans 算法(一)

K-means算法简述 K-means算法&#xff0c;也称为K-平均或者K-均值&#xff0c;一般作为掌握聚类算法的第一个算法。这里的K为常数&#xff0c;需事先设定&#xff0c;通俗地说该算法是将没有标注的 M 个样本通过迭代的方式聚集成K个簇。在对样本进行聚集的过程往往是以样本之间…

选择性搜索算法(Selective Search )——SS算法

文章目录 一、前言二、object Detection VS object Recognition&#xff08;Selective Search的提出&#xff09;2.1object recognition与object detection的关系2.2滑动窗口方法的局限性2.3Selective search算法的提出 三、Selective Search算法3.1什么是Selective Search&…

主动轮廓模型——Snake分割算法(MATLAB)

学习图像分割算法&#xff0c;在网上找到的关于主动轮廓模型的实现代码&#xff0c;自己简化总结了一下&#xff0c;在这里和大家分享&#xff0c;欢迎提问 snake是一种能量最小的曲线&#xff0c;表示为v(s) (x(s), y(s)), s为归一化的曲线长度&#xff0c;s∈[0, 1]。 能量…

麻雀搜索算法(Sparrow Search Algorithm,SSA)

文章目录 1 算法思想2 算法步骤3 求解函数最值&#xff08;Python实现&#xff09;4 算法进阶直接改进SSA融合别的智能优化算法来改进SSASMA及其改进的应用 原论文&#xff1a; [1]薛建凯. 一种新型的群智能优化技术的研究与应用[D].东华大学,2020. 1 算法思想 借鉴生物行为&a…

CVPR2020分割算法Deep Snake的配置(Deep Snake for Real-Time Instance Segmentation)

这篇文章为分割提供了新思路&#xff0c;很有参考意义。 注&#xff1a;原代码的运行环境为Ubuntu&#xff0c;本文在Windows10系统下完成配置。 1、论文下载&#xff1a; Deep Snake for Real-Time Instance Segmentation [paper][code] 2、代码下载&#xff1a; https:/…

图像分割之(五)活动轮廓模型之Snake模型简介

图像分割之&#xff08;五&#xff09;活动轮廓模型之Snake模型简介 zouxy09qq.com http://blog.csdn.net/zouxy09 在“图像分割之&#xff08;一&#xff09;概述”中咱们简单了解了目前主流的图像分割方法。下面咱们主要学习下基于能量泛函的分割方法。这里学习下Snake模型…

麻雀搜索算法SSA(Sparrow Search algorithm)

文章目录 前言数学模型 前言 麻雀搜索算法是2020提出的一种新的优化算法&#xff0c;出自东华大学xue和shen的论文&#xff1a;A novel swarm intelligence optimization approach: sparrow search algorithm&#xff0c;本文的内容是基于该论文来写的。 数学模型 麻雀搜索算…

snake 模型

转自&#xff1a;https://blog.csdn.net/caoniyadeniniang/article/details/77803002 一、曲线演化理论 假设CC(p)是一条光滑封闭的曲线&#xff0c;P是任意的参数化变量&#xff0c;设K表示曲 率&#xff0c;T表示切线&#xff0c;N表示法线&#xff0c;则有如下关系存在&…

蛇优化算法(Snake Optimization,SO)(附Matlab代码,完整,免费)

蛇优化算法&#xff08;Snake Optimization&#xff0c;SO&#xff09;&#xff08;附Matlab代码&#xff0c;完整&#xff0c;免费&#xff09; 一、算法灵感二、算法介绍2.1 初始化2.2 划分种群2.3 定义温度和食物2.4 食物不足时(探索阶段)2.5 食物充足时(开发阶段)2.5.1 斗争…

snake模型求解

&#xfeff;&#xfeff; snake 模型 一、曲线演化理论 假设CC(p)是一条光滑封闭的曲线&#xff0c;P是任意的参数化变量&#xff0c;设K表示曲 率&#xff0c;T表示切线&#xff0c;N表示法线&#xff0c;则有如下关系存在&#xff1a; 因为T和N是互相垂直的(如图所示)&am…

snake模型

1 能量泛函 在介绍snake模型的参考资料[1]中&#xff0c;提到能量泛函的概念&#xff0c;这里对此概念做一个总结。 参考资料[6]给出了泛函的定义&#xff1a; 简单的说&#xff0c; 泛函就是定义域是一个函数集&#xff0c;而值域是实数集或者实数集的一个子集。推广开来&…

Snake算法知识点记录

Snake算法 snake是一种主动轮廓模型&#xff0c;主动轮廓模型目前用到了2种&#xff1a;CV和snake。snake在逐步迭代优化过程的目标是能量函数最小化&#xff0c;snake的目标不像sobel、canny等找到整张图的轮廓。它只搜索你给出的初始轮廓附近&#xff0c;达到轮廓更精确的目…

snake模型简介

图像分割之&#xff08;五&#xff09;活动轮廓模型之Snake模型简介 zouxy09qq.com http://blog.csdn.net/zouxy09 在“图像分割之&#xff08;一&#xff09;概述”中咱们简单了解了目前主流的图像分割方法。下面咱们主要学习下基于能量泛函的分割方法。这里学习下Snake模型简…

蛇优化算法(Snake Optimizer)

生物学机理&#xff1a;来源于蛇的交配行为。如果温度较低&#xff0c;且食物可用&#xff0c;蛇的交配行为发生&#xff1b;否则蛇只会寻找食物&#xff08;食物量<0.25&#xff09;或吃现有的食物(T>0.6)。基于此&#xff0c;将考虑蛇优化算法的搜索过程分为两个阶段&a…

图像处理之图像分割(一)之活动轮廓模型:Snake算法简单梳理

图像处理之图像分割&#xff08;一&#xff09;之活动轮廓模型&#xff1a;Snake算法简单梳理 Snake算法&#xff0c;应该也可以翻译成蛇形算法&#xff0c;或者是包含曲折前进的意思。具体函数背景原理介绍参考&#xff1a;zouxy09&#xff0c;http://blog.csdn.net/zouxy09/a…

snake算法总结

snake是一种主动轮廓模型&#xff0c;笨妞对主动轮廓模型的理解&#xff1a;你先给它一个初始轮廓&#xff0c;模型以初始轮廓为基准逐步迭代&#xff0c;来改进图像的轮廓&#xff0c;使其更加精确。主动轮廓模型目前用到了2种&#xff1a;CV和snake。前者没有看算法内部的原理…

主动轮廓模型:Snake模型的python实现

质量声明&#xff1a;原创文章&#xff0c;内容质量问题请评论吐槽。如对您产生干扰&#xff0c;可私信删除。 主要参考&#xff1a;Active Contour Model — skimage v0.16.dev0 docs - scikit-image 文章目录 skimage实现函数声明代码示例结果显示 Numpy实现代码示例结果显示…

社交网络分析--python-igraph

#coding:utf-8 import scrapy import xlwt, lxml import re, json import matplotlib.pyplot as plt import numpy as np import pylab from scipy import linalg #文档&#xff1a;igraph.org/python/doc/ #社交网络分析 #from igraph import *社交网络算法介绍 分析-权利的游…

(一文读懂社交网络分析(附应用、前沿、学习资源)学习笔记)

一文读懂社交网络分析&#xff08;附应用、前沿、学习资源&#xff09;学习笔记 一、社交网络的结构特性与演化机理1、社交网络结构分析与建模1.1 统计特性1.2 网络特性1.3 网络模型 2、虚拟社区以及发现技术2.1 定义2.2 社区发现算法评估指标2.3社区静态发现算法2.4 社区动态发…