Phase Only Correlation - AForge
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using AForge;
using AForge.Imaging;
using AForge.Imaging.ComplexFilters; // for FFT
using AForge.Imaging.Filters; // for Smoothing
using AForge.Math;
namespace winForm1
{
public partial class Form1 : Form
{
Bitmap image; // Global Bitmap
Bitmap image2;
private bool _drawRect = false;
private bool _drawCircle = false;
public Form1()
{
InitializeComponent();
pictureBox1.Paint += new PaintEventHandler(this.pictureBox1_Paint);
// load image
image =
AForge.Imaging.Image.FromFile(@"C:\Users\user\Pictures\tiger22.png");
image2 =
AForge.Imaging.Image.FromFile(@"C:\Users\user\Pictures\tiger22.png");
}
// Calc FFT2 when button --------------------------------------------
private void button1_Click(object sender, EventArgs e)
{
// create complex image
ComplexImage complexImage = ComplexImage.FromBitmap(image);
// do forward Fourier transformation
complexImage.ForwardFourierTransform();
// get complex image as bitmat
Bitmap fourierImage = complexImage.ToBitmap();
pictureBox1.Image = fourierImage;
}
// show Original Image --------------------------------------------
private void Form1_Load(object sender, EventArgs e)
{
pictureBox2.Image = image;
pictureBox1.Image = image2;
pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
pictureBox2.SizeMode = PictureBoxSizeMode.Zoom;
pictureBox3.SizeMode = PictureBoxSizeMode.Zoom;
}
// form exit ------------------------------------------------------
private void button2_Click(object sender, EventArgs e)
{
this.Close();
}
// circle drawing button ------------------------------------------
private void button3_Click(object sender, EventArgs e)
{
_drawRect = false;
_drawCircle = true;
pictureBox1.Invalidate();
MessageBox.Show("Good~!");
}
// picBox Paint event ------------------------------------------------
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if (_drawRect){
Graphics g = e.Graphics;
// use g to do your drawing
Rectangle rect = new Rectangle(100, 100, 10, 10);
e.Graphics.DrawRectangle(new Pen(Color.Green, 20), rect);
}
if (_drawCircle)
{
Graphics g = e.Graphics;
// use g to do your drawing
Rectangle rect = new Rectangle(108, 108, 40, 40);
e.Graphics.DrawEllipse(new Pen(Color.Red, 1), rect);
}
}
// Calc LPF with FFT2 ----------------------------------------------
private void button4_Click(object sender, EventArgs e)
{
// create complex image
ComplexImage complexImage = ComplexImage.FromBitmap(image);
// do forward Fourier transformation
complexImage.ForwardFourierTransform();
// create filter
FrequencyFilter filter = new FrequencyFilter(new IntRange(0, 20));
// apply filter
filter.Apply(complexImage);
// do backward Fourier transformation
complexImage.BackwardFourierTransform();
// get complex image as bitmat
Bitmap fourierImage = complexImage.ToBitmap();
// create filter
HistogramEqualization filter2 = new HistogramEqualization();
// process image
filter2.ApplyInPlace(fourierImage);
pictureBox1.Image = fourierImage;
}// button4
// Calc POC ------------------------------------------------------
private void button5_Click(object sender, EventArgs e)
{
// 이미지들 로드
Bitmap fix1 = (Bitmap)pictureBox2.Image;
Bitmap shift1 = (Bitmap)pictureBox1.Image;
// 그레이 이미지화.
fix1 = Grayscale.CommonAlgorithms.BT709.Apply(fix1) ;
shift1 = Grayscale.CommonAlgorithms.BT709.Apply(shift1);
//pictureBox1.Image = fix1;
//pictureBox2.Image = shift1;
// 복소 이미지버퍼화.
ComplexImage fixedCplx = ComplexImage.FromBitmap(fix1) ;
int height = fixedCplx.Data.GetLength(0);
int width = fixedCplx.Data.GetLength(1);
ComplexImage shiftedCplx = ComplexImage.FromBitmap(shift1);
//
ComplexImage SonCplx = ComplexImage.FromBitmap(shift1);
ComplexImage MomCplx = ComplexImage.FromBitmap(shift1);
// 2D FFT
fixedCplx.ForwardFourierTransform();
shiftedCplx.ForwardFourierTransform();
//pictureBox1.Image = fixedCplx.ToBitmap();
// 복소영상의 모든 픽셀에 대해.
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
// 푸리에 분자곱
SonCplx.Data[y, x].Re =
fixedCplx.Data[y, x].Re * shiftedCplx.Data[y, x].Re -
fixedCplx.Data[y, x].Im * shiftedCplx.Data[y, x].Im;
SonCplx.Data[y, x].Im =
fixedCplx.Data[y, x].Re * shiftedCplx.Data[y, x].Im +
shiftedCplx.Data[y, x].Re * fixedCplx.Data[y, x].Im;
// 이미지를 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];
}
}
double Spectrum = 0;
// 복소영상의 모든 픽셀에 대해.
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
//Elementwise normalization
Spectrum = Math.Sqrt(SonCplx.Data[y, x].Re *
SonCplx.Data[y, x].Re +
SonCplx.Data[y, x].Im * SonCplx.Data[y, x].Im);
// 푸리에 분자곱 나누기 분모곱 절대값
MomCplx.Data[y, x].Re =
SonCplx.Data[y, x].Re / Spectrum;
MomCplx.Data[y, x].Im =
SonCplx.Data[y, x].Im / Spectrum;
// 절대 값을 계산하고 그 값으로 나누면 | 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;
}
}
// 푸리에 역변환.
//MomCplx.BackwardFourierTransform();
MomCplx.ForwardFourierTransform();
// get complex image as bitmat
Bitmap bmpFour = MomCplx.ToBitmap();
// Brighten filter
//BrightnessCorrection filter = new BrightnessCorrection(5);
// apply the filter
//filter.ApplyInPlace(fourierImage);
// Median filter
//GaussianBlur filter = new GaussianBlur();
// apply the filter
//filter.ApplyInPlace(bmpFour);
pictureBox3.Image = bmpFour;
MessageBox.Show("IFFT, Success~");
// collect statistics
ImageStatistics his =
new ImageStatistics(bmpFour);
// get gray histogram (for grayscale image)
Histogram histogram = his.Gray;
MessageBox.Show("Gray Max = " + histogram.Max.ToString());
}
}// class Form1
}// namespace
댓글
댓글 쓰기