Bootstrap

OpenCV norm 计算范数(18)

在opencv 里面 norm 这个函数是求解范数

在我的上一篇的博客中对范数做了一个简单的介绍,如果求解向量的范数和矩阵的范数

https://blog.csdn.net/datouniao1/article/details/109055343

norm(src1,normType )

我们来看opencv 中norm 这个函数,首先我们进行简单的计算

src 为输入的矩阵

normType 为范数的类型 默认的是L2 范数

NORM_INF、NORM_L1、NORM_L2、NORM_L2SQR、NORM_HAMMING、NORM_HAMMING2,其中NORM_L2SQR是2-范数的平方;NORM_HAMMING就是汉明距离,简单的讲就是一个数中非零的位的个数;而NORM_HAMMING2与NORM_HAMMING的区别在于,它使用一个表来映射不同的uchar值表示的汉明距离大小

 

//  Core.NORM_INF    绝对值最大

// Core.NORM_L1     绝对值值和

// Core.NORM_L2     绝对值平方和开方

	    Mat mat=new Mat(new Size(3,1),CvType.CV_8UC1);
		mat.put(0, 0, 1,2,3);
		System.out.println(mat.dump());
		double d=Core.norm(mat);
		System.out.println(d);

创建一个最为简单的矩阵

[1,2,3]

上面使用的是默认的L2的范数,我们看到其实这个是一个向量

利用这个公式: (1^2+2^2+2^3)^(1/2)=sqrt(14)=3.7

3.7416573867739413

我们验证一下:

Math.sqrt(14)=3.7416573867739413    

可见norm这个函数就是求解矩阵的范数

NormType为范数的类型,比如我们求上面上相的1范数

		Mat mat=new Mat(new Size(3,1),CvType.CV_8UC1);
		mat.put(0, 0, 1,2,3);
		System.out.println(mat.dump());
		double d=Core.norm(mat,Core.NORM_L1);
		System.out.println(d);

 这个就是求解L1范数,我们来看范数的计算公式:

  向量的1-范数: {\left\| X \right\|_1} = \sum\limits_{i = 1}^n {\left| {​{x_i}} \right|} ; 各个元素的绝对值之和;

输出结果:

[  1,   2,   3]
6.0

上面的矩阵都是1维的,我们创建一个二维的矩阵继续来看norm这个函数


		Mat mat=new Mat(new Size(3,2),CvType.CV_8UC1);
		mat.put(0, 0, 1,2,3);
		mat.put(1, 0, 2,2,3);
		System.out.println(mat.dump());
		double d=Core.norm(mat,Core.NORM_L1);

         但是Core.NORM_L1 所表示的是矩阵所有元素绝对值之和

		Mat mat=new Mat(new Size(3,3),CvType.CV_8UC1);
		mat.put(0, 0, 1,2,3);
		mat.put(1, 0, 2,2,3);
		mat.put(2, 0, 2,2,4);
		System.out.println(mat.dump());
		double d=Core.norm(mat,Core.NORM_L1);
		System.out.println("计算结果:"+d);

[  1,   2,   3;
   2,   2,   3;
   2,   2,   4]
21.0

[  1,   2,  -3;
   2,   2,   3;
   2,   2,   4]
计算结果:21.0

	    Mat mat=new Mat(new Size(3,3),CvType.CV_8SC1);
		mat.put(0, 0, 1,2,-3);
		mat.put(1, 0, 2,2,3);
		mat.put(2, 0, 2,2,4);
		System.out.println(mat.dump());
		double d=Core.norm(mat,Core.NORM_L2);
		System.out.println("计算结果:"+d);

Core.NORM_L2 计算出来的结果是所有元素的平方和然后求平方根

[  1,   2,  -3;
   2,   2,   3;
   2,   2,   4]
计算结果:7.416198487095663

Core.norm(mat, mat2);

其实是求出   Core.norm(mat,Core.NORM_L1)-Core.norm(mat2,Core.NORM_L1) 得到的结果就绝对值

		Mat mat=new Mat(new Size(3,3),CvType.CV_8SC1);
		mat.put(0, 0, 1,2,3);
		mat.put(1, 0, 2,2,3);
		mat.put(2, 0, 2,2,4);
		System.out.println(mat.dump());
		double d=Core.norm(mat,Core.NORM_L1);
		System.out.println("计算结果:"+d);
		Mat mat2=new Mat(new Size(3,3),CvType.CV_8SC1);
		mat2.put(0, 0, 1,2,8);
		mat2.put(1, 0, 2,2,3);
		mat2.put(2, 0, 2,2,4);
		double d2=Core.norm(mat2,Core.NORM_L1);
		System.out.println("计算结果:"+d2);
		double ds=Core.norm(mat, mat2);
		System.out.println("计算结果:"+ds);

[  1,   2,   3;
   2,   2,   3;
   2,   2,   4]
计算结果:21.0
[  1,   2,   8;
   2,   2,   3;
   2,   2,   4]
计算结果:26.0
计算结果:5.0

Core.norm(mat, mat2,Core.NORM_L1);

Core.norm(mat, mat2,Core.NORM_L2);

计算出来的结果都是:其实是求出   Core.norm(mat,Core.NORM_L1)-Core.norm(mat2,Core.NORM_L1) 得到的结果就绝对值

Mask

之前的操作一直在回避掩码,

double ss=Core.norm(mat, Core.NORM_L1, mask);

但是这个函数中正好也用到了掩码mask 那么我们不妨简单的研究一下

mask 具有这样的特征,和输入的图像src具有相同的大小,而且是8UC1

掩码是一种选择性的计算

Core.norm(mat, Core.NORM_L1)默认的是计算mat中所有的元素的绝对值之和,此时我们mask可以看成是NULL

[  1,   2,   3;
   2,   2,   3;
   2,   2,   4]

比如上面的矩阵,我们计算出的结果是Core.norm(mat, Core.NORM_L1)=21,

引入掩码:

我们先创建一个mask 需要和src具有同样大小,而且为8UC1

	    Mat mask=new Mat(mat.size(),CvType.CV_8UC1);
		mask.put(0, 0, 0,0,0);
		mask.put(1, 0, 0,0,0);
		mask.put(2, 0, 0,0,0);

mask=

[  0,   0,   0;
   0,   0,   0;
   0,   0,   0]

此时我们的计算结果:

double ss=Core.norm(mat, Core.NORM_L1,mask);
mat:   [  1,   2,   3;              mask:[  0,   0,   0;
            2,   2,   3;                          0,   0,   0;
             2,   2,   4]                         0,   0,   0]

输出结果为:0.0

mat:   [  1,   2,   3;              mask:[  1,   1,   1;
            2,   2,   3;                          1,   1,   1;
             2,   2,   4]                         1,   1,   1]

输出结果为:21

mat:   [  1,   2,   3;              mask:[  1,   1,   1;
            2,   2,   3;                          0,   0,   1;
             2,   2,   4]                         1,   0,   1]

在这个地方我们大概可以看出来,当我们进行范数计算的时候,输入对象如果对应掩码中的数值非零的时候参与计算,是0的时候值为0

其实我们最后最后计算的结果为:

[  1,   2   3;
   0,   0,   3;
   1,   0,   4]

根据掩码的特征,我们在处理图像的时候可以选择性的计算一些数值,当然这些需要我们队opencv相关的函数很熟悉了之后可以进行的操作

上面就是opencv的norm函数的一个基本用法,

希望对你有所帮助

 

 

 

 

 

                                         
           
           

 

 

 

 

 

 

;