小波变换处理灰度图像的cv代码

处理灰度图像的cv代码;

小波图像边缘检测可以超越传统的图像边缘检测方法,这种方法能有效的检测在不同尺寸下的图像边缘特征。小波变换在时域和频域中都具有很好的局部特性,它可以将信号或图像分成交织在一起的多尺度组成成分,并且对于大小不同的尺度成分使用相应粗细的时域或者空域取样步长。对高频信号的细处理和对低频信号的粗处理,从而能够不断聚集到对象的任意微小细节。

总之,小波变换边缘检测技术很牛,也很难。

不多说了,代码如下,感觉有帮助到您请酌情打赏。

#include <opencv2/opencv.hpp>
#include <iostream>
#include <string>
using namespace std;
using namespace cv;

void WDT(Mat& src, Mat& dst)
{ 
	Mat highfilter(1, 2, CV_32FC1);
	Mat lowfilter(1, 2, CV_32FC1);
	highfilter.at <float>(0, 0) = -1 / sqrtf(2);
	highfilter.at <float>(0, 1) =  1 / sqrtf(2);
	lowfilter.at <float>(0, 0) = 1 / sqrtf(2);
	lowfilter.at <float>(0, 1) = 1 / sqrtf(2);

	int row = src.rows;
	int col = src.cols;


	//行小波变换
	for (int i = 0; i < row; i++)
	{
		Mat oneRow(1, col, CV_32FC1);
		for (int j = 0; j < col; j++)
		{
			oneRow.at<float>(0, j) = src.at<uchar>(i, j);
		}
		//逐行滤波
		Mat dst1(1, col, CV_32FC1); //低通分量
		Mat dst2(1, col, CV_32FC1); //高通分量

		for (int k = 1; k < col; k++)
		{
			dst1.at<float>(0, k) = oneRow.at<float>(0, k - 1) * lowfilter.at<float>(0, 0) + oneRow.at<float>(0, k) * lowfilter.at<float>(0, 1);
			
		}


		for (int k = 1; k < col; k++)
		{
			dst2.at<float>(0, k) = oneRow.at<float>(0, k - 1) * highfilter.at<float>(0, 0) + oneRow.at<float>(0, k) * highfilter.at<float>(0, 1);
		}
		//低通高通拼接
		for (int p = 0, q = 1; p < col / 2; p++, q += 2)
		{
			oneRow.at<float>(0, p) = dst1.at<float>(0, q);
			oneRow.at<float>(0, p + col / 2) = dst2.at<float>(0, q);
		}

		for (int j = 0; j < col; j++)
		{
			dst.at<float>(i, j) = oneRow.at<float>(0, j);
		}
	}

	//列小波变换
	for (int j = 0; j < col; j++)
	{
		Mat oneCol(1, row, CV_32FC1);
		for (int i = 0; i < row; i++)
		{
			oneCol.at<float>(0, i) = dst.at<float>(i, j);
		}
		//逐行滤波
		Mat dst3(1, row, CV_32FC1); //低通分量
		Mat dst4(1, row, CV_32FC1); //高通分量

		for (int k = 1; k < row; k++)
		{
			dst3.at<float>(0, k) = oneCol.at<float>(0, k - 1) * lowfilter.at<float>(0, 0) + oneCol.at<float>(0, k) * lowfilter.at<float>(0, 1);

		}


		for (int k = 1; k < row; k++)
		{
			dst4.at<float>(0, k) = oneCol.at<float>(0, k - 1) * highfilter.at<float>(0, 0) + oneCol.at<float>(0, k) * highfilter.at<float>(0, 1);
		}

		//低通高通拼接
		for (int p = 0, q = 1; p < row / 2; p++, q += 2)
		{
			oneCol.at<float>(0, p) = dst3.at<float>(0, q);
			oneCol.at<float>(0, p + row / 2) = dst4.at<float>(0, q);
		}

		for (int i = 0; i < row; i++)
		{
			dst.at<float>(i, j) = oneCol.at<float>(0, i);
		}
	}

}

void IWDT(Mat& src, Mat& ini, Mat& dst)
{
	//将src的左上角替换为ini
	for (int i = 0; i < ini.rows; i++)
	{
		for (int j = 0; j < ini.cols; j++)
		{
			src.at<float>(i, j) = ini.at<uchar>(i, j) * 2;
		}
	}

	Mat highfilter(1, 2, CV_32FC1);
	Mat lowfilter(1, 2, CV_32FC1);
	highfilter.at <float>(0, 0) = 1 / sqrtf(2);
	highfilter.at <float>(0, 1) = -1 / sqrtf(2);
	lowfilter.at <float>(0, 0) = 1 / sqrtf(2);
	lowfilter.at <float>(0, 1) = 1 / sqrtf(2);

	int row = src.rows;
	int col = src.cols;
	//列逆变换
	for (int j = 0; j < col; j++)
	{
		Mat oneCol(1, row, CV_32FC1);
		for (int i = 0; i < row; i++)
		{
			oneCol.at<float>(0, i) = src.at<float>(i, j);
		}

		//重建
		Mat up1(Mat::zeros(1, row, CV_32FC1));
		Mat up2(Mat::zeros(1, row, CV_32FC1));
		for (int i = 0, cnt = 0; i < row / 2; i++, cnt += 2)
		{
			up1.at<float>(0, cnt) = oneCol.at<float>(0, i);
			up2.at<float>(0, cnt) = oneCol.at<float>(0, i + row/2);
		}

		//卷积
		Mat dst1(Mat::zeros(1, row, CV_32FC1));
		Mat dst2(Mat::zeros(1, row, CV_32FC1));
		for (int k = 1; k < row; k++)
		{
			dst1.at<float>(0, k) = up1.at<float>(0, k - 1) * lowfilter.at<float>(0, 0) + up1.at<float>(0, k) * lowfilter.at<float>(0, 1);

		}


		for (int k = 1; k < row; k++)
		{
			dst2.at<float>(0, k) = up2.at<float>(0, k - 1) * highfilter.at<float>(0, 0) + up2.at<float>(0, k) * highfilter.at<float>(0, 1);
		}

		//加起来
		for (int k = 1; k < row; k++)
		{
			oneCol.at<float>(0, k) = dst1.at<float>(0, k) + dst2.at<float>(0, k);
		}

		for (int i = 0; i < row; i++)
		{
			dst.at<float>(i, j) = oneCol.at<float>(0, i);
		}
	}

	//行逆变换
	for (int i = 0; i < row; i++)
	{
		Mat oneRow(1, col, CV_32FC1);
		for (int j = 0; j < col; j++)
		{
			oneRow.at<float>(0, j) = dst.at<float>(i, j);
		}

		//重建
		Mat up1(Mat::zeros(1, col, CV_32FC1));
		Mat up2(Mat::zeros(1, col, CV_32FC1));
		for (int j = 0, cnt = 0; j < col / 2; j++, cnt += 2)
		{
			up1.at<float>(0, cnt) = oneRow.at<float>(0, j);
			up2.at<float>(0, cnt) = oneRow.at<float>(0, j + col / 2);
		}

		//卷积
		Mat dst1(Mat::zeros(1, col, CV_32FC1));
		Mat dst2(Mat::zeros(1, col, CV_32FC1));
		for (int k = 1; k < col; k++)
		{
			dst1.at<float>(0, k) = up1.at<float>(0, k - 1) * lowfilter.at<float>(0, 0) + up1.at<float>(0, k) * lowfilter.at<float>(0, 1);

		}


		for (int k = 1; k < col; k++)
		{
			dst2.at<float>(0, k) = up2.at<float>(0, k - 1) * highfilter.at<float>(0, 0) + up2.at<float>(0, k) * highfilter.at<float>(0, 1);
		}

		//加起来
		for (int k = 1; k < col; k++)
		{
			oneRow.at<float>(0, k) = dst1.at<float>(0, k) + dst2.at<float>(0, k);
		}

		for (int j = 0; j < col; j++)
		{
			dst.at<float>(i, j) = oneRow.at<float>(0, j);
		}
	}

}


void float2uchar(Mat& dst, Mat& out)
{
	for (int i = 0; i < dst.rows; i++)
	{
		for (int j = 0; j < dst.cols; j++)
		{
			out.at<uchar>(i, j) = (uchar)dst.at<float>(i, j);
		}
	}
}

int main(int arge ,char ** argv)
{
   //in存放未处理过的540*960图片像素   
   //颜色模式设置
	Mat in = imread("C:\\Users\\kris9\\Desktop\\JCS\\集创赛数据集\\downscaled\\41.bmp",0);  //enum::ImreadModes = 0 灰度模式
	//Mat in = imread("C:\\Users\\kris9\\Desktop\\JCS\\集创赛数据集\\downscaled\\41.bmp", 1);   //enum::ImreadModes = 1 3通道color模式

    //初始化src存放线性插值过的1080*1920图片像素
	Mat src;

	//线性插值放缩,放缩后存放在src中
	resize(in, src, Size(0, 0),2,2,INTER_LINEAR);
	//resize(in, src, Size(0, 0), 2, 2, INTER_NEAREST);

	//初始化dst,用来存放小波正变换处理后像素数据
	Mat dst(src.rows,src.cols,CV_32FC1);
	//初始化iwdt,用来存放小波逆变换处理后像素数据
	Mat dst_iwdt(src.rows, src.cols, CV_32FC1);
	
	//wavelet
	WDT(src, dst);
	//逆wavelet
	IWDT(dst, in, dst_iwdt);


	Mat out(dst.rows, dst.cols, CV_8UC1);

	float2uchar(dst_iwdt, out);
	imshow("output",out);
	waitKey(0);
	return 0;
}

关于小波变换代码 以下是关于函数的说明 AppWizard has created this DSplit application for you. This application not only demonstrates the basics of using the Microsoft Foundation classes but is also a starting point for writing your application. This file contains a summary of what you will find in each of the files that make up your DSplit application. DSplit.h This is the main header file for the application. It includes other project specific headers (including Resource.h) and declares the CDSplitApp application class. DSplit.cpp This is the main application source file that contains the application class CDSplitApp. DSplit.rc This is a listing of all of the Microsoft Windows resources that the program uses. It includes the icons, bitmaps, and cursors that are stored in the RES subdirectory. This file can be directly edited in Microsoft Developer Studio. res\DSplit.ico This is an icon file, which is used as the application's icon. This icon is included by the main resource file DSplit.rc. res\DSplit.rc2 This file contains resources that are not edited by Microsoft Developer Studio. You should place all resources not editable by the resource editor in this file. DSplit.clw This file contains information used by ClassWizard to edit existing classes or add new classes. ClassWizard also uses this file to store information needed to create and edit message maps and dialog data maps and to create prototype member functions. ///////////////////////////////////////////////////////////////////////////// For the main frame window: MainFrm.h, MainFrm.cpp These files contain the frame class CMainFrame, which is derived from CFrameWnd and controls all SDI frame features. res\Toolbar.bmp This bitmap file is used to create tiled images for the toolbar. The initial toolbar and status bar are constructed in the CMainFrame class. Edit this toolbar bitmap along with the array in MainFrm.cpp to
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林中青木

原创不易,请多多支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值