问题描述
我试图想象与EMGU图像的FFT。下面是我在处理图像:
下面是预期的结果:
下面是我得到:
下面是我的代码:
图片<灰,浮>图像=新的图像<灰色,浮动>(@C:\Users\me\Desktop\sample3.jpg);
的IntPtr complexImage = CvInvoke.cvCreateImage(image.Size,Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_32F,2);
CvInvoke.cvSetZero(complexImage);
CvInvoke.cvSetImageCOI(complexImage,1);
CvInvoke.cvCopy(图像,complexImage,IntPtr.Zero);
CvInvoke.cvSetImageCOI(complexImage,0);
矩阵和LT;浮动> DFT =新的Matrix<浮动>(image.Rows,image.Cols,2);
CvInvoke.cvDFT(complexImage,干膜,Emgu.CV.CvEnum.CV_DXT.CV_DXT_FORWARD,0);
矩阵和LT;浮动> outReal =新的Matrix<浮动>(image.Size);
矩阵和LT;浮动> outIm =新的Matrix<浮动>(image.Size);
CvInvoke.cvSplit(DFT,outReal,outIm,IntPtr.Zero,IntPtr.Zero);
形象和LT;灰,浮> fftImage =新的图像<灰色,浮动>(outReal.Size);
CvInvoke.cvCopy(outReal,fftImage,IntPtr.Zero);
pictureBox1.Image = image.ToBitmap();
pictureBox2.Image = fftImage.Log()ToBitmap();
什么错误我是做在这里?
更新:这里按罗杰·罗兰的建议是我更新的代码。结果看起来更好,但我不是100%肯定它是正确的。这里的结果:结果
图片<灰,浮>图像=新的图像<灰色,浮动>(@C:\Users\yytov\Desktop\sample3.jpg);
的IntPtr complexImage = CvInvoke.cvCreateImage(image.Size,Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_32F,2);
CvInvoke.cvSetZero(complexImage); //初始化到零
CvInvoke.cvSetImageCOI所有元素(complexImage,1);
CvInvoke.cvCopy(图像,complexImage,IntPtr.Zero);
CvInvoke.cvSetImageCOI(complexImage,0);
矩阵和LT;浮动> DFT =新的Matrix<浮动>(image.Rows,image.Cols,2);
CvInvoke.cvDFT(complexImage,干膜,Emgu.CV.CvEnum.CV_DXT.CV_DXT_FORWARD,0);
//傅立叶的实部变换
矩阵和LT;浮动> outReal =新的Matrix<浮动>(image.Size);
//傅立叶的虚部变换
矩阵和所述;浮> outIm =新的Matrix<浮动>(image.Size);
CvInvoke.cvSplit(DFT,outReal,outIm,IntPtr.Zero,IntPtr.Zero);
CvInvoke.cvPow(outReal,outReal,2.0);
CvInvoke.cvPow(outIm,outIm,2.0);
CvInvoke.cvAdd(outReal,outIm,outReal,IntPtr.Zero);
CvInvoke.cvPow(outReal,outReal,0.5);
CvInvoke.cvAddS(outReal,新MCvScalar(1.0),outReal,IntPtr.Zero); // 1 +马格
CvInvoke.cvLog(outReal,outReal); //日志(1 + MAG)
//交换象限
INT CX = outReal.Cols / 2;
INT CY = outReal.Rows / 2;
矩阵和LT;浮动> Q0 = outReal.GetSubRect(新的Rectangle(0,0,CX,CY));
矩阵和LT;浮动> Q1 = outReal.GetSubRect(新的Rectangle(CX,0,CX,CY));
矩阵和LT;浮动> Q2 = outReal.GetSubRect(新的Rectangle(0,CY,CX,CY));
矩阵和LT;浮动> Q3 = outReal.GetSubRect(新的Rectangle(CX,CY,CX,CY));
矩阵和LT;浮动> TMP =新的Matrix<浮动>(q0.Size);
q0.CopyTo(TMP);
q3.CopyTo(Q0);
tmp.CopyTo(Q3);
q1.CopyTo(TMP);
q2.CopyTo(Q1);
tmp.CopyTo(Q2);
CvInvoke.cvNormalize(outReal,outReal,0.0,255.0,Emgu.CV.CvEnum.NORM_TYPE.CV_MINMAX,IntPtr.Zero);
形象和LT;灰,浮> fftImage =新的图像<灰色,浮动>(outReal.Size);
CvInvoke.cvCopy(outReal,fftImage,IntPtr.Zero);
pictureBox1.Image = image.ToBitmap();
pictureBox2.Image = fftImage.ToBitmap();
我不能对大小/评论所产生的强度形象,但我可以给你一个点的图像的空间分布提示。
OpenCV的不重新排列象限把原点[0,0]成图像的中心。你必须手动重新排列象限
看第6步在以下页面:
的
这对OpenCV的官方文档,因此它在C ++中,但原则也适用。
I'm trying to visualize the FFT of an image with EMGU. Here's the image I'm processing:
Here's the expected result:
Here's what I get:
Here's my code:
Image<Gray, float> image = new Image<Gray, float>(@"C:\Users\me\Desktop\sample3.jpg");
IntPtr complexImage = CvInvoke.cvCreateImage(image.Size, Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_32F, 2);
CvInvoke.cvSetZero(complexImage);
CvInvoke.cvSetImageCOI(complexImage, 1);
CvInvoke.cvCopy(image, complexImage, IntPtr.Zero);
CvInvoke.cvSetImageCOI(complexImage, 0);
Matrix<float> dft = new Matrix<float>(image.Rows, image.Cols, 2);
CvInvoke.cvDFT(complexImage, dft, Emgu.CV.CvEnum.CV_DXT.CV_DXT_FORWARD, 0);
Matrix<float> outReal = new Matrix<float>(image.Size);
Matrix<float> outIm = new Matrix<float>(image.Size);
CvInvoke.cvSplit(dft, outReal, outIm, IntPtr.Zero, IntPtr.Zero);
Image<Gray, float> fftImage = new Image<Gray, float>(outReal.Size);
CvInvoke.cvCopy(outReal, fftImage, IntPtr.Zero);
pictureBox1.Image = image.ToBitmap();
pictureBox2.Image = fftImage.Log().ToBitmap();
What mistake am I making here?
Update: as per Roger Rowland's suggestion here's my updated code. The result looks better but I'm not 100% sure it's correct. Here's the result:
Image<Gray, float> image = new Image<Gray, float>(@"C:\Users\yytov\Desktop\sample3.jpg");
IntPtr complexImage = CvInvoke.cvCreateImage(image.Size, Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_32F, 2);
CvInvoke.cvSetZero(complexImage); // Initialize all elements to Zero
CvInvoke.cvSetImageCOI(complexImage, 1);
CvInvoke.cvCopy(image, complexImage, IntPtr.Zero);
CvInvoke.cvSetImageCOI(complexImage, 0);
Matrix<float> dft = new Matrix<float>(image.Rows, image.Cols, 2);
CvInvoke.cvDFT(complexImage, dft, Emgu.CV.CvEnum.CV_DXT.CV_DXT_FORWARD, 0);
//The Real part of the Fourier Transform
Matrix<float> outReal = new Matrix<float>(image.Size);
//The imaginary part of the Fourier Transform
Matrix<float> outIm = new Matrix<float>(image.Size);
CvInvoke.cvSplit(dft, outReal, outIm, IntPtr.Zero, IntPtr.Zero);
CvInvoke.cvPow(outReal, outReal, 2.0);
CvInvoke.cvPow(outIm, outIm, 2.0);
CvInvoke.cvAdd(outReal, outIm, outReal, IntPtr.Zero);
CvInvoke.cvPow(outReal, outReal, 0.5);
CvInvoke.cvAddS(outReal, new MCvScalar(1.0), outReal, IntPtr.Zero); // 1 + Mag
CvInvoke.cvLog(outReal, outReal); // log(1 + Mag)
// Swap quadrants
int cx = outReal.Cols / 2;
int cy = outReal.Rows / 2;
Matrix<float> q0 = outReal.GetSubRect(new Rectangle(0, 0, cx, cy));
Matrix<float> q1 = outReal.GetSubRect(new Rectangle(cx, 0, cx, cy));
Matrix<float> q2 = outReal.GetSubRect(new Rectangle(0, cy, cx, cy));
Matrix<float> q3 = outReal.GetSubRect(new Rectangle(cx, cy, cx, cy));
Matrix<float> tmp = new Matrix<float>(q0.Size);
q0.CopyTo(tmp);
q3.CopyTo(q0);
tmp.CopyTo(q3);
q1.CopyTo(tmp);
q2.CopyTo(q1);
tmp.CopyTo(q2);
CvInvoke.cvNormalize(outReal, outReal, 0.0, 255.0, Emgu.CV.CvEnum.NORM_TYPE.CV_MINMAX, IntPtr.Zero);
Image<Gray, float> fftImage = new Image<Gray, float>(outReal.Size);
CvInvoke.cvCopy(outReal, fftImage, IntPtr.Zero);
pictureBox1.Image = image.ToBitmap();
pictureBox2.Image = fftImage.ToBitmap();
I cannot comment on the magnitude/intensity of the resulting image, but I can give you a tip about the spatial distribution of points in your image.
OpenCV doesn't rearrange the quadrants to put origin [0,0] into center of image. You have to rearrange the quadrants manually.
Look at step 6 at the following page:http://docs.opencv.org/doc/tutorials/core/discrete_fourier_transform/discrete_fourier_transform.html
It's official doc for OpenCV, so it's in C++, but principle holds.
这篇关于图像EMGU / OpenCV的FFT没有产生预期的效果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!