图像配准 - 使用AForge.NET框架的相位相关算法(C#)

问题描述 投票:2回答:1

我一直用C#编写代码,用这种相位相关算法记录两个图像之间的移位(x,y轴),如维基百科中所示:Phase Correlation

为了帮助我,我正在使用AForge.NET Framework的ComplexImage类及其快速傅里叶变换方法。

代码如下所示:

 Bitmap fixed = (Bitmap)System.Drawing.Image.FromFile("Lenna.png");
 Bitmap shifted = (Bitmap)System.Drawing.Image.FromFile("Lenna2.png");

 //apply greyscale
 fixed = Grayscale.CommonAlgorithms.BT709.Apply(fixed);
 shifted = Grayscale.CommonAlgorithms.BT709.Apply(shifted);

 ComplexImage fixedCplx = ComplexImage.FromBitmap(fixed);
 int height = fixedCplx.Data.GetLength(0);
 int width  = fixedCplx.Data.GetLength(1);
 ComplexImage shiftedCplx = ComplexImage.FromBitmap(shifted);

 fixedCplx.ForwardFourierTransform();
 shiftedCplx.ForwardFourierTransform();

 for (int y = 0; y < height; y++)
 {
     for (int x = 0; x < width; x++)
     {
         //Calculating elementwise complex conjugate of the shifted image 2d vector
         shiftedCplx.Data[y, x].Im = -1 * shiftedCplx.Data[y, x].Im;
         //Elementwise multiplication to obtain cross power spectrum
         shiftedCplx.Data[y, x] = Complex.Multiply(fixedCplx.Data[y, x], shiftedCplx.Data[y, x]);
         //Elementwise normalization
         shiftedCplx.Data[y, x] = Complex.Divide(shiftedCplx.Data[y, x], shiftedCplx.Data[y, x].Magnitude);
     }
 }
 shiftedCplx.BackwardFourierTransform();

然而,计算逆变换时应该出现的峰值函数并没有显示出来......我已经使用维基百科链接上的图片进行了测试,但我得到的结果是白色图片。上面显示的代码有什么问题吗?

一些考虑:

  • 也许我不理解算法背后的数学。当采用元素乘积[Ga]。[Gb *]时,这个*符号是否意味着我需要像我一直在共轭矩阵的每个元素?或者它是矩阵的conjugate transpose
  • 归一化[Ga]。[Gb *] / | [Ga]。[Gb *] |,将每个矩阵元素(都是复数)除以其大小是否正确?我已经在我的代码中完成了这个并且正如预期的那样,在算法结束时,shiftedCplx.Data[]数组中的每个元素都具有幅度= 1(这意味着此时所有相关信息都是它们的相位)。

看起来'BackwardFourierTransform()`函数并没有按预期工作,或者在我修改数据的过程中的某个地方。

编辑1

刚刚编写的代码是jaket在评论中指出的。

另外,我刚刚意识到一件事:当傅立叶变换灰度图像时,相应的2D矢量中的每个值的范围都是0到255.对我来说,暗示逆变换也会在该范围之间产生一些值(即使数据事先规范化了,但我发现在这种情况下并非如此。 shiftedCplx.Data[,]矢量中的大多数元素在被转换回空间域后将具有大于255的值,当然,从其中制作位图图像会创建大部分全白的图像。有什么我想念的吗?

c# algorithm image-processing fft aforge
1个回答
0
投票

在POC中,F * G不是矩阵的乘法,而是矩阵的元素生成。

所以,它被称为Hadamard Production。

在matlab中,该生产由“。*”运算符操作。

但是在AForge.net的Complex.functions中,没有这样的操作,可能是......

    // 푸리에 변환 한 이미지를 현실과 상상의 부분 분해
    Cv.Split (dft1, srcRe1, srcIm1, null , null );
    Cv.Split (dft2, srcRe2, srcIm2, null , null );

    for  ( int  I = 0; i <dft_M; i ++)
    {
        for  ( int  J = 0; j <dft_N; j ++)
        {
            // 이미지를  F × G *
            dstRe [i, j] = srcRe1 [i, j] * srcRe2 [i, j] - srcIm1 [i, j] * srcIm2 [i, j];
            dstIm [i, j] = srcRe1 [i, j] * srcIm2 [i, j + srcRe2 [i, j] * srcIm1 [i, j];

            // 절대 값을 계산하고 그 값으로 나누면 | F × G * |
            double  Spectrum = Math.Sqrt (dstRe [i, j] * dstRe [i, j + dstIm [i, j] * dstIm [i, j]);
            dstRe [i, j] = dstRe [i, j] / spectrum;
            dstIm [i, j] = dstIm [i, j] / spectrum;
        }
    }
    // 계산 결과를 통합
    Cv.Merge (dstRe, dstIm, null , null , result);

我希望这有帮助。我还需要你完成的POC代码。我也是AForge.Net用户〜。 (_:

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.