이제는 속도와 사각형 모양의 흐려짐 문제를 동시에 해결할 때입니다. 흐림에 대한 정사각형 모양을 제거하려면 원형 모양의 커널이 필요합니다. 불행히도 Box blur에 사용 된 트릭은 원과 함께 작동하지 않지만 허점이 있습니다. 커널에 올바른 프로파일 (가우스 프로파일)이 있는 경우 우리가 Box blur에서 했던 것처럼 두 번의 1D 흐림을 수행하여 2D 흐림을 수행 할 수 있습니다. 슬라이딩 윈도우 트릭이 작동하지 않기 때문에 너무 빠르지 않지만 2D 컨볼루션보다 훨씬 빠릅니다. 필요한 프로파일은 익숙한 종 모양 또는 가우스 곡선이 됩니다:
Gaussian Blur
다음은 주어진 반지름에 대해 1D 가우스 커널을 만드는 코드입니다. 우리가해야 할 일은 이것을 한 번 수평으로 그리고 한 번 수직으로 두 번 적용하는 것입니다. 보너스로 사용하기 쉽도록 Gaussian 필터로 포장했습니다.
View GaussianFilter.java
이것이 가우시안 Blur가 모든 그래픽 패키지에서 발견되는 이유입니다. 다른 Blur 유형보다 훨씬 빠릅니다. 유일한 문제는 카메라 렌즈를 시뮬레이션 할 때 그렇게 실제 현실적으로 보이지 않는다는 것입니다만, 그 후에는 더 많은 것이 있을 것입니다. 그림자 시뮬레이션과 같은 작업을 원한다면 Gaussian Blur 또는 심지어 박스 Blur도 괜찮을 것입니다. 이러한 모든 효과들을 원하는 곳이 존재합니다. 현실적이지 않기 때문에 유용하지 않다는 것을 의미하지는 않습니다.
가우시안 블러는 훨씬 빠르지 만 이전에 했던 Box blur만큼이나 빠르지는 않습니다. 이 둘을 결합 할 방법이 있다면 말입니다. 하나 정도는 지금부터 짐작할 수 있을 것 같아서, 이 궁금증을 풀어보도록 하겠습니다. Box Blur 효과를 많이 수행 한다면 결과는 점점 가우시안 Blur처럼 보일 것입니다. 사실, 남는 시간이 있다면 이를 수학적으로 증명할 수 있습니다 (증명법에 대해서 관심이 없으므로 얘기하지는 않겠습니다). 실제로 3 ~ 5 개의 상자 흐림 효과를 반복하면 아주 잘 보입니다. 말로만으로 상상하지 말고. 위의 box blur 애플릿에는 "반복"슬라이더가 있으므로 직접 시도해 볼 수 있을 것입니다.
(애플릿이 없음….)
Box Blur: 1, 2 and 3 iterations
필자의 경우에서처럼 나도 이 이론에 대해서 관심이 없다.. 라는 것보다는공부를 중점적으로 할 생각은 그렇게 느끼지 못한다. Github에 내가 작성한 PPMProcessing.java2 파일에서 내용을 보면 다음과 같다.
static class GaussianBlurTest implements Blurring
{
private static final String Gaussian_src_path = CAR_IMAGE_STRING;
private static final String Gaussian_path= CONV_CAR_IMAGE_STRING.replace("{filter}", "gauss");
private PPMImage Gaussian_src;
private PPMImage Gaussian_img;
private GaussianFilter convfilter;
GaussianBlurTest()
{
Gaussian_src = PPMImage.read(Gaussian_src_path);
Gaussian_img = new PPMImage(Gaussian_src.getHeight(), Gaussian_src.getWidth());
}
@Override
public void doBlur() {
convfilter = new GaussianFilter(15);
convfilter.filter(Gaussian_src, Gaussian_img);
}
@Override
public boolean makeImageBlurred() {
boolean success = false;
try {
PPMImage.writeToFile(Gaussian_path, Gaussian_img);
} catch (Exception e) {
e.printStackTrace();
}
return success;
}
@Override
public String toString()
{
return convfilter.toString();
}
}
Blurring 이라는 인터페이스를 하나 만들어서 필터 테스트를 위한 팩토리 클래스를 하나 만들었고 doBlur 메서드를 공통적으로 쓰도록 한다.
PPM 파일 이미지를 읽어 들이는 클래스를 따로 만들어서 구현 하였다. 계속적으로 예로 사용하는 차량 이미지를 이 필터로 돌려 보도록 하자.
결과물에 대해서는 다음과 같다.
이렇게 된다. 필자의 말이 맞다면Box Blur를 반복 수행 할 경우에는 어떻게 될 것 인가인데..
다음과 같이 인터페이스를 하나 빼서 구현을 하려고 한다.
public abstract void filter(final PPMImage src, final PPMImage dst, finalint iterCnt );
여기서 반복 수를 3과 5로 설정해서 한번 보도록 한다.
일단 한번 수행한 결과는
다음은 세번 수행한 결과
마지막으로 다섯번 수행한 결과이다.
실험의 결과는 가우시안 Blur 효과를 내기 위해서 Box Blur를 반복적으로 수행하면 된다 이다.
이상으로 가우시안 흐림 효과에 대해서 알아보았다.
테스트 클래스와 구현은 내 github3에 올려 놓았다.
'프로그래밍' 카테고리의 다른 글
초보자를 위한 클라우트 컴퓨팅 자습서 (1) | 2023.04.09 |
---|---|
초보자를 위한 Blurring 기술 - 1 (0) | 2023.04.08 |
초보자를 위한 이미지 Blurring 기술 - 2 (0) | 2023.04.06 |
[C#] 인라인 함수 사용하기 (0) | 2023.04.04 |
[자바] 부울 값을 정수 값으로 변환하기 (0) | 2023.04.03 |