본문 바로가기
Nuke/Blink Script

blink kernels (3)

by 르면가게 2024. 12. 8.

2D Ranged Access

https://learn.foundry.com/nuke/developers/13.2/BlinkKernels/BoxBlurKernel2.html

 

2D Ranged Access — Guide to Writing Blink Kernels

Setting up the 2D Range To set up the 2D range, we again call setRange() inside the init() function. This time, we give it four parameters to specify the horizontal minimum, vertical minimum, horizontal maximum and vertical maximum respectively: void init(

learn.foundry.com

 

The BoxBlur2DKernel

kernel BoxBlur2D :public ImageComputationKernel<eComponentWise>
{
  Image<eRead, eAccessRanged2D, eEdgeClamped> src;
  Image<eWrite, eAccessPoint> dst;

param:
  int xRadius;//The horizontal radius of our box blur  int yRadius;//The vertical radius of our box blurlocal:
  int _filterSize;

  void define() {
    defineParam(xRadius, "RadiusX", 5);
    defineParam(yRadius, "RadiusY", 3);
  }

  void init() {
//Set the range we need to access from the source    src.setRange(-xRadius, -yRadius, xRadius, yRadius);

    _filterSize = (2 * xRadius + 1) * (2 * yRadius + 1);
  }

  void process() {
    float sum = 0.0f;
for(int j = -yRadius; j <= yRadius; j++)
for(int i = -xRadius; i <= xRadius; i++)
        sum += src(i, j);
    dst() = sum / (float)_filterSize;
  }
};

 

2D Ranged Access

2D 범위 접근 설명

이번 예제에서는 2D 범위를 사용하여 입력 이미지에서 여러 위치를 접근하는 방법을 설명합니다. 이 경우, **eAccessRanged2D**를 사용하여 2D 범위 내의 픽셀들을 접근합니다.

1. eAccessRanged2D: 2D 범위 접근

  • *eAccessRanged2D*는 2D 범위로 픽셀을 접근할 때 사용됩니다. 출력 위치에서 2D 영역을 설정하고, 그 범위 내의 입력 이미지의 픽셀들을 접근할 수 있게 해줍니다.

2. 엣지 처리 방법

  • eEdgeClamped: 2D 범위가 이미지 외부로 벗어날 경우, 가장자리를 반복하는 방식입니다.
  • eEdgeConstant: 2D 범위가 이미지 외부로 벗어날 경우, 0 값을 반환하는 방식입니다.
  • eEdgeNone: 엣지 검사를 하지 않으며, 범위를 벗어날 경우 예측할 수 없는 동작이 발생할 수 있습니다. 이 방식은 범위 밖으로 접근할 일이 없을 때 사용되지만, 벗어날 수 있는 경우엔 주의해야 합니다.

3. 예시 코드: 2D 박스 블러 커널

// 입력 이미지 정의: 2D 범위 접근, 엣지 클램프 방식 사용
Image<eRead, eAccessRanged2D, eEdgeClamped> src;

이 코드는 입력 이미지에서 2D 범위로 픽셀을 접근하며, 엣지에 대해 eEdgeClamped 방식을 사용하여 가장자리를 반복하도록 설정합니다.

4. 출력 이미지에 대한 접근

출력 이미지는 이 예제에서는 2D 범위 접근을 사용하지 않음으로 정의됩니다. 대신, 포인트 접근을 사용하여 각 픽셀에 값을 기록합니다.

// 출력 이미지 정의: 포인트 접근, 쓰기만 가능
Image<eWrite, eAccessPoint> dst;

5. 2D 범위 접근 사용

eAccessRanged2D를 사용하면, 출력 위치를 기준으로 2D 범위 내의 픽셀들을 읽어올 수 있습니다. 예를 들어, 박스 블러 같은 2D 필터를 적용할 때 유용합니다. src(i, j)와 같이 두 개의 인덱스를 사용하여 2D 범위 내에서 픽셀을 접근합니다.

요약

  • eAccessRanged2D: 2D 범위 접근을 통해, 출력 위치를 기준으로 입력 이미지의 2D 범위 내의 여러 픽셀을 접근할 수 있습니다.
  • 엣지 처리: eEdgeClamped, eEdgeConstant, eEdgeNone 중 하나를 선택하여 엣지에서의 동작을 설정할 수 있습니다.
  • 출력 이미지: 기본적으로 2D 범위 접근은 사용하지 않고, eAccessPoint로 출력 이미지를 수정합니다.

이 방식은 2D 박스 블러와 같은 필터를 구현할 때 유용하며, 각 픽셀에 대해 주변 2D 범위 내의 값을 읽어와 처리하는 방식으로 동작합니다.

 

Setting up the 2D Range

2D 범위를 설정하기 위해, init() 함수에서 **setRange()**를 호출하여 수평(minimum, maximum)과 수직(minimum, maximum) 범위를 지정합니다. 이때 두 개 이상의 파라미터를 사용하여 범위를 정의할 수 있습니다.

1. setRange() 함수 사용

setRange() 함수는 2D 범위에 대해 4개의 파라미터를 받을 수 있습니다. 이 네 가지 파라미터는 각각 수평(min, max)과 수직(min, max) 범위를 설정합니다.

void init() {
    // 2D 범위 설정: 수평, 수직 각각에 대해 최소/최대값을 설정
    src.setRange(-xRadius, -yRadius, xRadius, yRadius);
}
  • xRadius, xRadius: 수평 범위로, 현재 위치 (x, y)를 기준으로 왼쪽(-xRadius)과 오른쪽(xRadius)으로 접근할 범위를 설정합니다.
  • yRadius, yRadius: 수직 범위로, 현재 위치 (x, y)를 기준으로 위쪽(-yRadius)과 아래쪽(yRadius)으로 접근할 범위를 설정합니다.

이 방식으로 2D 범위를 정의할 수 있으며, 두 축에 대해 각각 최소값과 최대값을 설정할 수 있습니다.

2. 두 파라미터만 사용하기

setRange()는 두 개의 파라미터만 사용할 수도 있으며, 이 경우 수평과 수직 범위가 동일하게 설정됩니다. 예를 들어:

src.setRange(xRadius, yRadius);

이 호출은 다음과 같은 효과가 있습니다:

  • 수평 범위: xRadius부터 +xRadius
  • 수직 범위: yRadius부터 +yRadius

3. setAxis() 호출 불필요

이번 예제에서는 2D 범위를 설정하므로, setAxis()는 호출할 필요가 없습니다. setAxis()는 1D 범위에 대해서만 사용되며, 2D 범위에서는 자동으로 두 축 모두를 고려하여 접근합니다.

요약

  • setRange(-xRadius, -yRadius, xRadius, yRadius): 수평과 수직에 대해 각각 최소값과 최대값을 지정하여 2D 범위를 설정합니다.
  • 두 파라미터 사용: setRange(xRadius, yRadius)를 사용하면 수평과 수직 범위가 동일하게 설정됩니다.
  • setAxis() 불필요: 2D 범위를 설정할 때는 setAxis()를 사용할 필요가 없습니다.

이렇게 설정된 2D 범위는 2D 필터(예: 박스 블러, 가우시안 블러 등)에 활용되며, 각 픽셀 주변의 2D 영역을 접근할 수 있게 해줍니다.

Accessing the 2D Range

2D 범위 접근 및 처리

process() 함수에서 2D 범위를 접근하는 방식은 1D 범위 접근과 유사하지만, 이번에는 두 개의 오프셋(수평과 수직)을 사용하여 입력 이미지의 범위 내 픽셀들을 순차적으로 접근합니다.

1. 2D 범위 접근 방법

2D 범위를 접근할 때는 두 개의 인덱스를 사용하여 각 축에 대해 범위 내의 값을 순차적으로 읽어옵니다. 이를 위해 두 개의 중첩된 for 루프를 사용하여, 수직 범위와 수평 범위를 모두 탐색합니다.

2. 예시 코드

void process() {
    float sum = 0.0f;

    // 수직 범위 탐색
    for(int j = -yRadius; j <= yRadius; j++) {
        // 수평 범위 탐색
        for(int i = -xRadius; i <= xRadius; i++) {
            sum += src(i, j);  // src(i, j): 2D 범위에서 (i, j) 위치의 값
        }
    }

    // 필터 크기만큼 평균 값을 계산하여 출력 픽셀에 저장
    dst() = sum / (float)_filterSize;
}
  • 수직 범위 루프 (j): yRadius부터 yRadius까지 반복하면서 수직 방향의 범위를 탐색합니다.
  • 수평 범위 루프 (i): 각 수직 위치에 대해 xRadius부터 xRadius까지 반복하면서 수평 방향의 범위를 탐색합니다.
  • src(i, j)는 현재 (i, j) 위치에서 입력 이미지 src의 값을 읽어옵니다.
  • 모든 값을 더한 후, 필터 크기(_filterSize)로 나누어 평균값을 계산하여 출력 이미지 dst()에 저장합니다.

3. 최종 출력

  • 최종적으로 평균값이 계산되고, **dst()*에 할당됩니다. _filterSize는 init() 함수에서 계산한 필터 크기로, 전체 범위 내에서 값들을 평균내는 데 사용됩니다.

요약

  • 2D 범위 접근은 두 개의 오프셋을 사용하여 수직과 수평 범위를 탐색합니다.
  • process() 함수에서는 두 개의 중첩된 for 루프를 사용하여 범위 내 모든 값을 누적하고, 평균값을 계산하여 출력합니다.
  • 2D 필터링 예제에서는 이 방법을 사용하여 박스 블러와 같은 필터를 적용할 수 있습니다.

'Nuke > Blink Script' 카테고리의 다른 글

blink kernels (5) - Blink Reference Guide  (0) 2024.12.08
blink kernels (4)  (0) 2024.12.08
blink kernels (2)  (0) 2024.12.08
blink kernels (1)  (0) 2024.12.08
Blink Script (2)  (0) 2024.12.08