图像处理haar变换

2019-07-26 20:42:44 Arthur_Holmes 阅读数 1176
  • 人眼检测

    学会自己查阅opencv doxygen文档 学会编写opencv代码实现简单图像处理变换 初步了解图像算法及机器视觉基础 运用计算机视觉相关知识和opencv库来构建简单的应用程序。

    168人学习 金圣韬
    免费试看

https://zh.wikipedia.org/wiki/%E5%8D%8F%E6%96%B9%E5%B7%AE%E7%9F%A9%E9%98%B5

KL中将五副图像作为原始图像的五个分量,然后使用KL变换之后的第一个分量包含了几乎所有的信息,这也是去相关五个图像之间的相关性

另外一种比较基础的就是只是在一副图像中运用,使得图像旋转,指向图像的主分量方向

所以哈尔矩阵既反映局部特征,又反映整体特征

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2017-01-06 15:12:38 u012507022 阅读数 15454
  • 人眼检测

    学会自己查阅opencv doxygen文档 学会编写opencv代码实现简单图像处理变换 初步了解图像算法及机器视觉基础 运用计算机视觉相关知识和opencv库来构建简单的应用程序。

    168人学习 金圣韬
    免费试看

  Haar-like特征是计算机视觉领域一种常用的特征描述算子(也称为Haar特征,这是因为Haar-like是受到一维haar小波的启示而发明的,所以称为类Haar特征),后来又将Haar-like扩展到三维空间(称为3DHaar-Like)用来描述视频中的动态特征。关于Haar的发展历程如图1所示。


图1

Haar-like特征的特点

       目前最常用的还是Haar-like特征,描述图像的特征,多用于人脸检测、行人检测,等目标检测;Haar-like特征可以理解为卷积模板(如同prewittsobel算子,当然不完全一样)Haar-like特征模板内只有白色和黑色两种矩形,并定义该模板的特征值为白色矩形像素和减去黑色矩形像素和。Haar特征值反映了图像的灰度变化情况。例如:脸部的一些特征能由矩形特征简单的描述,如:眼睛要比脸颊颜色要深,鼻梁两侧比鼻梁颜色要深,嘴巴比周围颜色要深等。但矩形特征只对一些简单的图形结构,如边缘、线段较敏感,所以只能描述特定走向(水平、垂直、对角)的结构。

Haar-like特征分类

Haar-like特征可以分为四类:线性特征、边缘特征、点特征(中心特征)、对角线特征;

也可以分成三类:边缘特征、线性特征(包含对角线特征)、点特征(中心特征);如图1(D)所示。

Haar-like特征的计算

       通过改变特征模板的大小和位置,可在图像子窗口中穷举出大量的特征。图1(D)中的的特征模板称为“特征原型”;特征原型在图像子窗口中扩展(平移伸缩)得到的特征称为“矩形特征”;矩形特征的值称为“特征值”。矩形特征可位于图像任意位置,大小也可以任意改变,所以矩形特征值是矩形模版类别、矩形位置和矩形大小这三个因素的函数。故类别、大小和位置的变化,使得很小的检测窗口含有非常多的矩形特征,如:在24*24像素大小的检测窗口内矩形特征数量可以达到16万个。

1) Haar特征个数计算参考博客:

http://blog.csdn.net/xiaowei_cqu/article/details/8216109

2)利用积分图Haar特征的加速算法

        刚开始认为积分图(Integral image)是个高深的东西,其实很简单。对于一个灰度图像I而言,其积分图也是一张与I尺寸相同的图,只不过该图上任意一点(x,y)的值是指从灰度图像I的左上角与当前点所围成的举行区域内所有像素点灰度值之和,有点耳熟吧。类似于图像直方图与图像累积直方图的关系,这里只不过是二维的图像。


       当把扫描图像一遍,到达图像右下角像素时,积分图像就构造好了。积分图构造好之后,图像中任何矩阵区域的像素累加和都可以通过简单运算得到如图2所示。而Haar-like特征值无非就是两个矩阵像素和的差,同样可以在常数时间内完成。所以矩形特征的特征值计算,只与此特征矩形的端点的积分图有关,所以不管此特征矩形的尺度变换如何,特征值的计算所消耗的时间都是常量。这样只要遍历图像一次,就可以求得所有子窗口的特征值。


参考文献:https://en.wikipedia.org/wiki/Haar-like_features

http://blog.csdn.net/xiaowei_cqu/article/details/8216109

http://blog.csdn.net/lg1259156776/article/details/48677637

http://blog.csdn.net/carson2005/article/details/8094699

http://blog.csdn.net/zouxy09/article/details/7929570/


2019-01-17 04:48:09 T_27080901 阅读数 2324
  • 人眼检测

    学会自己查阅opencv doxygen文档 学会编写opencv代码实现简单图像处理变换 初步了解图像算法及机器视觉基础 运用计算机视觉相关知识和opencv库来构建简单的应用程序。

    168人学习 金圣韬
    免费试看

Haar变换

案例一简单一维信号变换

下面是一个一维信号(一组数):f={2,2,2,4,4,4}f = \{2, 2, 2, 4, 4, 4\}

我对这个信号进行如下处理:

am=2f2m1+f2m2=f2m1+f2m2a_m = \sqrt{2}\frac{f_{2m-1}+f_{2m}}{2} = \frac{f_{2m-1}+f_{2m}}{\sqrt{2}}(相邻两个数相加,求平均,然后乘以2\sqrt{2}

dm=2f2m1f2m2=f2m1f2m2d_m = \sqrt{2}\frac{f_{2m-1}-f_{2m}}{2} = \frac{f_{2m-1}-f_{2m}}{\sqrt{2}}(相邻两个数相减,求平均,然后乘以2\sqrt{2}

注:至于为什么要乘以2\sqrt{2}呢?我们这里先不解释,放到后面再说。

然后按照先aadd的顺序排列a1,a2,...,aN/2,d1,d2,...,dN/2{a_1,a_2,...,a_{N/2}, d_1, d_2, ..., d_{N/2}}NN是离散信号中的值的个数)

则,a={22,32,42}a = \{2\sqrt{2}, 3\sqrt{2}, 4\sqrt{2}\}d={0,2,0}d=\{0, -\sqrt{2}, 0\}

我们可以得到结果:tf={22,32,42,0,2,0}tf = \{2\sqrt{2}, 3\sqrt{2}, 4\sqrt{2}, 0, -\sqrt{2}, 0\}

这就是传说中的Haar变换了……

aa表示的是信号的趋势(trend),近似(approximation),是低频信息;而dd表示的是信号的细节(detail),是高频信息。

那么我们怎么变回去呢?我们对变换以后的信号进行如下处理:

f2m1=2am+dm2=am+dm2f_{2m-1} = \sqrt{2}\frac{a_m +d_m}{2} = \frac{a_m +d_m}{\sqrt{2}}(第mmaadd相加,求平均,然后乘以2\sqrt{2}

f2m=2amdm2=amdm2f_{2m} = \sqrt{2}\frac{a_m -d_m}{2} = \frac{a_m -d_m}{\sqrt{2}} (第mmaadd相减,求平均,然后乘以2\sqrt{2}

我们可以得到结果if={2,2,2,4,4,4}if = \{2, 2, 2, 4, 4, 4\}

这样就是Haar变换的逆变换。

通过观察,我们可以发现:

  • dd中的数字绝大部分都很小(这是做信息压缩很重要的依据)
  • 变换前后信号的能量保持不变,即fi2=am2+di2\sum{f_i^2} = \sum{a_m^2} + \sum{d_i^2}(有兴趣的同学可以算一下对于fftftf的能量都是60,刚好相等)

案例二多分辨率一维信号变换

我们可以按照上面的思路将信号对得到的低频信号(aa)一直一直划分下去,直到log2N\mathrm{log}_2N(离散信号的值的数目不是偶数的,可以在后面补0)

给定如下的一个信号:f(t)=20x2(1x)4cos(12πx)f(t) = 20x^2(1-x)^4\cos(12\pi x)

我们通过在[0, 1]之间取样1024个点可以得到信号的振幅,绘制出信号图像如下:
原始信号
我们可以通过案例一种描述的方法进行Haar变换,我们这里对f(t)f(t)信号进行两次Haar变换,如下图所示:
Haar多分辨率分析

这是多分辨率分析(Multi-Resolution Analysis,MRA)以及图像压缩(JPEG2000编码)等的基础理念,这里现有一个大概理解,后面我们会继续谈到。

变换的结果如下(感兴趣的朋友可以使用Mathematica或者MATLAB是一样,这两个数学软件都提供了对Haar变换的直接支持):
Haar变换

好了,这一节先到这里,我们以后有时间慢慢聊!

2015-06-04 21:31:33 baidu_28563321 阅读数 1858
  • 人眼检测

    学会自己查阅opencv doxygen文档 学会编写opencv代码实现简单图像处理变换 初步了解图像算法及机器视觉基础 运用计算机视觉相关知识和opencv库来构建简单的应用程序。

    168人学习 金圣韬
    免费试看

编程环境:windows下结合opencv库

//离散Haar小波变换
/*
dst深度为IPL_DEPTH_32F
nLayer为变换尺度
*/
void HaarWavelet(IplImage* src, IplImage* dst, int nLayer);
//离散Haar小波变换
/*
dst深度为IPL_DEPTH_32F
nLayer为变换尺度
*/
void HaarWavelet(IplImage* src, IplImage* dst, int nLayer)
{
	if (!dst)
	{
		return;
	}
	if (((dst->width >> nLayer) << nLayer != dst->width) 
		|| ((dst->height >> nLayer) << nLayer != dst->height)
		|| (dst->depth != IPL_DEPTH_32F)
		|| (src->nChannels != 1)
		|| (dst->nChannels != 1)
		|| (nLayer <= 0))
	{
		return;
	}

	int x, y;
	int nWidth = dst->width;
	int nHeight = dst->height;
	int nHalfWidth = nWidth / 2;
	int nHalfHeight = nHeight / 2;
	//图像数据的起始地址
	float* *pfData = (float**)(malloc(sizeof(float*) * nHeight));
	//保存计算过程中用到的行列数据
	float* pfRow = (float*)(malloc(sizeof(float) * nWidth));
	float* pfColumn = (float*)(malloc(sizeof(float) * nHeight));
	CvMat tmp;
	//预先填充dst
	cvZero(dst);
	cvGetSubRect(dst, &tmp, cvRect(0, 0, src->width, src->height));
	cvScale(src, &tmp, 1.0, 0);
	//保存图像数据每行的起始地址
	for (y = 0; y < nHeight; y++)
	{
		pfData[y] = (float*)(dst->imageData + y * dst->widthStep);
	}

	while (nLayer > 0)
	{
		//行变换
		for (y = 0; y < nHeight; y++)
		{
			for (x = 0; x < nHalfWidth; x++)
			{
				pfRow[x] = (pfData[y][2 * x] + pfData[y][2 * x + 1]) / 2.0;
				pfRow[x + nHalfWidth] = (pfData[y][2 * x] - pfData[y][2 * x + 1]) / 2.0;
			}
			for (x = 0; x < nWidth; x++)
			{
				pfData[y][x] = pfRow[x];
			}
		}
		//列变换
		for (x = 0; x < nWidth; x++)
		{
	
			for (y = 0; y < nHalfHeight; y++)
			{
				pfColumn[y] = (pfData[2 * y][x] + pfData[2 * y + 1][x]) / 2;
				pfColumn[y + nHalfHeight] = (pfData[2 * y][x] - pfData[2 * y + 1][x]) / 2;
			}
			for (y = 0; y < nHeight; y++)
			{
				pfData[y][x] = pfColumn[y];
			}
		}
		//一层变换后尺度的缩小
		nLayer--;
		nWidth = nHalfWidth;
		nHeight = nHalfHeight;
		nHalfWidth = nHalfWidth / 2;
		nHalfHeight = nHalfHeight / 2;
	}

	//结果缩放以便与显示
	double min,max;
	cvMinMaxLoc(dst, &min, &max, NULL, NULL, NULL);
    cvScale(dst, dst, 1.0/(max-min), 1.0*(-min)/(max-min));
}


2018-11-01 08:43:33 HanFeiKei 阅读数 13789
  • 人眼检测

    学会自己查阅opencv doxygen文档 学会编写opencv代码实现简单图像处理变换 初步了解图像算法及机器视觉基础 运用计算机视觉相关知识和opencv库来构建简单的应用程序。

    168人学习 金圣韬
    免费试看

说起小波变换就需要提起傅里叶变换。傅里叶变换就是把波进行分解,可以认为任意一个周期波都可以有足够多的正弦(余弦)波组成,这里足够多的正弦波对应的频率不同,把这些足够的正弦波放在频域中,就是傅里叶变换,详细傅里叶变换可以参见这里,如图1。

图1 傅里叶变换

详细的小波变换可以参考这里,简单说来就是用一系列集中的、能量有限的波代替正弦波。而Haar小波变换就是利用haar滤波器进行计算。

一维Haar 变换计算如下:

设原始一维数据 a=[a_{1},a_{2},a_{3},a_{4}],   Haar低通滤波 [1, 1] , Haar高通滤波[-1, 1], 

则Haar小波变换为:b=[\frac{a_{1}+a_{2}}{2},\frac{a_{3}+a_{4}}{2},\frac{a_{1}-a_{2}}{2},\frac{a_{3}-a_{4}}{2}], 当需要进行下2采样时计算其均值(也有保留偶数序列),直接取[b_{1},b_{2}]

再次进行小波变换:c=[\frac{b_{1}+b_{2}}{2},\frac{b_{1}-b_{2}}{2}], 下2采样为 c1 。将[b_{3},b_{4}], c_{2} 称为细节系数。因此通过Haar 变换,一幅分辨率为4的数据就可以由分辨率为1,以及3个细节系数表示。同样由降采样的数据和细节系数可以恢复出原始数据。从上面计算过程可以看出:矢量a 与低通滤波器卷积得到近似,与高通滤波器卷积得到细节

二维图像Haar变换

对于二维图像Haar变换不再从一个方向进行滤波,而是从水平和竖直两个方向进行低通和高通滤波(水平和竖直先后不影响),用图像表述如图2所示:图2中a表示原图,图b表示经过一级小波变换的结果,h1 表示水平反向的细节,v1 表示竖直方向的细节,c1表示对角线方向的细节,b表示下2采样的图像。图c中表示继续进行Haar小波变换。一级Haar小波变换实际效果如图3所示

图2 Haar小波变换
图3 二维图像Haar小波变换