NVidia 텍스처 툴에 컨벌루션 필터링을 추가하는 방법
NVTT 컨벌루션 필터 추가 방법 (Markdown 정리본)
몇 달 전부터 올릴려고 했던 글인데… 회사 법무팀의 허락을 받느라 좀 지체되었다. 드디어 올려도 된다는 허락을 받았으니.. 아싸 -_-;
배경
NVidia 텍스처 툴(NVTT)에 컨벌루션 영상처리 기법을 추가하게 된 계기는 회사에서 아티스트들의 요청 때문이었다.
NVTT 1.0은 밉맵에 샤프닝(sharpening) 필터를 적용하는 옵션이 있었는데, NVTT 2.0에서는 삭제… (추후 추가할 예정이었으나 1년이 넘도록 추가되지 않음 -_-)
NVTT가 오픈소스 프로젝트가 된 이후로는 개발도 뜸해서 이 기능이 추가되길 기다리기보다는 직접 추가하기로 맘을 먹었다.
어차피 샤프닝 필터는 2D 커널을 이용한 컨벌루션이니, 범용적인 컨벌루션 필터를 넣는 게 낫다고 판단했다. 이러면 샤프닝뿐 아니라 컨벌루션 기반 영상처리 기법은 전부 적용 가능해진다.
NVTT 소스 코드 수정
사실 수정할 코드는 얼마 안 된다. 6개 파일에 몇 줄 추가하면 끝.
Step 1
NVidia 텍스처 툴 프로젝트 웹페이지에서 revision 1277을 받는다.
Step 2
src/nvimage/Filter.h에 생성자 추가:
Kernel2(uint width, const float * data);
Step 3
src/nvimage/Filter.cpp에 구현 추가:
Kernel2::Kernel2(uint ws, const float* data) : m_windowSize(ws)
{
m_data = new float[m_windowSize * m_windowSize];
memcpy(m_data, data, sizeof(float) * m_windowSize * m_windowSize);
}
Step 4
src/nvimage/FloatImage.h에 선언:
NVIMAGE_API void doConvolution(uint size, const float* data);
Step 5
src/nvimage/FloatImage.cpp에 실제 구현:
void FloatImage::doConvolution(uint size, const float* data)
{
Kernel2 k(size, data);
AutoPtr<floatimage> tmpImage = clone();
for(uint y = 0; y < height(); y++)
{
for(uint x = 0; x < width(); x++)
{
for (uint c = 0; c < 4; ++c)
{
pixel(x, y, c) = tmpImage->applyKernel(&k, x, y, c, WrapMode_Clamp);
}
}
}
}
Step 6
src/nvtt/nvtt.h의 struct TexImage에 선언:
NVTT_API void doConvolution(unsigned int size, const float* data);
Step 7
src/nvtt/TexImage.cpp에 구현:
void TexImage::doConvolution(unsigned int size, const float* data)
{
if (m->image == NULL) return;
detach();
m->image->doConvolution(size, data);
}
사용법
이미 TexImage image;가 있다고 가정하면:
const int kernelSize = 3; // 3x3 커널
const float sharpenKernel[] =
{
-1/16.0f, -2/16.0f, -1/16.0f,
-2/16.0f, 1 + 12/16.0f, -2/16.0f,
-1/16.0f, -2/16.0f, -1/16.0f,
};
image.doConvolution(kernelSize, sharpenKernel);
끝! (정말 간단하지? -_-)
제대로 대우받는 개발자 | 부족한 컴공지식 배우기 | MIT급 컴공인강
최저임금으로 고통받는 일회성 프로그래머는 그만! POCU 아카데미가 올해 연봉협상을 책임지겠습니다!