Wiener Deconvolution Filter

1 개요

Blur 가 발생한 이미지를 복원하는 알고리즘 또는 Convolution 의 역연산 알고리즘.

2 알고리즘 상세 설명

RestoredX^=F1[HH2+SNRY]Restored\hat X = \mathcal{F}^{-1}[\frac {H^{*}}{H^{2} + SNR} Y]

H : 푸리에 변환된 Point Spread Function Kernel

H* : 푸리에 변환된 Point Spread Function Kernel의 Conjugation

Y : 푸리에 변환된 대상 이미지

2.1 Motion Blur

해당 Motion Blur 는 이미지 전반에 걸친 선형 모션 블러를 일컬으며 Blur(Convolution), Deblur(Deconvolution) 모두를 수행할 수 있습니다.

Source Image Motion Blur Image Restored Image
Source Image Motion Blur Image Restored Image
Fig. Motion Blur Convolution, Deconvolution 결과 이미지

Motion Blur Image 와 같이 이미지에 임의로 Motion Blur 를 적용할 수 있으며, Motion Blur가 적용된 이미지를 Restored Image 와 같이 복원할 수 있습니다.

2.2 Focal Blur

해당 Focal Blur는 Lens Blur 와 같은 의미로 사용되어지며 이미지에 촛점이 맞지 않아 발생하는 블러를 일컫습니다. 촛점이 센서 앞으로 맺히는 지 뒤에 맺히는 지에 따라 Front Focal, Back Focal 등으로 구분되지만, 해당 모드 설정 시 이상적인 Neutral Focal 기준으로 동작합니다. 그러나 Lens에 따라 발생할 수 있는 구면수차 조정 SA(Spherical Aberration) Tunning 기능을 활용하여 Neutral Focal 이 아닌 블러도 보정할 수 있습니다.

Source Image Focal Blur Image Restored Image
Source Image Focal Blur Image Restored Image
Fig. Focal Blur Convolution, Deconvolution 결과 이미지

Motion Blur 와 비슷한 조작으로 Convolution, Deconvolution 동작이 가능합니다.

2.3 User Defined

해당 모드는 사용자가 사전에 Blur 의 형태 또는 PSF Kernel 을 알고있는 경우 직접 입력을 통해 실행할 수 있는 기능입니다.

User Defined Psf Blur Image Deblur Image
User Defined Psf Blur Image Deblur Image
Fig. 사용자 지정 Psf를 사용한 Convolution, Deconvolution 결과 이미지

Convolution Filter 와 비슷한 조작으로 Kernel 입력과 저장 및 불러오기 동작이 가능합니다.

3 파라미터 설정 및 사용 방법

3.1 Motion, Focal Blur 공통 파라미터

멤버함수 파라미터 설 명
SetLength double f64Length IN Blur Length(Unit : Pixel)
SetOperationType EOperationType eOperationType IN 연산 타입
SetPSFType EPSFType ePSFType IN PSF 타입
SetSNR double f64SNR IN 신호 대 잡음비 값

3.2 Motion Blur 파라미터

멤버함수 파라미터 설 명
SetAngle double f64Angle IN Motion Blur 각도(Unit : Degree)
EnableWeightedKernel bool bWeightedKernel IN 가중치 커널 설정 적용 여부
PSF Kernel PSF Weighted Kernel
non Weighted Weighted
Fig. Kernel Angle : 33.25, Length : 20 커널 이미지

3.3 Focal Blur 파라미터

멤버함수 파라미터 설 명
EnableSATuning bool bSATuning IN 구면 수차 적용 여부
SetIntensity double f64Intensity IN Intensity 설정자
SetCutOffRatio double f64CutOffRatio IN CutOffRatio 설정자
Neutral Back Front
Neutral Focal Back Focal Fornt Focal
Fig. Focal Blur PSF 종류를 나타낸 이미지

3.4 User Difned PSF

SetKernel 함수를 통해 사용자 정의 PSF 를 입력하여 실행합니다. PSF 의 가로, 세로 크기를 지정하고 각 위치에서 Weight 값들의 상대적인 크기를 입력합니다. PSF 의 모든 Weight 값들은 합이 1인 정규화 프로세스를 거쳐 연산에 적용됩니다.

4 예제 코드

CWienerDeconvolutionFilter wiener;
CFLImage fliSourceImage;
wiener.SetSourceImage(fliSourceImage);

CFLImage fliDestinationImage;
wiener.SetDestinationImage(fliDestinationImage);

/* 
  Motion Blur(Convolution Type) 적용 예시
*/
wiener.SetOperationType(CWienerDeconvolutionFilter::EOperationType_Convolution);
wiener.SetPSFType(CWienerDeconvolutionFilter::EPSFType_Motion);
wiener.SetAngle(33.25);
wiener.SetLength(6.7);
wiener.Execute();

/* 
  Motion Blur(Deconvolution Type) 적용 예시
*/
wiener.SetOperationType(CWienerDeconvolutionFilter::EOperationType_Deconvolution);
wiener.SetPSFType(CWienerDeconvolutionFilter::EPSFType_Motion);
wiener.SetSNR(0.00001);
wiener.Execute();

/* 
  Focal Blur(Convolution Type) 적용 예시
*/
wiener.SetOperationType(CWienerDeconvolutionFilter::EOperationType_Convolution);
wiener.SetPSFType(CWienerDeconvolutionFilter::EPSFType_Focal);
wiener.SetLength(15.2);
wiener.Execute();

/* 
  Focal Blur(Deconvolution Type) 적용 예시
*/
wiener.SetOperationType(CWienerDeconvolutionFilter::EOperationType_Deconvolution);
wiener.SetPSFType(CWienerDeconvolutionFilter::EPSFType_Focal);
wiener.SetSNR(0.0001);
wiener.Execute();

/* 
  User Defined(Convolution Type) 적용 예시
*/
wiener.SetOperationType(CWienerDeconvolutionFilter::EOperationType_Convolution);
wiener.SetPSFType(CWienerDeconvolutionFilter::EPSFType_UserDefined);

CFLArray<CFLArray<CFLArray<float>>> flarrKernel;
flarrKernel.PushBack(CFLArray<CFLArray<float>>());
flarrKernel[0].PushBack(CFLArray<float>());
flarrKernel[0][0].PushBack(0.000000f);
flarrKernel[0][0].PushBack(0.000000f);
flarrKernel[0][0].PushBack(0.000000f);
flarrKernel[0][0].PushBack(5.000000f);
flarrKernel[0][0].PushBack(0.000000f);
flarrKernel[0][0].PushBack(0.000000f);
flarrKernel[0][0].PushBack(0.000000f);

flarrKernel[0].PushBack(CFLArray<float>());
flarrKernel[0][1].PushBack(0.000000f);
flarrKernel[0][1].PushBack(0.000000f);
flarrKernel[0][1].PushBack(0.000000f);
flarrKernel[0][1].PushBack(7.000000f);
flarrKernel[0][1].PushBack(0.000000f);
flarrKernel[0][1].PushBack(0.000000f);
flarrKernel[0][1].PushBack(0.000000f);

...

flarrKernel[0].PushBack(CFLArray<float>());
flarrKernel[0][6].PushBack(0.000000f);
flarrKernel[0][6].PushBack(0.000000f);
flarrKernel[0][6].PushBack(0.000000f);
flarrKernel[0][6].PushBack(5.000000f);
flarrKernel[0][6].PushBack(0.000000f);
flarrKernel[0][6].PushBack(0.000000f);
flarrKernel[0][6].PushBack(0.000000f);

wiener.SetKernel(flarrKernel);
wiener.Execute();

/* 
  User Defined(Deonvolution Type) 적용 예시
*/
wiener.SetOperationType(CWienerDeconvolutionFilter::EOperationType_Deconvolution);
wiener.SetPSFType(CWienerDeconvolutionFilter::EPSFType_UserDefined);
wiener.SetSNR(0.0001);
wiener.Execute();

CWienerDeconvolutionFilter wiener = new CWienerDeconvolutionFilter();
CFLImage fliSourceImage = new CFLImage();
CFLImage fliDestinationImage = new CFLImage();

wiener.SetSourceImage(ref fliSourceImage);
wiener.SetDestinationImage(ref fliDestinationImage);

/* 
  Motion Blur(Convolution Type) 적용 예시
*/
wiener.SetOperationType(CWienerDeconvolutionFilter.EOperationType.Convolution);
wiener.SetPSFType(CWienerDeconvolutionFilter.EPSFType.Motion);
wiener.SetAngle(33.25);
wiener.SetLength(6.7);
wiener.Execute();

/* 
  Motion Blur(Deconvolution Type) 적용 예시
*/
wiener.SetOperationType(CWienerDeconvolutionFilter.EOperationType.Deconvolution);
wiener.SetPSFType(CWienerDeconvolutionFilter.EPSFType.Motion);
wiener.SetSNR(0.00001);
wiener.Execute();

/* 
  Focal Blur(Convolution Type) 적용 예시
*/
wiener.SetOperationType(CWienerDeconvolutionFilter.EOperationType.Convolution);
wiener.SetPSFType(CWienerDeconvolutionFilter.EPSFType.Focal);
wiener.SetLength(15.2);
wiener.Execute();

/* 
  Focal Blur(Deconvolution Type) 적용 예시
*/
wiener.SetOperationType(CWienerDeconvolutionFilter::EOperationType.Deconvolution);
wiener.SetPSFType(CWienerDeconvolutionFilter.EPSFType.Focal);
wiener.SetSNR(0.0001);
wiener.Execute();

/* 
  User Defined(Convolution Type) 적용 예시
*/
wiener.SetOperationType(CWienerDeconvolutionFilter.EOperationType.Convolution);
wiener.SetPSFType(CWienerDeconvolutionFilter.EPSFType.UserDefined);

List<List<List<float>>> flarrKernel = new List<List<List<float>>>();
List<List<float>> flarrRowElement = new List<List<float>>();
List<float> flarrKernelElement = new List<float>();
flarrRowElement.Clear();
flarrKernelElement.Clear();
flarrKernelElement.Add(0.000000f);
flarrKernelElement.Add(0.000000f);
flarrKernelElement.Add(0.000000f);
flarrKernelElement.Add(0.000000f);
flarrKernelElement.Add(0.000000f);
flarrRowElement.Add(new List<float>(flarrKernelElement));

flarrKernelElement.Clear();
flarrKernelElement.Add(0.000000f);
flarrKernelElement.Add(5.000000f);
flarrKernelElement.Add(0.000000f);
flarrKernelElement.Add(0.000000f);
flarrKernelElement.Add(0.000000f);
flarrRowElement.Add(new List<float>(flarrKernelElement));

flarrKernelElement.Clear();
flarrKernelElement.Add(0.000000f);
flarrKernelElement.Add(0.000000f);
flarrKernelElement.Add(0.000000f);
flarrKernelElement.Add(0.000000f);
flarrKernelElement.Add(0.000000f);
flarrRowElement.Add(new List<float>(flarrKernelElement));

flarrKernelElement.Clear();
flarrKernelElement.Add(0.000000f);
flarrKernelElement.Add(0.000000f);
flarrKernelElement.Add(0.000000f);
flarrKernelElement.Add(7.000000f);
flarrKernelElement.Add(0.000000f);
flarrRowElement.Add(new List<float>(flarrKernelElement));

flarrKernelElement.Clear();
flarrKernelElement.Add(0.000000f);
flarrKernelElement.Add(0.000000f);
flarrKernelElement.Add(6.000000f);
flarrKernelElement.Add(0.000000f);
flarrKernelElement.Add(0.000000f);
flarrRowElement.Add(new List<float>(flarrKernelElement));

flarrKernel.Add(new List<List<float>>(flarrRowElement));

wiener.SetKernel(flarrKernel);
wiener.Execute();

/* 
  User Defined(Deonvolution Type) 적용 예시
*/
wiener.SetOperationType(CWienerDeconvolutionFilter::EOperationType_Deconvolution);
wiener.SetPSFType(CWienerDeconvolutionFilter::EPSFType_UserDefined);
wiener.SetSNR(0.0001);
wiener.Execute();
wiener = CWienerDeconvolutionFilter()
fliSourceImage = CFLImage()
fliDestinationImage = CFLImage()

wiener.SetSourceImage(fliSourceImage)
wiener.SetDestinationImage(fliDestinationImage)

# Motion Blur(Convolution Type) 적용 예시
wiener.SetOperationType(CWienerDeconvolutionFilter.EOperationType.Convolution)
wiener.SetPSFType(CWienerDeconvolutionFilter.EPSFType.Motion)
wiener.SetAngle(33.25)
wiener.SetLength(6.7)
wiener.Execute()

# Motion Blur(Deconvolution Type) 적용 예시

wiener.SetOperationType(CWienerDeconvolutionFilter.EOperationType.Deconvolution)
wiener.SetPSFType(CWienerDeconvolutionFilter.EPSFType.Motion)
wiener.SetSNR(0.00001)
wiener.Execute()

# Focal Blur(Convolution Type) 적용 예시

wiener.SetOperationType(CWienerDeconvolutionFilter.EOperationType.Convolution)
wiener.SetPSFType(CWienerDeconvolutionFilter.EPSFType.Focal)
wiener.SetLength(15.2)
wiener.Execute()

 
# Focal Blur(Deconvolution Type) 적용 예시

wiener.SetOperationType(CWienerDeconvolutionFilter.EOperationType.Deconvolution)
wiener.SetPSFType(CWienerDeconvolutionFilter.EPSFType.Focal)
wiener.SetSNR(0.0001)
wiener.Execute()

 
# User Defined(Convolution Type) 적용 예시

wiener.SetOperationType(CWienerDeconvolutionFilter.EOperationType.Convolution)
wiener.SetPSFType(CWienerDeconvolutionFilter.EPSFType.UserDefined)

flarrKernel = List[List[List[Single]]]()
flarrRowElement = List[List[Single]]()
flarrKernelElement = List[Single]()
flarrRowElement.Clear()
flarrKernelElement.Clear()
flarrKernelElement.Add(0.000000)
flarrKernelElement.Add(0.000000)
flarrKernelElement.Add(0.000000)
flarrKernelElement.Add(0.000000)
flarrKernelElement.Add(0.000000)
flarrRowElement.Add(List[Single](flarrKernelElement))

flarrKernelElement.Clear()
flarrKernelElement.Add(0.000000)
flarrKernelElement.Add(5.000000)
flarrKernelElement.Add(0.000000)
flarrKernelElement.Add(0.000000)
flarrKernelElement.Add(0.000000)
flarrRowElement.Add(List[Single](flarrKernelElement))

flarrKernelElement.Clear()
flarrKernelElement.Add(0.000000)
flarrKernelElement.Add(0.000000)
flarrKernelElement.Add(0.000000)
flarrKernelElement.Add(0.000000)
flarrKernelElement.Add(0.000000)
flarrRowElement.Add(List[Single](flarrKernelElement))

flarrKernelElement.Clear()
flarrKernelElement.Add(0.000000)
flarrKernelElement.Add(0.000000)
flarrKernelElement.Add(0.000000)
flarrKernelElement.Add(7.000000)
flarrKernelElement.Add(0.000000)
flarrRowElement.Add(List[Single](flarrKernelElement))

flarrKernelElement.Clear()
flarrKernelElement.Add(0.000000)
flarrKernelElement.Add(0.000000)
flarrKernelElement.Add(6.000000)
flarrKernelElement.Add(0.000000)
flarrKernelElement.Add(0.000000)
flarrRowElement.Add(List[Single](flarrKernelElement))

flarrKernel.Add(List[List[Single]](flarrRowElement))

wiener.SetKernel(flarrKernel)
wiener.Execute()

 
# User Defined(Deonvolution Type) 적용 예시

wiener.SetOperationType(CWienerDeconvolutionFilter.EOperationType.Deconvolution)
wiener.SetPSFType(CWienerDeconvolutionFilter.EPSFType.UserDefined)
wiener.SetSNR(0.0001)
wiener.Execute()

5 관련 알고리즘

Out Focus Deblurring, Motion Deblurring, Convolution Filter