小波变换

首先说一下一维haar小波的原理。 
例如我们有一个一维的图像[2,4,6,8,10,12,14,16].

  1. 求均值:我们求相邻像素的均值[3,7,11,15]。这个新的图像分辨率就成了原来的一半(8/2=4)。
  2. 求差值。上面的均值我们存储了图像的整体信息。但是很多细节信息我们丢掉了,所以我们同时要记录图像的细节信息,这样在重构时能够恢复图像的全部信息。下面是求第m个差值的公式:

b[m] = (a[2m] - a[2m+1])/2

经过计算我们得到了结果[-1,-1,-1,-1]。这个新的分辨率也成了原来的一半(8/2=4)。 
3. 此时上面两步形成了第一次分解的结果[3,7,11,15,-1,-1,-1,-1]。包含了图像的整体信息和细节信息。接下来的分解我们重复1,2步,将整体信息再次进行分解,得到了二级分解结果[5,13,-2,-2].同样的,前面的[5,13]是整体信息,后面的[-2,-2]是细节信息。

分辨率整体信息细节信息
43,7,11,15-1,-1,-1,-1
25,13-2,-2
19-4

经过三次分解,我们得到了一个整体信息和三个细节系数,这个就是一维小波变换。

对于二维haar小波,我们通常一次分解形成了整体图像,水平细节,垂直细节,对角细节。首先我们按照一维haar小波分解的原理,按照行顺序对行进行处理,然后按照列顺序对行处理结果进行同样的处理。最后形成了如下的形式。 

接下来就是代码时间了,首先看下代码结果:


/****************************
* multi-scale wavelet translation
******************************/

#include <opencv2/opencv.hpp>
#include <iostream>

int main()
{
	Mat img = imread("F:/test/img/data/others/boat.jpg",0);
	int Height = img.rows;
	int Width = img.cols;
	cout << "Height :" << Height << endl<< "Width: " << Width << endl;
	int depth = 1;//decompose scale
	int depthcount = 1;
	Mat tmp = Mat::ones(Height, Width, CV_32FC1);
	Mat wavelet = Mat::ones(Height, Width, CV_32FC1);//the result of wavelet decomposion
	Mat imgtmp = img.clone();
	imgtmp.convertTo(imgtmp, CV_32FC1);
	while (depthcount <= depth) {
		Height = img.rows / depthcount;
		Width = img.cols / depthcount;

		for (int i = 0; i < Height; i++) {
			for (int j = 0; j < Width / 2; j++) {
				tmp.at<float>(i, j) = (imgtmp.at<float>(i, 2 * j) + imgtmp.at<float>(i, 2 * j + 1)) / 2;
				tmp.at<float>(i, j + Width / 2) = (imgtmp.at<float>(i, 2 * j) - imgtmp.at<float>(i, 2 * j + 1)) / 2;
			}
		}
		for (int i = 0; i < Height / 2; i++) {
			for (int j = 0; j < Width; j++) {
				wavelet.at<float>(i, j) = (tmp.at<float>(2 * i, j) + tmp.at<float>(2 * i + 1, j)) / 2;
				wavelet.at<float>(i + Height / 2, j) = (tmp.at<float>(2 * i, j) - tmp.at<float>(2 * i + 1, j)) / 2;
			}
		}
		imgtmp = wavelet;
		depthcount++;
	}

	namedWindow("jpg", 0);
	wavelet.convertTo(wavelet, CV_8UC1);
	wavelet += 50;//because the image is too dark, I add 50 to the image
	imshow("jpg", wavelet);
	cv::imwrite("lenaWaveletResult.jpg", wavelet);
	waitKey(0);
	return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值