
위 사진은 위키피디아에서 Kernel(Image Processing)부분을 가져온 것이다.
이미지에 행렬의 형태를 하고 있는 Kenel을 적용하면 사진을 흐리게 하거나 날카롭게 하는 등 다양한 효과를 줄 수 있다.
행렬에 있는 숫자를 모두 더하면 1이라는 공통점이 있다.

이미지에 Kernel을 적용하는 것을 Convolution이라고 한다.
이미지의 원본 픽셀 값에 Kernel 값을 곱한 값이 최종 이미지의 값이 된다.

위 그림은 2차원 커널을 적용한 것인데, 원본 이미지 픽셀에서 없는 부분은 가장 가까운 픽셀값에서 끌어온다.
그리고 3x3 행렬에서 같은 위치에 있는 픽셀 값과 커널 값을 곱하고 모두 더한 값을 최종 이미지 픽셀(초록색)에 저장한다.
예시로 Blur을 만들기 위해서 Separable Convolution을 사용할텐데 2차원 커널을 적용하는 것이 아니라 x축으로 1차원 커널을 만들어서 적용을 한 후에 y축으로 1차원 커널을 만들어 적용하는 분리된 (Separable) Convolution이다.
const float weights[5] = { 0.0545f, 0.2442f, 0.4026f, 0.2442f, 0.0545f };
for (int j = 0; j < this->height; j++)
{
for (int i = 0; i < this->width; i++)
{
pixelsBuffer[i + this->width*j].v[0] = std::clamp((GetPixel(i - 2, j).v[0] * weights[0] + GetPixel(i - 1, j).v[0] * weights[1] + GetPixel(i, j).v[0] * weights[2] + GetPixel(i + 1, j).v[0] * weights[3] + GetPixel(i + 2, j).v[0] * weights[4]), 0.f, 1.f);
pixelsBuffer[i + this->width*j].v[1] = std::clamp((GetPixel(i - 2, j).v[1] * weights[0] + GetPixel(i - 1, j).v[1] * weights[1] + GetPixel(i, j).v[1] * weights[2] + GetPixel(i + 1, j).v[1] * weights[3] + GetPixel(i + 2, j).v[1] * weights[4]),0.f,1.f);
pixelsBuffer[i + this->width*j].v[2] = std::clamp((GetPixel(i - 2, j).v[2] * weights[0] + GetPixel(i - 1, j).v[2] * weights[1] + GetPixel(i, j).v[2] * weights[2] + GetPixel(i + 1, j).v[2] * weights[3] + GetPixel(i + 2, j).v[2] * weights[4]),0.f,1.f);
// 주변 픽셀들의 색을 평균내어서 (i, j)에 있는 픽셀의 색을 변경
// this->pixels로부터 읽어온 값들을 평균내어서 pixelsBuffer의 값들을 바꾸기
}
}
먼저 x축 convolution을 한다. 주변 픽셀들의 색을 weight배열의 가중치만큼 곱해서 더한 값이 i,j에 있는 픽셀의 색이 된다.
box blur의 경우 모든 픽셀이 같은 비율로 흐려지기 때문에 주변 픽셀 5칸의 평균이 i,j의 값이 될것이다. 그러면 weight는
0.2f로 모두 같을 것이다. (5개의 색을 평균내기 때문에) 하지만 가우시안 블러는 가장자리가 더 흐리게 보이고 중간이 더 선명하게 보이는 효과이기 때문에 가장자리는 0.0545, 중간은 0.4026으로 가장자리로 갈수록 가중치가 작아진다.
이것이 커널을 이용해서 다른 효과를 만들어내는 예시이다.
'그래픽스' 카테고리의 다른 글
| [그래픽스] 직선과 삼각형의 충돌 (0) | 2023.05.15 |
|---|---|
| [그래픽스] 선과 구의 충돌 (0) | 2023.05.11 |
| [DX12] Animation (0) | 2022.08.01 |
| [DX12] Picking (0) | 2022.07.31 |
| [DX12] Terrain (0) | 2022.07.31 |