return-1;
}
imshow("原始图像",srcImage);
//将输入图像延扩到最佳的尺寸,边界用0补充
intm=getOptimalDFTSize(srcImage.rows);
intn=getOptimalDFTSize(srcImage.cols);
//将添加的像素初始化为0.
Matpadded;
copyMakeBorder(srcImage,padded,0,m-srcImage.rows,0,n-srcImage.cols,BORDER_CONSTANT,Scalar:
:
all(0));
//为傅立叶变换的结果(实部和虚部)分配存储空间。
//将planes数组组合合并成一个多通道的数组complexI
Matplanes[]={Mat_(padded),Mat:
:
zeros(padded.size(),CV_32F)};
MatcomplexI;
merge(planes,2,complexI);
//进行就地离散傅里叶变换
dft(complexI,complexI);
//将复数转换为幅值,即=>log(1+sqrt(Re(DFT(I))^2+Im(DFT(I))^2))
split(complexI,planes);
//将多通道数组complexI分离成几个单通道数组,planes[0]=Re(DFT(I),//planes[1]=Im(DFT(I))
magnitude(planes[0],planes[1],planes[0]);//planes[0]=magnitude
MatmagnitudeImage=planes[0];
//进行对数尺度(logarithmicscale)缩放
magnitudeImage+=Scalar:
:
all
(1);
log(magnitudeImage,magnitudeImage);//求自然对数
//剪切和重分布幅度图象限
//若有奇数行或奇数列,进行频谱裁剪
magnitudeImage=magnitudeImage(Rect(0,0,magnitudeImage.cols&-2,magnitudeImage.rows&-2));
//重新排列傅立叶图像中的象限,使得原点位于图像中心
intcx=magnitudeImage.cols/2;
intcy=magnitudeImage.rows/2;
Matq0(magnitudeImage,Rect(0,0,cx,cy));//ROI区域的左上
Matq1(magnitudeImage,Rect(cx,0,cx,cy));//ROI区域的右上
Matq2(magnitudeImage,Rect(0,cy,cx,cy));//ROI区域的左下
Matq3(magnitudeImage,Rect(cx,cy,cx,cy));//ROI区域的右下
//交换象限(左上与右下进行交换)
Mattmp;
q0.copyTo(tmp);
q3.copyTo(q0);
tmp.copyTo(q3);
//交换象限(右上与左下进行交换)
q1.copyTo(tmp);
q2.copyTo(q1);
tmp.copyTo(q2);
//归一化,用0到1之间的浮点值将矩阵变换为可视的图像格式
normalize(magnitudeImage,magnitudeImage,0,1,CV_MINMAX);
//显示效果图
imshow("频域",magnitudeImage);
//(3)频域-->空域
Matinversed;
dft(complexI,inversed,DFT_INVERSE|DFT_REAL_OUTPUT);
normalize(inversed,inversed,0,1,CV_MINMAX);
imshow("空域",inversed);
waitKey();
return0;
}
其转换的原始图像及其效果图频域图像、空域图像分别如下图所示:
(1)
题目四:
对MNIST手写数字数据库(可在网上搜索下载),编程实现来提取其链码。
该题实现的具体思路过程为:
(1)将Mnist字库读取到以OpenCV里的Mat为储存单元的vector中;
(2)使用findContours将链码保存在vector中;
(3)输出链码。
#include
#include
#include
#include
#include
#include
#include
usingnamespacestd;
usingnamespacecv;
//格式转换
intReverseInt(inti)
{
unsignedcharch1,ch2,ch3,ch4;
ch1=i&255;
ch2=(i>>8)&255;
ch3=(i>>16)&255;
ch4=(i>>24)&255;
return((int)ch1<<24)+((int)ch2<<16)+((int)ch3<<8)+ch4;
}
/**
*将Mnist数据库读取到OpenCV:
:
Mat格式中
*格式:
*magicnumber
*numberofimages
*rows
*cols
*averyverylongvectorcontainsalldigits
*/
voidread_Mnist(stringfilename,vector&vec)
{
ifstreamfile(filename,ios:
:
binary);
if(file.is_open())
{
intmagic_number=0;
intnumber_of_images=0;
intn_rows=0;
intn_cols=0;
file.read((char*)&magic_number,sizeof(magic_number));
magic_number=ReverseInt(magic_number);
file.read((char*)&number_of_images,sizeof(number_of_images));
number_of_images=ReverseInt(number_of_images);
file.read((char*)&n_rows,sizeof(n_rows));
n_rows=ReverseInt(n_rows);
file.read((char*)&n_cols,sizeof(n_cols));
n_cols=ReverseInt(n_cols);
for(inti=0;i{
cv:
:
Mattp=Mat:
:
zeros(n_rows,n_cols,CV_8UC1);
for(intr=0;r{
for(intc=0;c{
unsignedchartemp=0;
file.read((char*)&temp,sizeof(temp));
tp.at(r,c)=(int)temp;
}
}
vec.push_back(tp);
}
}//if
}
intmain(intargc,char**argv)
{
intcount=1;
//存储Mnist字库
vectorvec;
//将Mnist字库读取到vector中
read_Mnist("t10k-images.idx3-ubyte",vec);
cout<<"共含有:
"<for(autoiter=vec.begin();iter!
=vec.end();iter++)
{
cout<<"第"<//显示Mnist字库
imshow("Mnist",*iter);
vector>contours;
//读取轮廓
findContours(*iter,contours,CV_RETR_EXTERNAL,CV_CHAIN_CODE);
//输出链码
for(inti=0;i{
for(intj=0;j{
cout<}
cout<}
waitKey(1000);
}
waitKey();
return0;
}
实现的效果图如下截图所示:
根据输出结果,所得到的链码并不是所熟悉的4方向和8方向链码,由于时间仓促,进一步的完善会在接下来的学习过程中继续进行。