图像处理矩阵确定中心

2016-02-20 15:27:24 samkieth 阅读数 904
  • (二)矩阵基本运算

    本课程由专业数学系老师讲解,从数学背景和现实应用中讲解线性代数的相关知识,摆脱传统...使听众能够了解矩阵和空间的概念、性质。深刻理解矩阵各类运算、分解的数学意义和应用,为后续的机器学习打下扎实的数学基础。

    825人学习 AI100讲师
    免费试看

我们尝试用矩阵表示一个图像,在一段程序中,出现了有趣的现象:

// imgproc.cpp : 定义控制台应用程序的入口点。
//
//#include "stdafx.h"
#include "iostream"
#include "opencv2\opencv.hpp"
#include "opencv2/highgui/highgui.hpp"
using namespace std;
using namespace cv;

int main(int argc, int ** argv[])
{
	//////////////////////////////////////////////////////////////////////////
	Mat img1=imread("yu.jpg");  //9*8
	namedWindow("demo");
	imshow("demo",img1);
	int i,j;
	cout<<"ptr方法"<<endl;
	cout<<"-----------------------------------------------"<<endl;
	for(j=0;j<img1.rows;j++)
	{
		uchar * data=img1.ptr<uchar>(j);//得到行指针(储存行数据的地址)
		for (i=0;i<img1.cols*img1.channels();i++)//行数据的长度为 列数*通道数
		{
			//仿照方式格式打印出来
			cout<<(int)data[i];////b通道
			i++;
			cout<<(int)data[i];//g通道
			i++;
			cout<<(int)data[i];//r通道
			cout<<"\t";


		}
		cout<<endl;
	}
	cout<<"-----------------------------------------------"<<endl;
	waitKey(0);
	return 0;	
}
结果是:

以及最终出现的结果是:




2018-04-01 09:56:30 u013921430 阅读数 13137
  • (二)矩阵基本运算

    本课程由专业数学系老师讲解,从数学背景和现实应用中讲解线性代数的相关知识,摆脱传统...使听众能够了解矩阵和空间的概念、性质。深刻理解矩阵各类运算、分解的数学意义和应用,为后续的机器学习打下扎实的数学基础。

    825人学习 AI100讲师
    免费试看

 

fishing-panhttps://blog.csdn.net/u013921430转载请注明出处】

前言

       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.1415926

using 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 = 0.1;
	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

      

 

2018-07-12 17:49:37 dfdfdsfdfdfdf 阅读数 5807
  • (二)矩阵基本运算

    本课程由专业数学系老师讲解,从数学背景和现实应用中讲解线性代数的相关知识,摆脱传统...使听众能够了解矩阵和空间的概念、性质。深刻理解矩阵各类运算、分解的数学意义和应用,为后续的机器学习打下扎实的数学基础。

    825人学习 AI100讲师
    免费试看

fishing-panhttps://blog.csdn.net/u013921430转载请注明出处】

前言

       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的函数;

  1. ///---------------------------///
  2. //---海森矩阵二维图像增强
  3. //---潘正宇---2018.03.27
  4. #include <iostream>
  5. #include <vector>
  6. #include<opencv2/opencv.hpp>
  7. #include<opencv2/highgui/highgui.hpp>
  8. #include<opencv2/imgproc/imgproc.hpp>
  9. #include <map>
  10. #define STEP 6
  11. #define ABS(X) ((X)>0? X:(-(X)))
  12. #define PI 3.1415926
  13. using namespace std;
  14. using namespace cv;
  15. int main()
  16. {
  17. Mat srcImage = imread("G:\\博客\\图像处理\\hessian\\hessian_matrix\\Multiscale vessel enhancement filtering1.bmp");
  18. if (srcImage.empty())
  19. {
  20. cout << "图像未被读入";
  21. system("pause");
  22. return 0;
  23. }
  24. if (srcImage.channels() != 1)
  25. {
  26. cvtColor(srcImage, srcImage, CV_RGB2GRAY);
  27. }
  28. int width = srcImage.cols;
  29. int height = srcImage.rows;
  30. Mat outImage(height, width, CV_8UC1,Scalar::all(0));
  31. int W = 5;
  32. float sigma = 01;
  33. Mat xxGauKernel(2 * W + 1, 2 * W + 1, CV_32FC1, Scalar::all(0));
  34. Mat xyGauKernel(2 * W + 1, 2 * W + 1, CV_32FC1, Scalar::all(0));
  35. Mat yyGauKernel(2 * W + 1, 2 * W + 1, CV_32FC1, Scalar::all(0));
  36. //构建高斯二阶偏导数模板
  37. for (int i = -W; i <= W;i++)
  38. {
  39. for (int j = -W; j <= W; j++)
  40. {
  41. 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)));
  42. 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)));
  43. xyGauKernel.at<float>(i + W, j + W) = ((i*j))*exp(-1 * (i*i + j*j) / (2 * sigma*sigma))*(1 / (2 * PI*pow(sigma, 6)));
  44. }
  45. }
  46. for (int i = 0; i < (2 * W + 1); i++)
  47. {
  48. for (int j = 0; j < (2 * W + 1); j++)
  49. {
  50. cout << xxGauKernel.at<float>(i, j) << " ";
  51. }
  52. cout << endl;
  53. }
  54. Mat xxDerivae(height, width, CV_32FC1, Scalar::all(0));
  55. Mat yyDerivae(height, width, CV_32FC1, Scalar::all(0));
  56. Mat xyDerivae(height, width, CV_32FC1, Scalar::all(0));
  57. //图像与高斯二阶偏导数模板进行卷积
  58. filter2D(srcImage, xxDerivae, xxDerivae.depth(), xxGauKernel);
  59. filter2D(srcImage, yyDerivae, yyDerivae.depth(), yyGauKernel);
  60. filter2D(srcImage, xyDerivae, xyDerivae.depth(), xyGauKernel);
  61. for (int h = 0; h < height; h++)
  62. {
  63. for (int w = 0; w < width; w++)
  64. {
  65. //map<int, float> best_step;
  66. /* int HLx = h - STEP; if (HLx < 0){ HLx = 0; }
  67. int HUx = h + STEP; if (HUx >= height){ HUx = height - 1; }
  68. int WLy = w - STEP; if (WLy < 0){ WLy = 0; }
  69. int WUy = w + STEP; if (WUy >= width){ WUy = width - 1; }
  70. float fxx = srcImage.at<uchar>(h, WUy) + srcImage.at<uchar>(h, WLy) - 2 * srcImage.at<uchar>(h, w);
  71. float fyy = srcImage.at<uchar>(HLx, w) + srcImage.at<uchar>(HUx, w) - 2 * srcImage.at<uchar>(h, w);
  72. float fxy = 0.25*(srcImage.at<uchar>(HUx, WUy) + srcImage.at<uchar>(HLx, WLy) - srcImage.at<uchar>(HUx, WLy) - srcImage.at<uchar>(HLx, WUy));*/
  73. float fxx = xxDerivae.at<float>(h, w);
  74. float fyy = yyDerivae.at<float>(h, w);
  75. float fxy = xyDerivae.at<float>(h, w);
  76. float myArray[2][2] = { { fxx, fxy }, { fxy, fyy } }; //构建矩阵,求取特征值
  77. Mat Array(2, 2, CV_32FC1, myArray);
  78. Mat eValue;
  79. Mat eVector;
  80. eigen(Array, eValue, eVector); //矩阵是降序排列的
  81. float a1 = eValue.at<float>(0, 0);
  82. float a2 = eValue.at<float>(1, 0);
  83. if ((a1>0) && (ABS(a1)>(1+ ABS(a2)))) //根据特征向量判断线性结构
  84. {
  85. outImage.at<uchar>(h, w) = pow((ABS(a1) - ABS(a2)), 4);
  86. //outImage.at<uchar>(h, w) = pow((ABS(a1) / ABS(a2))*(ABS(a1) - ABS(a2)), 1.5);
  87. }
  88. }
  89. }
  90. //----------做一个闭操作
  91. Mat element = getStructuringElement(MORPH_RECT, Size(3, 2));
  92. morphologyEx(outImage, outImage, MORPH_CLOSE, element);
  93. imwrite("temp.bmp", outImage);
  94. imshow("[原始图]", outImage);
  95. waitKey(0);
  96. system("pause");
  97. return 0;
  98. }

输出结果

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

                                        

结果分析

      从结果来看,图像中的大部分的线性结构都被增强了,但是有一些细微的结构并未被增强太多,而且有些粗的结构中出现了空洞,其实这都与求导窗口的大小有关,求导窗口太小,很多粗的结构会出现中空的现象,因为中心区域被认为是点结构了;求导窗口太大,就容易出现细微结构丢失的情况。此外,高斯模板的方差选取也影响了偏导数的大小。其实,这种方式是使用一个方差为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

2016-04-21 20:44:32 yangdashi888 阅读数 2784
  • (二)矩阵基本运算

    本课程由专业数学系老师讲解,从数学背景和现实应用中讲解线性代数的相关知识,摆脱传统...使听众能够了解矩阵和空间的概念、性质。深刻理解矩阵各类运算、分解的数学意义和应用,为后续的机器学习打下扎实的数学基础。

    825人学习 AI100讲师
    免费试看

6.5 矩阵的运算及其运算规则

一、矩阵的加法与减法


  1、运算规则
  设矩阵
  则
     
  简言之,两个矩阵相加减,即它们相同位置的元素相加减!
  注意:只有对于两个行数、列数分别相等的矩阵(即同型矩阵),加减法运算才有意义,即加减运算是可行的.

  2、 运算性质 (假设运算都是可行的)
  满足交换律和结合律
  交换律 
  结合律 

二、矩阵与数的乘法


  1、 运算规则
  乘矩阵A,就是将数乘矩阵A中的每一个元素,记为
  特别地,称称为的负矩阵.
  2、 运算性质
  满足结合律和分配律
  结合律: (λμ)A=λ(μA) ; (λ+μ)A =λA+μA
  分配律: λ (A+B)=λA+λB

  典型例题
  例6.5.1 已知两个矩阵
  满足矩阵方程,求未知矩阵
   由已知条件知
    
    

三、矩阵与矩阵的乘法


  1、 运算规则
  设,则A与B的乘积是这样一个矩阵:
  (1) 行数与(左矩阵)A相同,列数与(右矩阵)B相同,即
  (2) C的第行第列的元素由A的第行元素与B的第列元素对应相乘,再取乘积之和.

  典型例题
  例6.5.2 设矩阵
  计算
   的矩阵.设它为
    

    
  想一想:设列矩阵,行矩阵的行数和列数分别是多少呢
  是3×3的矩阵,是1×1的矩阵,即只有一个元素.

  课堂练习
  1、设,求
  2、在第1道练习题中,两个矩阵相乘的顺序是A在左边,B在右边,称为A左乘B或B右乘A.如果交换顺序,让B在左边,A在右边,即A右乘B,运算还能进行吗?请算算试试看.并由此思考:两个矩阵应当满足什么条件,才能够做乘法运算.
  3、设列矩阵,行矩阵,求,比较两个计算结果,能得出什么结论吗?
  4、设三阶方阵,三阶单位阵为,试求,并将计算结果与A比较,看有什么样的结论.

  解:
  第1题
  第2题
  对于
  求是有意义的,而是无意义的.

  结论1 只有在下列情况下,两个矩阵的乘法才有意义,或说乘法运算是可行的:左矩阵的列数=右矩阵的行数.
  第3题
  矩阵,的矩阵.
         
           
    结论2 在矩阵的乘法中,必须注意相乘的顺序.即使在均有意义时,也未必有=成立.可见矩阵乘法不满足交换律.
  第4题
  计算得:
  结论3 方阵A和它同阶的单位阵作乘积,结果仍为A,即
  单位阵在矩阵乘法中的作用相当于数1在我们普通乘法中的作用.

  典型例题
  例6.5.3 设,试计算
   
      
      
    
      
      
    结论4 两个非零矩阵的乘积可以是零矩阵.由此若,不能得出的结论.

  例6.5.4 利用矩阵的乘法,三元线性方程组
  可以写成矩阵的形式
  若记系数、未知量和常数项构成的三个矩阵分别为
  则线性方程组又可以简写为矩阵方程的形式:

  2、 运算性质(假设运算都是可行的)
  (1) 结合律 
  (2) 分配律 (左分配律);
         (右分配律).
  (3) 
   3、 方阵的幂
 
定义:设A是方阵,是一个正整数,规定
显然,记号表示个A的连乘积.

四、矩阵的转置


  1、 定义
 
定义:将矩阵A的行换成同序号的列所得到的新矩阵称为矩阵A的转置矩阵,记作
  例如,矩阵的转置矩阵为
  2、运算性质(假设运算都是可行的)
  (1) 
  (2) 
  (3) 
  (4) 是常数.

  典型例题
  例6.5.5  利用矩阵
  验证运算性质:
   
  而
    
  所以
   

 
定义:如果方阵满足,即,则称A为对称矩阵
  对称矩阵的特点是:它的元素以主对角线为对称轴对应相等.

五、方阵的行列式


  1、定义
 
定义:由方阵A的元素所构成的行列式(各元素的位置不变),称为方阵A的行列式,记作

  2 、运算性质
  (1) (行列式的性质)
  (2) ,特别地:
  (3) 是常数,A的阶数为n)
  思考:设A为阶方阵,那么的行列式与A的行列式之间的关系为什么不是,而是

  不妨自行设计一个二阶方阵,计算一下
  例如,则
  于是,而
  思考:,有几种方法可以求
    方法一:先求矩阵乘法,得到一个二阶方阵,再求其行列式.
    方法二:先分别求行列式,再取它们的乘积.

3、逆矩阵
     逆矩阵: 设A是数域上的一个n阶方阵,若在相同数域上存在另一个n阶矩阵B,使得: AB=BA=E。 则我们称B是A的逆矩阵,而A则被称为可逆矩阵。其用A^(-1)表示。
   逆矩阵的性质为:
    1 矩阵A可逆的充要条件是A的行列式不等于0。
   2 可逆矩阵一定是方阵
3 如果矩阵A是可逆的,A的逆矩阵是唯一的。
4 可逆矩阵也被称为非奇异矩阵、满秩矩阵。
5 两个可逆矩阵的乘积依然可逆。
6 可逆矩阵的转置矩阵也可逆。
7 矩阵可逆当且仅当它是满秩矩阵

 其中的方阵:就是行和列数相等的矩阵。
行列式:其就是求一个矩阵的数值,一般使用上三角或者下三角。其如下:


满秩矩阵:一个判断线性方程是否有解的关键条件,其是其说的就是要线性无关,其可分为列满秩和行满秩。其概念是:
满秩矩阵(non-singular matrix): 设A是n阶矩阵, 若r(A) = n, 则称A为满秩矩阵。但满秩不局限于n阶矩阵。若矩阵秩等于行数,称为行满秩;若矩阵秩等于列数,称为列满秩。既是行满秩又是列满秩则为n阶矩阵即n阶方阵。其中的R(A)指的就是求其秩。其中的行满秩就是行向量线性无关;列满秩就是列向量线性无关;其示意图如下:



   3、 列(行)满秩阵与方程关系:
 
这也是为什么相机标定的时候每个视场只能提前四个有用的点,这时因为第五个点肯定跟前面的四个点其中一个线性相关,意思就是(x,y)(X,Y)这个肯定跟前面的一个点成倍数关系,这样子在求秩的时候,有成倍数的行会被化成零,则这就成了降秩了,就不是满秩了。








2018-03-14 10:34:53 qq_26614295 阅读数 2188
  • (二)矩阵基本运算

    本课程由专业数学系老师讲解,从数学背景和现实应用中讲解线性代数的相关知识,摆脱传统...使听众能够了解矩阵和空间的概念、性质。深刻理解矩阵各类运算、分解的数学意义和应用,为后续的机器学习打下扎实的数学基础。

    825人学习 AI100讲师
    免费试看

在学习Opencv中的矩阵掩码时候遇到一个关于掩码矩阵表示的紧凑形式的问题,这里本人找了很多关于矩阵卷积的内容,大概说下比较通俗的理解:

1首先上一个叫做卷积核的矩阵

在Opencv官方文档的掩码矩阵中,我们可以看到会出现这样一个矩阵,先说说对掩码矩阵的公式的理解,对于图中一个像素点,视觉效果会收到相邻的像素点的影响,分别是上面的像素点,下面的像素点,左边的像素点和右边的像素点,我们把该像素点乘以5倍,然后分别减去这4个相邻的像素点的值,会发生以下情况,如果改像素点的值比较大,周围的像素点值比较小,那么相减之后的结果必然比该像素点的值大;反之,如果该像素点值比较小,周围像素点值比较大,那么相减之后的结果必然比该像素点值小,从而达到亮的点更加亮,暗的点更加暗,也就是锐化的效果。

那么这个卷积核矩阵就是为了实现这个功能,下面会对这个矩阵的原理做详细分析


2再看看我设定的图像输入矩阵,这里假设图像是单通道


3矩阵掩码操作

操作步骤大概就是先固定住卷积核矩阵不动,也就是上面灰色的矩阵,然后确定图像输入矩阵待求的像素点如(0,0),也就是上面图像输入矩阵的“1”;然后把这个待求点对准卷积核矩阵的中心点,也就是上图卷积核矩阵中的“5”,然后对这两个矩阵求卷积。下面先上图:

看到了吗,“1”和“5”已经对准,下面就是求卷积,求卷积的方法我大概说下我的理解,就是把图像矩阵重叠的部分与卷积核矩阵重叠部分相乘,然后不重叠的部分就是用0乘以对应卷积核矩阵的像素值,然后相加得出的结果,也就是为什么卷积核矩阵中心“5”周围的点要设置为“-1”的原因,就是为了用这些“-1”乘以图像像素点周围4个相邻像素点,不明白的话可以看我下面的计算,当然图中知识以图像矩阵中(0,0)也就是“1”为例,对于图像矩阵,我们必须把其余8个位置的像素值都算出来。

y(0,0) = 0*0 + 0*-1 + 0*0 +0*-1 +1*5 + 2*-1 + 0*0 + 4*-1 + 5*0  

从上面的计算中可以看出,对于图像矩阵中“1”这个点,和他相邻的只有“2”和“4”两个,所以计算中体现出了2*-1和4*-1

剩下图像矩阵中的8个点也是按照这个原理做卷积运算,例如我要求图像矩阵中的“5”点,就把这个“5”点和卷积核矩阵中心的“5”对齐,然后做卷积运算。






图像处理经典文献

阅读数 2701