小波变换处理灰度图像的cv代码;
小波图像边缘检测可以超越传统的图像边缘检测方法,这种方法能有效的检测在不同尺寸下的图像边缘特征。小波变换在时域和频域中都具有很好的局部特性,它可以将信号或图像分成交织在一起的多尺度组成成分,并且对于大小不同的尺度成分使用相应粗细的时域或者空域取样步长。对高频信号的细处理和对低频信号的粗处理,从而能够不断聚集到对象的任意微小细节。
总之,小波变换边缘检测技术很牛,也很难。
不多说了,代码如下,感觉有帮助到您请酌情打赏。
#include
#include
#include
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 (0, 0) = -1 / sqrtf(2);
highfilter.at (0, 1) = 1 / sqrtf(2);
lowfilter.at (0, 0) = 1 / sqrtf(2);
lowfilter.at (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(0, j) = src.at(i, j);
}
//逐行滤波
Mat dst1(1, col, CV_32FC1); //低通分量
Mat dst2(1, col, CV_32FC1); //高通分量
for (int k = 1; k < col; k++)
{
dst1.at(0, k) = oneRow.at(0, k - 1) * lowfilter.at(0, 0) + oneRow.at(0, k) * lowfilter.at(0, 1);
}
for (int k = 1; k < col; k++)
{
dst2.at(0, k) = oneRow.at(0, k - 1) * highfilter.at(0, 0) + oneRow.at(0, k) * highfilter.at(0, 1);
}
//低通高通拼接
for (int p = 0, q = 1; p < col / 2; p++, q += 2)
{
oneRow.at(0, p) = dst1.at(0, q);
oneRow.at(0, p + col / 2) = dst2.at(0, q);
}
for (int j = 0; j < col; j++)
{
dst.at(i, j) = oneRow.at(0, j);
}
}
//列小波变换
for (int j = 0; j < col; j++)
{
Mat oneCol(1, row, CV_32FC1);
for (int i = 0; i < row; i++)
{
oneCol.at(0, i) = dst.at(i, j);
}
//逐行滤波
Mat dst3(1, row, CV_32FC1); //低通分量
Mat dst4(1, row, CV_32FC1); //高通分量
for (int k = 1; k < row; k++)
{
dst3.at(0, k) = oneCol.at(0, k - 1) * lowfilter.at(0, 0) + oneCol.at(0, k) * lowfilter.at(0, 1);
}
for (int k = 1; k < row; k++)
{
dst4.at(0, k) = oneCol.at(0, k - 1) * highfilter.at(0, 0) + oneCol.at(0, k) * highfilter.at(0, 1);
}
//低通高通拼接
for (int p = 0, q = 1; p < row / 2; p++, q += 2)
{
oneCol.at(0, p) = dst3.at(0, q);
oneCol.at(0, p + row / 2) = dst4.at(0, q);
}
for (int i = 0; i < row; i++)
{
dst.at(i, j) = oneCol.at(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(i, j) = ini.at(i, j) * 2;
}
}
Mat highfilter(1, 2, CV_32FC1);
Mat lowfilter(1, 2, CV_32FC1);
highfilter.at (0, 0) = 1 / sqrtf(2);
highfilter.at (0, 1) = -1 / sqrtf(2);
lowfilter.at (0, 0) = 1 / sqrtf(2);
lowfilter.at (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(0, i) = src.at(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(0, cnt) = oneCol.at(0, i);
up2.at(0, cnt) = oneCol.at(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(0, k) = up1.at(0, k - 1) * lowfilter.at(0, 0) + up1.at(0, k) * lowfilter.at(0, 1);
}
for (int k = 1; k < row; k++)
{
dst2.at(0, k) = up2.at(0, k - 1) * highfilter.at(0, 0) + up2.at(0, k) * highfilter.at(0, 1);
}
//加起来
for (int k = 1; k < row; k++)
{
oneCol.at(0, k) = dst1.at(0, k) + dst2.at(0, k);
}
for (int i = 0; i < row; i++)
{
dst.at(i, j) = oneCol.at(0, i);
}
}
//行逆变换
for (int i = 0; i < row; i++)
{
Mat oneRow(1, col, CV_32FC1);
for (int j = 0; j < col; j++)
{
oneRow.at(0, j) = dst.at(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(0, cnt) = oneRow.at(0, j);
up2.at(0, cnt) = oneRow.at(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(0, k) = up1.at(0, k - 1) * lowfilter.at(0, 0) + up1.at(0, k) * lowfilter.at(0, 1);
}
for (int k = 1; k < col; k++)
{
dst2.at(0, k) = up2.at(0, k - 1) * highfilter.at(0, 0) + up2.at(0, k) * highfilter.at(0, 1);
}
//加起来
for (int k = 1; k < col; k++)
{
oneRow.at(0, k) = dst1.at(0, k) + dst2.at(0, k);
}
for (int j = 0; j < col; j++)
{
dst.at(i, j) = oneRow.at(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(i, j) = (uchar)dst.at(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;
}