OpenCV中傅里叶变换和反变换的运用
2014-05-17 13:07
344 查看
#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
using namespace std;
using namespace cv;
void main()
{
Mat img = imread("lena.jpg",CV_LOAD_IMAGE_GRAYSCALE); //读入图像 转化为八位灰度图
imshow("source",img); //原图像显示
int h = cv::getOptimalDFTSize(img.rows); //图像尺寸的修正目的在于计算过程中可以优化,加快计算
int w = cv::getOptimalDFTSize(img.cols);
Mat padded;
cv::copyMakeBorder(img,padded,0,h-img.rows,0,w-img.cols,BORDER_CONSTANT,::Scalar::all(0));
//扩充成最优尺寸,注意:此处是复制了img的数据到padded,并非简单通过指针和img共享内存
//但这种情况则没有复制: 因为dst本身就和img共享了内存,只是简单的扩充了边界
//Mat img = imread("xxx.jpg");
//Mat dst = img;
//cv::copyMakeBorder(img,dst,2,2,2,2,BORDER_CONSTANT,Scalar::all(0));
Mat plane[] = {Mat_<float>(padded),Mat::zeros(padded.size(),CV_32F)}; //实部为img,虚部填充0
Mat complexImg;
cv::merge(plane,2,complexImg); //可以理解为组合成2通道(实部+虚部)图像
dft(complexImg,complexImg); //DFT变换后的数据复制到原处,没有另外开辟内存
//--------------------------------------------------------------------------
//dft变换后利用idft变换恢复原图像,显示效果与原图像相差无几,
Mat frequencyImg;
complexImg.copyTo(frequencyImg);
Mat iDft[] = {Mat::zeros(padded.size(),CV_32F),Mat::zeros(padded.size(),CV_32F)};
::idft(frequencyImg,frequencyImg);
::split(frequencyImg,iDft);
::magnitude(iDft[0],iDft[1],iDft[0]);
cv::normalize(iDft[0],iDft[0],1,0,CV_MINMAX);
imshow("iDFT",iDft[0]); //dft idft 后的图像
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------------
//根据DFT的能力集中地特点,即图像信息集中在低频部分
//先取出图像四个角(低频部分)的小块区域(其余灰度置为0),在idft反变换回去,和原图像进行比较
//显示结果表明只取出反变换后的16%信息,在利用idft反变换,发现与原图相差不太大
//这是图像处理中利用正交变换(包括傅里叶变换)的能量集中特性(图像有损压缩中有利用)
Mat partFrequencyImg;
complexImg.copyTo(partFrequencyImg);
int nx1 = int(0.2f*padded.cols);
int nx2 = int(0.8f*padded.cols);
int ny1 = int(0.2f*padded.rows);
int ny2 = int(0.8f*padded.rows);
partFrequencyImg.colRange(nx1,nx2).setTo(Scalar::all(0));
partFrequencyImg.rowRange(ny1,ny2).setTo(Scalar::all(0));
Mat iPartDft[] = {Mat::zeros(padded.size(),CV_32F),Mat::zeros(padded.size(),CV_32F)};
::idft(partFrequencyImg,partFrequencyImg);
::split(partFrequencyImg,iPartDft);
::magnitude(iPartDft[0],iPartDft[1],iPartDft[0]);
cv::normalize(iPartDft[0],iPartDft[0],1,0,CV_MINMAX);
imshow("iPartDFT",iPartDft[0]); //取dft变换后的部分低频部分,利用idft反变换后的图像
//--------------------------------------------------------------------------
::split(complexImg,plane); //实部plane[0] 虚部plane[1]
::magnitude(plane[0],plane[1],plane[0]);//计算幅频 结果保存到plane[0]
imshow("dft",plane[0]); //显示出来的幅频图,看不出任何有效信息,需要做增强处理
plane[0] += Scalar::all(1); //整体加1的目的在于log计算后非负
cv::log(plane[0],plane[0]); //log可起到拉伸,增大对比度的作用
cv::normalize(plane[0],plane[0],1,0,CV_MINMAX);//整体映射到0~1,也称归一化处理
imshow("enhance",plane[0]); //增强后的图像,显示效果明显改善
//保证plane[0]的行列均为偶数 以下将低频部分往中心移动
int cx = plane[0].cols / 2;
int cy = plane[0].rows / 2;
Mat m1(plane[0],cv::Rect(0,0,cx,cy)); //左上部分
Mat m2(plane[0],cv::Rect(cx,0,cx,cy)); //右上部分
Mat m3(plane[0],cv::Rect(0,cy,cx,cy)); //左下部分
Mat m4(plane[0],cv::Rect(cx,cy,cx,cy)); //右下部分
Mat temp;
m1.copyTo(temp); //左上与右下交换
m4.copyTo(m1);
temp.copyTo(m4);
m2.copyTo(temp);// 右上与左下交换
m3.copyTo(m2);
temp.copyTo(m3);
imshow("shift",plane[0]); //低频中心化的图像
waitKey(0);
}
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
using namespace std;
using namespace cv;
void main()
{
Mat img = imread("lena.jpg",CV_LOAD_IMAGE_GRAYSCALE); //读入图像 转化为八位灰度图
imshow("source",img); //原图像显示
int h = cv::getOptimalDFTSize(img.rows); //图像尺寸的修正目的在于计算过程中可以优化,加快计算
int w = cv::getOptimalDFTSize(img.cols);
Mat padded;
cv::copyMakeBorder(img,padded,0,h-img.rows,0,w-img.cols,BORDER_CONSTANT,::Scalar::all(0));
//扩充成最优尺寸,注意:此处是复制了img的数据到padded,并非简单通过指针和img共享内存
//但这种情况则没有复制: 因为dst本身就和img共享了内存,只是简单的扩充了边界
//Mat img = imread("xxx.jpg");
//Mat dst = img;
//cv::copyMakeBorder(img,dst,2,2,2,2,BORDER_CONSTANT,Scalar::all(0));
Mat plane[] = {Mat_<float>(padded),Mat::zeros(padded.size(),CV_32F)}; //实部为img,虚部填充0
Mat complexImg;
cv::merge(plane,2,complexImg); //可以理解为组合成2通道(实部+虚部)图像
dft(complexImg,complexImg); //DFT变换后的数据复制到原处,没有另外开辟内存
//--------------------------------------------------------------------------
//dft变换后利用idft变换恢复原图像,显示效果与原图像相差无几,
Mat frequencyImg;
complexImg.copyTo(frequencyImg);
Mat iDft[] = {Mat::zeros(padded.size(),CV_32F),Mat::zeros(padded.size(),CV_32F)};
::idft(frequencyImg,frequencyImg);
::split(frequencyImg,iDft);
::magnitude(iDft[0],iDft[1],iDft[0]);
cv::normalize(iDft[0],iDft[0],1,0,CV_MINMAX);
imshow("iDFT",iDft[0]); //dft idft 后的图像
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------------
//根据DFT的能力集中地特点,即图像信息集中在低频部分
//先取出图像四个角(低频部分)的小块区域(其余灰度置为0),在idft反变换回去,和原图像进行比较
//显示结果表明只取出反变换后的16%信息,在利用idft反变换,发现与原图相差不太大
//这是图像处理中利用正交变换(包括傅里叶变换)的能量集中特性(图像有损压缩中有利用)
Mat partFrequencyImg;
complexImg.copyTo(partFrequencyImg);
int nx1 = int(0.2f*padded.cols);
int nx2 = int(0.8f*padded.cols);
int ny1 = int(0.2f*padded.rows);
int ny2 = int(0.8f*padded.rows);
partFrequencyImg.colRange(nx1,nx2).setTo(Scalar::all(0));
partFrequencyImg.rowRange(ny1,ny2).setTo(Scalar::all(0));
Mat iPartDft[] = {Mat::zeros(padded.size(),CV_32F),Mat::zeros(padded.size(),CV_32F)};
::idft(partFrequencyImg,partFrequencyImg);
::split(partFrequencyImg,iPartDft);
::magnitude(iPartDft[0],iPartDft[1],iPartDft[0]);
cv::normalize(iPartDft[0],iPartDft[0],1,0,CV_MINMAX);
imshow("iPartDFT",iPartDft[0]); //取dft变换后的部分低频部分,利用idft反变换后的图像
//--------------------------------------------------------------------------
::split(complexImg,plane); //实部plane[0] 虚部plane[1]
::magnitude(plane[0],plane[1],plane[0]);//计算幅频 结果保存到plane[0]
imshow("dft",plane[0]); //显示出来的幅频图,看不出任何有效信息,需要做增强处理
plane[0] += Scalar::all(1); //整体加1的目的在于log计算后非负
cv::log(plane[0],plane[0]); //log可起到拉伸,增大对比度的作用
cv::normalize(plane[0],plane[0],1,0,CV_MINMAX);//整体映射到0~1,也称归一化处理
imshow("enhance",plane[0]); //增强后的图像,显示效果明显改善
//保证plane[0]的行列均为偶数 以下将低频部分往中心移动
int cx = plane[0].cols / 2;
int cy = plane[0].rows / 2;
Mat m1(plane[0],cv::Rect(0,0,cx,cy)); //左上部分
Mat m2(plane[0],cv::Rect(cx,0,cx,cy)); //右上部分
Mat m3(plane[0],cv::Rect(0,cy,cx,cy)); //左下部分
Mat m4(plane[0],cv::Rect(cx,cy,cx,cy)); //右下部分
Mat temp;
m1.copyTo(temp); //左上与右下交换
m4.copyTo(m1);
temp.copyTo(m4);
m2.copyTo(temp);// 右上与左下交换
m3.copyTo(m2);
temp.copyTo(m3);
imshow("shift",plane[0]); //低频中心化的图像
waitKey(0);
}
相关文章推荐
- OpenCV学习Laplacian 变换及其运用
- opencv 傅里叶变换与反变换
- 【python下使用OpenCV实现计算机视觉读书笔记2】图像与字节的变换
- opencv-霍夫线变换
- opencv----霍夫(Hough)变换:霍夫线变换,霍夫圆变换
- OpenCV-基于傅里叶变换的旋转文本图像矫正实现
- 【OpenCV】傅里叶变换
- 基于opencv的数学形态学的操作,涉及数学形态学细化、击中击不中变换
- Opencv模板匹配运用
- OpenCV学习笔记-霍夫线变换2
- Hough变换在opencv中的应用
- 思考:矩阵及变换,以及矩阵在DirectX和OpenGL中的运用问题:左乘/右乘,行优先/列优先,...
- Opencv2教程一:图像变换之阈值二值threshold
- OpenCV实现Hough变换检测圆形
- Opencv图像尺寸变换
- OpenCV2.4.10之samples_cpp_tutorial-code_learn-----ImgTrans(Hough变换)
- opencv创建序列cvCreateSeq与插入元素cvSeqPush的运用
- OpenCV 下面的图像亮度变换 Intensity transformation
- Hough变换(openCV的cvHoughLines2)
- opencv:图像变换