https://learn.foundry.com/nuke/developers/13.2/BlinkKernels/BoxBlurKernel.html
1D Ranged Access — Guide to Writing Blink Kernels
Accessing the 1D Range The final thing to note is how we access positions inside the 1D range within the process() function. With point access to the input, as in the previous example, the input image src was accessed as src(). In this case, when accessing
learn.foundry.com
BoxBlur1DKernel
kernel BoxBlur1D :public ImageComputationKernel<eComponentWise>
{
Image<eRead, eAccessRanged1D, eEdgeClamped> src;
Image<eWrite, eAccessPoint> dst;
param:
int radius;//The radius of our box blurlocal:
int _filterWidth;
void define() {
//RIP node will identify radius as the apron defineParam(radius, "Radius", 5);
}
void init() {
//Set the range we need to access from the source src.setRange(-radius, radius);
//Set the axis for the 1D-range to be horizontal src.setAxis(eX);
_filterWidth = 2 * radius + 1;
}
void process() {
float sum = 0.0f;
for(int i = -radius; i <= radius; i++)
sum += src(i);
dst() = sum / (float)_filterWidth;
}
};
1D Ranged Access
1D 범위 접근과 엣지 처리 설명
이 커널에서는 입력 이미지의 1D 범위에 접근해야 합니다. 이를 위해 eRead, eAccessRanged1D, **eEdgeClamped**를 사용한 src 이미지를 정의합니다. 각 설정의 의미는 다음과 같습니다.
1. eAccessRanged1D: 1D 범위 접근
- eAccessRanged1D는 출력 위치마다 입력 이미지의 1D 범위에 접근한다는 것을 의미합니다. 즉, 한 픽셀을 처리할 때 해당 픽셀을 중심으로 주변 픽셀들을 접근할 수 있습니다.
2. 엣지 처리: eEdgeClamped, eEdgeConstant, eEdgeNone
- eEdgeClamped: 입력 이미지의 범위를 벗어나는 위치가 있을 경우, 가장자리에 있는 픽셀을 반복하여 사용합니다. 예를 들어, 1D 범위의 일부가 이미지 밖에 있을 때, 해당 부분은 이미지의 가장자리 픽셀을 계속해서 사용합니다.
- eEdgeConstant: 이미지의 범위를 벗어나는 부분은 0으로 처리됩니다.
- eEdgeNone (기본값): 엣지 검사를 하지 않으며, 범위를 벗어날 경우 예측할 수 없는 동작이 발생할 수 있습니다. 이 옵션은 속도 측면에서는 유리하지만, 범위를 벗어나는 접근이 있을 경우 크래시나 예기치 않은 결과를 초래할 수 있기 때문에 주의가 필요합니다.
3. 출력 이미지에 대한 접근: eWrite와 eAccessPoint
- 출력 이미지 dst에 대한 접근은 eWrite와 eAccessPoint로 설정되어 있습니다. 이는 출력 이미지의 각 위치에 대해 포인트 접근을 사용하여 값을 쓴다는 의미입니다.
예시 코드
// 입력 이미지 정의: 1D 범위 접근, 엣지 클램프 방식 사용
Image<eRead, eAccessRanged1D, eEdgeClamped> src;
// 출력 이미지 정의: 포인트 접근, 쓰기만 가능
Image<eWrite, eAccessPoint> dst;
설명
- src: 입력 이미지에서 각 픽셀 주변의 1D 범위를 접근하면서 엣지 클램프 방식으로 이미지를 처리합니다.
- dst: 출력 이미지에 대해서는 각 픽셀에 포인트 접근 방식으로 값을 기록합니다.
이 방식은 1D 박스 블러와 같은 연산에 적합하며, 입력 이미지의 범위를 벗어날 때 엣지 픽셀을 반복해서 사용하는 방식으로 처리됩니다.
Setting up the 1D Range
1D 범위 접근 설정
입력 이미지에 대해 1D 범위 접근을 정의한 후, 범위의 크기와 방향을 설정해야 합니다. 이 작업은 init() 함수 내에서 이루어집니다. 범위 설정은 setRange()와 setAxis()를 통해 수행됩니다.
1. setRange(...): 범위 정의
setRange()는 현재 출력 위치를 기준으로 접근할 범위를 설정합니다. 예를 들어, -radius부터 radius까지의 범위를 정의하면, 현재 위치에서 앞뒤로 radius 크기만큼의 범위를 설정할 수 있습니다.
src.setRange(-radius, radius);
- radius는 블러 크기를 정의하는 파라미터로, 범위의 크기는 radius부터 +radius까지 포함됩니다.
- 이 범위는 **현재 위치 (x, y)*를 기준으로 설정되며, setRange(...)의 범위는 양쪽 끝을 모두 포함합니다.
2. setAxis(...): 범위 방향 정의
setAxis()를 사용하여 1D 범위가 어느 축을 따라 정의될지 설정합니다. 예를 들어, 수평 범위를 원할 경우 eX를 사용하고, 수직 범위를 원할 경우 eY를 사용합니다.
src.setAxis(eX);
- eX는 수평 범위를 의미하며, 이 경우 범위는 (x - radius, y)에서 (x + radius, y)까지가 됩니다.
- 수직 범위를 원하면 eY를 사용하여 (x, y - radius)에서 (x, y + radius)까지의 범위를 정의합니다.
전체 예시 코드
void init() {
// src 이미지에서 범위 정의: 수평으로 -radius에서 +radius까지
src.setRange(-radius, radius);
src.setAxis(eX); // 수평 범위 설정
}
요약
- setRange(-radius, radius): 현재 위치 (x, y)를 기준으로 radius부터 +radius까지의 범위를 설정합니다.
- setAxis(eX): 범위가 수평(x축)으로 정의되도록 설정합니다. 수직 범위로 설정하려면 eY를 사용합니다.
Accessing the 1D Range
process() 함수에서 1D 범위 내의 픽셀들을 접근하는 방법에 대해 설명합니다. 이전 예제에서 입력 이미지 src를 포인트 접근으로 src()로 사용했듯이, 1D 범위에서는 출력 위치에서의 오프셋을 지정해야 합니다. 이를 통해 1D 범위 내의 특정 픽셀에 접근할 수 있습니다.
1. 범위 내의 픽셀 접근
1D 범위 내에서 픽셀을 접근하려면, 출력 위치에 대해 오프셋을 사용하여 접근해야 합니다. 이를 위해 src(i)와 같이 범위 내에서 오프셋을 지정합니다. 이때 i는 -radius부터 +radius까지 반복되며, 각 위치에서 값을 누적하여 박스 블러를 계산합니다.
2. 예시 코드: 수평 범위에서 박스 블러 구현
void process() {
float sum = 0.0f;
// 수평 범위에서 왼쪽에서 오른쪽으로 루프를 돌며 합산
for (int i = -radius; i <= radius; i++) {
sum += src(i); // src(i)는 1D 범위 내의 각 픽셀을 접근
}
// 출력 픽셀을 계산된 평균값으로 설정
dst() = sum / (float)_filterWidth;
}
- src(i)는 현재 위치에서 i만큼 오프셋을 적용한 입력 이미지의 픽셀 값입니다.
- sum은 범위 내의 모든 값을 누적하여, 마지막에 평균값을 구합니다.
3. 수직 블러로 변경하기
수평 블러를 수직 블러로 바꾸는 방법은 간단합니다. init() 함수에서 setAxis(eX)를 setAxis(eY)로 변경하면, 수직 범위로 블러를 적용할 수 있습니다.
void init() {
src.setRange(-radius, radius); // 범위 설정
src.setAxis(eY); // 수직 범위로 변경
}
요약
- 1D 범위 접근: src(i)를 사용하여 출력 위치를 기준으로 radius부터 +radius까지의 범위 내에서 픽셀 값을 접근합니다.
- 수평 블러: setAxis(eX)로 수평 범위에 대해 블러를 적용합니다.
- 수직 블러로 변경: setAxis(eY)로 수직 범위로 블러를 적용할 수 있습니다
'Nuke > Blink Script' 카테고리의 다른 글
blink kernels (4) (0) | 2024.12.08 |
---|---|
blink kernels (3) (0) | 2024.12.08 |
blink kernels (1) (0) | 2024.12.08 |
Blink Script (2) (1) | 2024.12.08 |
Blink Script (1) (0) | 2024.12.08 |