转自:https://blog.csdn.net/u013921430/article/details/79770458

这个例子效果并没有给出的结果那么好,但是Hessian矩阵的生成可以参考

前言

Hessian Matrix(海森矩阵)在图像处理中有广泛的应用,比如边缘检测、特征点检测等。而海森矩阵本身也包含了大量的数学知识,例如泰勒展开、多元函数求导、矩阵、特征值等。写这篇博客的目的,就是想从原理和实现上讲一讲Hessian Matrix,肯定有不足的地方,希望大家批评指正。

泰勒展开及海森矩阵
      将一个一元函数f(x)在x0处进行泰勒展开,可以得到以下公式。

其中余项为皮亚诺余项。

其中二阶导数的部分映射到二维以及多维空间就是Hessian Matrix。在二维图像中,假设图像像素值关于坐标(x, y)的函数是f(x, y),那么将f(x+dx,y+dy)在f(x0, y0)处展开,得到如下式子

如果将这个式子用矩阵表示,并且舍去余项,则式子会是下面这个样子。

上面等式右边的第三项中的第二个矩阵就是二维空间中的海森矩阵了;从而有了一个结论,海森矩阵就是空间中一点处的二阶导数。进而推广开来,多维空间中的海森矩阵可以表示为。

海森矩阵的意义

众所周知,二阶导数表示的导数的变化规律,如果函数是一条曲线,且曲线存在二阶导数,那么二阶导数表示的是曲线的曲率,曲率越大,曲线越是弯曲。以此类推,多维空间中的一个点的二阶导数就表示该点梯度下降的快慢。以二维图像为例,一阶导数是图像灰度变化即灰度梯度,二阶导数就是灰度梯度变化程度,二阶导数越大灰度变化越不具有线性性(这里有一点绕口了,意思就是这里灰度梯度改变越大,不是线性的梯度)。

但是在二维图像中,海森矩阵是二维正定矩阵,有两个特征值和对应的两个特征向量。两个特征值表示出了图像在两个特征向量所指方向上图像变化的各向异性。如果利用特征向量与特征值构成一个椭圆,那么这个椭圆就标注出了图像变化的各向异性。那么在二维图像中,什么样的结构最具各项同性,又是什么样的结构的各向异性更强呢?很显然,圆具有最强的各项同性,线性越强的结构越具有各向异性。如下图

注:图中箭头的方向不一定正确,我只是随意标注

且特征值应该具有如下特性

λ1         λ2           图像特征

-High      -High   斑点结构(前景为亮)

+High    +High   斑点结构(前景为暗)

Low        -High   线性结构(前景为亮)

Low       +High   线性结构(前景为暗)

有一个常见的表格也把不同空间特征与特征值之间的对应关系描述的很直观

海森矩阵的应用

海森矩阵的应用很多,我在此不一一列举。上文中提到了矩阵的特征值与特征向量构成的椭圆表现出了图像的各向异性,这种各项异性图像处理就得到了应用。以二维图像为例,图像中的点性结构具有各项同性,而线性结构具有各向异性。因此我们可以利用海森矩阵对图像中的线性结构进行增强,滤去点状的结构和噪声点。同样,也可以用于找出图像中的点状结构,滤除其他信息。

当然,我们在使用海森矩阵时,不需要把图像进行泰勒展开,我们只需要直接求取矩阵中的元素即可。一般,对数字图像进行二阶求导使用的是以下方法

但是这种方法鲁棒性很差,容易受到图像中局部信号的干扰,甚至可以说,这种求导方式是存在争议的。因为这一点的二阶导数也可以采用如下方法表示;

除了上面两种表示方法外,二阶导数还可以采用其他方式表示,而且往往不同的方法求得的值不同,因为这种方法只把包含其自身在内的三个点的信息囊括进去,信息量不足。因此,提倡大家换一种方法。根据线性尺度空间理论(LOG),对一个函数求导,等于函数与高斯函数导数的卷积。式子如下

由于高斯模板可以将周围一矩形范围内所有的点的信息都包含进来,这样就不会有误差。所以利用图像求取hessian矩阵中的元素时,将图像与高斯函数的二阶导数做卷积即可。在此,为大家提供高斯函数的二阶偏导。

在编写程序时,我们只需要事先将图像分别于三个模板进行卷积,生成三种偏导数的“图”,然后每次根据需要索引对应位置的偏导数即可。

代码

需要说明的是,我在代码中运用了一些OpenCV的函数;

///---------------------------///
//---海森矩阵二维图像增强
//---潘正宇---2018.03.27#include <iostream>
#include <vector>
#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include <map>#define STEP 6
#define ABS(X) ((X)>0? X:(-(X)))
#define PI 3.1415926using namespace std;
using namespace cv;int main()
{Mat srcImage = imread("G:\\博客\\图像处理\\hessian\\hessian_matrix\\Multiscale vessel enhancement filtering1.bmp");if (srcImage.empty()){cout << "图像未被读入";system("pause");return 0;}if (srcImage.channels() != 1){cvtColor(srcImage, srcImage, CV_RGB2GRAY);}int width = srcImage.cols;int height = srcImage.rows;Mat outImage(height, width, CV_8UC1,Scalar::all(0));int W = 5;float sigma = 01;Mat xxGauKernel(2 * W + 1, 2 * W + 1, CV_32FC1, Scalar::all(0));Mat xyGauKernel(2 * W + 1, 2 * W + 1, CV_32FC1, Scalar::all(0));Mat yyGauKernel(2 * W + 1, 2 * W + 1, CV_32FC1, Scalar::all(0));//构建高斯二阶偏导数模板for (int i = -W; i <= W;i++){for (int j = -W; j <= W; j++){xxGauKernel.at<float>(i + W, j + W) = (1 - (i*i) / (sigma*sigma))*exp(-1 * (i*i + j*j) / (2 * sigma*sigma))*(-1 / (2 * PI*pow(sigma, 4)));yyGauKernel.at<float>(i + W, j + W) = (1 - (j*j) / (sigma*sigma))*exp(-1 * (i*i + j*j) / (2 * sigma*sigma))*(-1 / (2 * PI*pow(sigma, 4)));xyGauKernel.at<float>(i + W, j + W) = ((i*j))*exp(-1 * (i*i + j*j) / (2 * sigma*sigma))*(1 / (2 * PI*pow(sigma, 6)));}}for (int i = 0; i < (2 * W + 1); i++){for (int j = 0; j < (2 * W + 1); j++){cout << xxGauKernel.at<float>(i, j) << "  ";}cout << endl;}Mat xxDerivae(height, width, CV_32FC1, Scalar::all(0));Mat yyDerivae(height, width, CV_32FC1, Scalar::all(0));Mat xyDerivae(height, width, CV_32FC1, Scalar::all(0));//图像与高斯二阶偏导数模板进行卷积filter2D(srcImage, xxDerivae, xxDerivae.depth(), xxGauKernel);filter2D(srcImage, yyDerivae, yyDerivae.depth(), yyGauKernel);filter2D(srcImage, xyDerivae, xyDerivae.depth(), xyGauKernel);for (int h = 0; h < height; h++){for (int w = 0; w < width; w++){//map<int, float> best_step;/*    int HLx = h - STEP; if (HLx < 0){ HLx = 0; }int HUx = h + STEP; if (HUx >= height){ HUx = height - 1; }int WLy = w - STEP; if (WLy < 0){ WLy = 0; }int WUy = w + STEP; if (WUy >= width){ WUy = width - 1; }float fxx = srcImage.at<uchar>(h, WUy) + srcImage.at<uchar>(h, WLy) - 2 * srcImage.at<uchar>(h, w);float fyy = srcImage.at<uchar>(HLx, w) + srcImage.at<uchar>(HUx, w) - 2 * srcImage.at<uchar>(h, w);float fxy = 0.25*(srcImage.at<uchar>(HUx, WUy) + srcImage.at<uchar>(HLx, WLy) - srcImage.at<uchar>(HUx, WLy) - srcImage.at<uchar>(HLx, WUy));*/float fxx = xxDerivae.at<float>(h, w);float fyy = yyDerivae.at<float>(h, w);float fxy = xyDerivae.at<float>(h, w);float myArray[2][2] = { { fxx, fxy }, { fxy, fyy } };          //构建矩阵,求取特征值Mat Array(2, 2, CV_32FC1, myArray);Mat eValue;Mat eVector;eigen(Array, eValue, eVector);                               //矩阵是降序排列的float a1 = eValue.at<float>(0, 0);float a2 = eValue.at<float>(1, 0);if ((a1>0) && (ABS(a1)>(1+ ABS(a2))))             //根据特征向量判断线性结构{outImage.at<uchar>(h, w) =  pow((ABS(a1) - ABS(a2)), 4);//outImage.at<uchar>(h, w) = pow((ABS(a1) / ABS(a2))*(ABS(a1) - ABS(a2)), 1.5);}}}//----------做一个闭操作Mat element = getStructuringElement(MORPH_RECT, Size(3, 2));morphologyEx(outImage, outImage, MORPH_CLOSE, element);imwrite("temp.bmp", outImage);imshow("[原始图]", outImage);waitKey(0);system("pause");return 0;
}

输出结果

左侧是原图,中间是增强后的结果,右侧是将增强后的结果做了二值化的结果图;

                             

结果分析

从结果来看,图像中的大部分的线性结构都被增强了,但是有一些细微的结构并未被增强太多,而且有些粗的结构中出现了空洞,其实这都与求导窗口的大小有关,求导窗口太小,很多粗的结构会出现中空的现象,因为中心区域被认为是点结构了;求导窗口太大,就容易出现细微结构丢失的情况。此外,高斯模板的方差选取也影响了偏导数的大小。其实,这种方式是使用一个方差为s 的高斯核的二阶导数生成一个探测核,用于测量导数方向范围内(-s,s)内外区域之间的对比度。

但是同一图像中,线性结构的粗细肯定是不同的,同样的窗口大小是无法全部适用的,针对上面的问题,有人提出了多模板的方法。即对一个点用多种尺度的高斯模板进行卷积,然后选择各向异性最强的结果作为该点的输出。值得一试。

回过头来看,根据海森矩阵,还可以确定一张图像中的角点部分,即前面表格中提到的两个特征值的绝对值都较大的情况。其实这就是Harris 角点检测的主要思想。

最后
      这篇博客准备了一段时间了,主要是公式的原因,我想使用markdown编辑器以及LaTex公式编辑器编辑公式,但是没搞定,还需要琢磨一下,等我琢磨好了,就把这篇文章中的图片格式的公式换掉。

参考文献:
     Frangi A.F., Niessen W.J., Vincken K.L., Viergever M.A. (1998) Multiscale vessel enhancement filtering. In: Wells W.M., Colchester A., Delp S. (eds) Medical Image Computing and Computer-Assisted Intervention — MICCAI’98. MICCAI 1998. Lecture Notes in Computer Science, vol 1496. Springer, Berlin, Heidelberg

特征提取 - 海森矩阵(Hessian Matrix)及一个用例(图像增强)相关推荐

  1. 局部最优、梯度消失、鞍点、海森矩阵(Hessian Matric)、批梯度下降算法(btach批梯度下降法BGD、小批量梯度下降法Mini-Batch GD、随机梯度下降法SGD)

    日萌社 人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战(不定时更新) BATCH_SIZE大小设置对训练耗时的影响:1.如果当设置B ...

  2. 雅克比矩阵和海森矩阵 Jacobian and Hessian Matrix

    转:http://jacoxu.com/jacobian%E7%9F%A9%E9%98%B5%E5%92%8Chessian%E7%9F%A9%E9%98%B5/ 1. Jacobian 在向量分析中 ...

  3. 多元函数严格凹 海塞矩阵正定_海森矩阵的应用:多元函数极值的判定

    海森矩阵(Hessian Matrix),又译作黑塞矩阵.海瑟矩阵. 海塞矩阵等,是一个多元函数的二阶偏导数构成的方阵,描述 了函数的局部曲率.黑塞矩阵最早于19世纪由德国数学家 Ludwig Ott ...

  4. 雅可比矩阵 和 海森矩阵

    雅可比矩阵 假设F:Rn→Rm 是一个从欧式n维空间转换到欧式m维空间的函数.这个函数由m个实函数组成: y1(x1,...,xn), ..., ym(x1,...,xn). 这些函数的偏导数(如果存 ...

  5. matlab生成海森矩阵

    在 Matlab 中,可以使用如下代码生成海森矩阵: n = 3; % 矩阵的大小 H = eye(n) - circshift(eye(n),1,2); 这里,n 表示生成的海森矩阵的大小,而 ey ...

  6. 海森矩阵和雅克比矩阵的区别

    海森矩阵是梯度矩阵的雅克比矩阵 雅可比矩阵可以理解为: 若在n维欧式空间中的一个向量映射成m维欧式空间中的另一个向量的对应法则为F,F由m个实函数组成,即: 那么雅可比矩阵是一个m×n矩阵: 与海森矩 ...

  7. 牛顿法、雅克比矩阵、海森矩阵

    转自:https://blog.csdn.net/Yan456jie/article/details/52332043 一般来说, 牛顿法主要应用在两个方面, 1, 求方程的根; 2, 最优化. 1, ...

  8. 梯度、雅克比矩阵、海森矩阵、多元泰勒公式

      梯度向量的表达式为: [∂f∂x1∂f∂x2...∂f∂xn]=[∂f∂x1∂f∂x2..∂f∂xn]T\left[ \begin{array} { c c } {\frac {\partial{ ...

  9. 海森矩阵与多元多项式的结合与极值判定【浅显易懂版:欢迎补充】

    1.海森矩阵 2.二元泰勒展开式 3.利用海森矩阵判定多元函数的极值

最新文章

  1. PHP算法题:如何实现冒泡排序
  2. Ubuntu14.04安装redis和简单配置
  3. 【Flask】url_for函数
  4. 5.20打卡 equals()方法与“==”的区别
  5. java中Vector
  6. 实例手册_独家数据 | 1820Fall 香港研究生商科类14个热门专业 1400+申请实例汇总...
  7. 世纪大争论:Linux还是GNU/Linux?
  8. NLP数据增强方法总结:EDA、BT、MixMatch、UDA
  9. ImportError: cannot import name ‘moving_averages‘
  10. Python测试开发django5.urls.py参数name与a标签的引用
  11. Android 渗透测试学习手册 第五章 Android 取证
  12. 四边形可以分为几类_大件物流有哪些公司?大件物流公司的业务可以分为哪几类...
  13. apicloud - addEventListener 接收不到 sendEvent 的解决方法
  14. SIFT算法学习心得
  15. matlab中TCR触发,TCR+FC型SVC的研究及MATLAB仿真
  16. 学计算机的高等数学,高等数学-计算机类
  17. 以下哪些不是Linux操作系统特点,[多选] Linux操作系统具有以下()特点。
  18. 手机自动休眠与距离感应器失效的问题
  19. l/min是什么单位
  20. 红米ax6000和ax5400区别 红米ax6000和ax5400评测 哪个好

热门文章

  1. 毕业论文文献引用方法
  2. cytoscape插件下载_cytoscape五步曲之三:安装各种插件
  3. 解决前端警告: Warning: Failed prop type: Invalid prop value of type number supplied to Textinput
  4. tcp 如何维护长连接
  5. 关于SVN提交不成功问题
  6. android 脚本模拟点击屏幕
  7. Numpy:数组(Ndarray)操作之数组的转换
  8. linux基础知识总结(上)
  9. EWSTM8系列教程06_工程节点选项配置(一)
  10. 无线网络与移动IP技术