초보자를 위한 Blurring 기술 - 1

2023. 4. 8. 19:44프로그래밍

728x90

소개

이것은 초보자를 위한 blurring 기술에 대한 짧은 튜토리얼 입니다. 이 기술에 대한 유용한 자료가 내가 막상 시작 했을 때엔 거의 없었습니다. 그것은 물론 정확한 얘기는 아니구요 – 정말 많은 자료들이 있었습니다만, 그 중 절반은 너무 단순했고 나머지 절반은 "T를 반 개방 간격으로 계산 된 벡터 함수라고 합시다 ..."라고 시작하며 그 큰 시그마 기호와 사물을 가진 여러 줄 방정식들이 나를 너무 겁을 주었죠.. 이 문서는 이 무서운 얘기의 약이 될 수 있을 겁니다. 자바의 소스 코드를 사용하여 다양한 종류의 흐림 효과와 그 효과를 사용 할 수 있도록 지금부터 해보도록 합시다.

 

A Disclaimer

(소프트웨어에 사용되는 말. 소프트웨어의 사용으로 인한 어떤 손해에 대해서도 그 소프트웨어의 판매자는 책임이 없다는 것)

 

blurring이 언급 될 때마다 항상 "이봐요! 실제 blur 효과가 아니잖아요!"라고 말하는 사람이 있습니다. 또는 녹색 잉크로 화가 난 편지를 쓰거나 쓰인 수학이 의심스럽거나 HAL-9000에서 sponglerizer 레지스터를 사용하는 훨씬 더 빠른 방법 있다고 말하는 이 사람들을 무시하겠습니다.

이것은 큰 주제이며 이 튜토리얼은 초보자를 위한 것입니다.

(그건 제가 자랑스럽게 말할 수 있습니다.) 중요한 것은 당신이 생각하는 결과를 얻었느냐는 것입니다. 그리고 목표로 삼고 있는 결과가 모호한 수학을 필요로 한다면, 그렇게 하십시오. 목표로 삼고 있는 결과로 나에게 끔찍한 표정을 짓게 되더라도, 그 나름 당신에게 그것이 잘된 것이라면 괜찮을 것 같네요.

 

Another Disclaimer

 

여기에서 내가 말한 모든 내용에 대해 자바로 만들어진 소스 코드가 있습니다. 나는 이 코드들이 어떤 식 으로 든 최적화되었다고 생각하지 않습니다 - 속도를 넘어선 단순함을 선택했습니다. 그리고 여러분은 아마도 이러한 것들을 대부분 노력으로 더 빠르게 할 수 있을 것입니다. 상업적 목적을 포함하여 원하는 모든 것을 소스 코드로 사용할 수는 있지만 책임은 지지 않습니다. 원자력 발전소 나 미사일 시스템이 부적절한 blur 효과로 인해 실패한다면, 그건 내 잘못이 아닙니다.

 

Blurring이 뭘까?

 

우리 모두는 blurring의 영어적 의미가 무엇인지 알고 있습니다. 그렇지 않나요? 이 효과를 설명해 보라면 카메라에 초점이 맞지 않거나 개가 안경을 훔칠 때 일어나는 일일 것입니다. 무슨 일이 일어나는가에 대해 명확한 관점으로 보아야 하는 것이 디스크 모양으로 번져 있는 것입니다.

이미지 용어에서 이것은 소스 이미지의 각 픽셀이 주변 픽셀로 퍼져 혼합된다는 것을 의미합니다.

이렇게 보여지는 또 다른 방법은 대상 이미지의 각 픽셀이 소스 이미지의 주변 픽셀 혼합으로 구성된다는 것입니다.

 

 

이를 위해 필요한 작업을 컨볼루션 (convolution)이라고합니다. 복잡하게 들리지만 수학자들이 마법의 공기를 유지하고 자금 조달을 유지하기 위해 복잡한 소리를 내기를 좋아하기 때문에 그렇습니다. 글쎄, 나는 그들과 만나서 이 컨볼루션 (convolution)이 복잡하지 않다는 것을 말해 줄 수 있을 겁니다

(어쨌든 내 수준에서). 이 컨볼루션이 동작하는 방식은 다음과 같습니다.

우리는 이미지 위에 직사각형의 숫자 ​​배열을 밀어 넣는 것을 상상 봅시다. 이 배열을 컨볼루션 커널이라고 합니다.

이미지의 모든 픽셀에 대해 커널과 픽셀에서 해당 숫자를 가져 와서 곱한 다음 모든 결과를 함께 추가하여 새 픽셀을 만듭니다.

예를 들어, 각 픽셀과 그 바로 옆에있는 8 개의 이웃을 평균으로 계산하는 아주 단순한 blur 효과를 원한다고 다음과 같이 상상해 볼 수 있습니다.

 

우리가 필요한 커널은 다음과 같습니다:

1/9 1/9 1/9
1/9 1/9 1/9
1/9 1/9 1/9
 

 이들 모두가 모두 1에 가깝다는 것을 알 수 있습니다.

이는 결과 이미지가 원래 이미지와 똑같을 것임을 의미합니다.

더 이상 고민할 필요없이 Java로 이미지 blur 효과를 만들어 봅시다. 모든 convolution 정보는 구현하기 까다로워 보이지만, 다행스럽게도 Java에는 내장형 즉시 사용 연산자가 포함되어 있습니다.

ConvolveOp가 바로 그것입니다.

 

 

코드는 아래와 같습니다:

float[] matrix = {
	0.111f, 0.111f, 0.111f,
	0.111f, 0.111f, 0.111f,
	0.111f, 0.111f, 0.111f,
};

BufferedImageOp op = new ConvolveOp( new Kernel(3, 3, matrix) );
blurredImage= op.filter(sourceImage, destImage);
 

 

 

 

 

 

The Original and Blurred Images

 

환상적이네요! Blurry 화 된 이미지입니다! 너무 희미하지 않지만요, 그럼 좀 더 크게 흐려지게 해 봅시다:

float[]matrix = new float[400];
for(int i = 0; i < 400; i++)

matrix[i]= 1.0f/400.0f;

BufferedImageOp op = new ConvolveOp( new Kernel(20, 20, matrix), ConvolveOp.EDGE_NO_OP, null );
blurredImage= op.filter(sourceImage, destImage)
 
 

 

 

Big Blur with ConvolveOp

 

흠. 잘되지 않네요. 이 오퍼레이션은 정말 오랜 시간이 걸렸을 뿐만 아니라 결과도 약간 이상합니다.

모든 것이 제대로 된 것 같은 데, 정사각형 가장자리에서는 도대체 어떤 일이 발생 했을까요?

 

첫 번째 가장자리들 : ConvolveOp는 이미지의 가장자리에서 떨어져 버리는 것을 두려워하는 소심한 namby-pamby 같은 놈입니다.

 

커널이 이미지의 가장자리를 겹치게되면 그냥 포기하고 그냥 픽셀을 변경하지 않고 남겨 둔다는 것이죠.

 

이를 EDGE_NO_OP 대신 EDGE_ZERO_FILL을 전달하면 이 값을 변경할 수 있지만 더 이상해 지죠- 가장자리가 둥근 픽셀이 0으로 설정되어 효과적으로 사라져 버린다는 것입니다.

 

어떻게 해야 할까요? 글쎄, 우리는 blurring 전에 가장자리 주변의 이미지를 채우고 결과를 자르면 되지만, 그건 그냥 포기하는 것이고 더욱이 우리는 여기에서 아무것도 배울 수 없을 것입니다.

 

대신, 우리는 가장자리의 적절하면서, 두려움이 없으면서, 말도 안되는 연산자를 작성할 것입니다. 우리는 이 메서드를 ConvolveOp메서드와 구별하기 위해 ConvolveFilter메서드라고 부를 것입니다.

 

나는 이 기사에서 소스에 대한 자세한 내용을 다루지는 않을 것입니다. 시간이나 공간이 충분하지 않고 또 아직 작성해야 할 필터가 더 많이 남았거든요. 대신 소스를 다운로드 하거나 볼 수 있으며 코드는 충분히 가독성이 있다고 생각합니다.

 

실제 필자의 사이트를 찾아보는 것이 좋을 듯...

 

이상.


 

728x90