처음 '슈아 왕'에 의해 만들어진 OpenCV 를 이용한 super resolution 을 OpenMP 로 몇배 빠르게 만들었던 작업 뒤에 순수 C++ 로만 구동 되도록 만든 라이브러리 엔진을 작년에 만든 적이 있습니다. (관련글)
기존에 만들었던 엔진에 몇가지 문제가 있었는 점을 확인 한 바가, 내부에 사용된 미리 계산된 학습 데이터가 2배 이내의 이미지에 최적화가 되어 있다는 점 입니다. 그래서 2배를 초과하는 이미지에서는 해당 이미지의 해상도가 SRCNN 알고리즘에 정확히 동작하지 못하는 부분이 많이 발견 되었었 습니다만, 이를 개선하기 위해 2배 단위로 영상 단계별로 scaling 하도록 개선한 소스를 업데이트 하였습니다. 물론 이로 인해 속도가 매우 떨어지게 되는 점은 아쉬운 부분 입니다만, 원본 소스가 2배에 학습된 데이터라 이에 맞춰 개선을 하는 것이 중요해 보였습니다.
개선된 libsrcnn 은 현재 대부분의 모든 platform 을 지원 하고 있습니다, 특히 ARM 계열을 지원 하고 있는데, 속도는 x86.64 보다 다소 떨어지긴 합니다만, OpenCV 를 쓰는 알고리즘 보다는 빠르게 10배 이상의 속도를 가지고 있기 때문에 느리지만 느린 알고리즘은 아니라는 점이 장점 입니다.
소스 및 빌드
소스는 https://github.com/rageworx/libsrcnn 에서 누구나 clone 이나 download 를 하실 수 있으나, 라이센스가 LGPL-3.0 으로 지정 되어 있다는 점을 고려해서 사용하는 것이 좋으시며, 간단한 테스트는 shell 에서 clone 또는 압축을 푼 위치에 있는 위치에서 다음과 같은 차례로 test 용 바이너리를 만들 수 있습니다.
$ make -f Makefile.staticlib
$ make -f Makefile.test
단, test 용 바이너리를 만들기 위해서는 다음 두가지 종속성이 있습니다. 두 라이브러리 모두 대부분의 모든 platform 을 지원 하고 있으며, armhf 및 aarch64 에서 사용이 가능 합니다.
현재 M$VC 는 지원하고 있지 않지만 Makefile 을 참조해서 간단히 프로젝트를 만들어 쓰시면 되지 않을까 합니다. 단, 소스에 포함된 OpenMP 는 M$VC 에서 version 2.5 이후로 지원을 하지 않기 떄문에 제대로 사용이 불가능 합니다. 독자노선 좋아 하시는 M$ 가 OpenMP 대신 concurrency 를 갈아 탔으니 해당 알고리즘을 모두 변경 하는 것에 대해서는 지원이 불가능 함을 먼저 밝힙니다.
맥의 경우는 지정되는 makefile 이 Makefile.staticlibmac 과 Makefile.testmac 으로 내부에서 llvm-gcc 와 OpenMP 를 빼고 구동하도록 되어 있습니다. llvm-gcc 나 clang 모두 같은 것이며, mac 의 경우느 hpc-gcc 가 아니면 -fopenmp 지시어가 존재하지 않습니다. 물론 내부적으로 for() 나 while() 등의 구동되는 반복문 내에서 여러 CPU core 를 모두 쓰도록 컴파일러 자체에서 별도의 지시어 없이도 잘 구동 하도록 만들어 져 있기 때문에 OpenMP 를 직접 구동하는 시스템에 비해서는 어느정도 성능이 떨어지는 면이 있을지 몰라도 MacOSX 자체에서 반복구문 내의 성능은 OpenMP 를 지시해서 구동하지 않는 일반 시스템들 보다는 뛰어난 결과를 얻을 수 있습니다.
64x64 이미지 다단계 크기 조정 테스트
기존 알고리즘에서 개선된 부분은 아직 여러 튜닝요소가 남아 있기 떄문에 실험적으로 현재는 stepscaling 을 true 로 설정해서 사용해야지만 사용이 가능한 형태로 만들어 두고 있긴 합니다만, 2배 이상의 이미지를 다단계로 SRCNN 처리 하는 것에 대한 효과는 다음과 같이 차이가 발생 하게 됩니다.
원본 이미지
흔한 그 나비 날개 256x256
이미지 프로세싱엔 모든 공돌이들의 미의 여신? 이라 불릴 만큼 유명한 레나님이 계셨다면, SRCNN 에서는 선형성 데이터의 극적인 품질 향상 비교를 위해 노란 나비의 날개를 사용하고 있습니다. 아마 SRCNN 을 검색 해 보면 죄다 이 노란 나비만 사용되고 있을 겁니다만, 이미 이 이미지 자체가 256x256 이란 높은? 해사도를 가지고 있으므로 저는 이를 더욱 더 낮춘 성능인 64x64 로 높은 해상도로 변경시 변화를 보고자 했습니다. 그래서 실제 사용한 이미지는 64x64 인 아래 날개 이미지를 사용 하였습니다.
사실 이정도 크기 이미지라면 아무리 키워 봤자 SRCNN 외에는 검은 패턴이 가진 특성을 그대로 복호하지 못합니다만, stepscaing 를 할 경우는 원본 이미지가 가진 그 이상의 의미를 찾을 수 있습니다.
배율 | 기존 SRCNN |
step-scaling SRCNN |
x1.9 |
|
|
x2.0 |
|
|
x3.0 |
|
|
x5.0 |
|
|
x7.0 |
|
|
2배를 넘어 가는 이미지에 대해서는 기존 SRCNN 이 학습 데이터를 넘어 서는 범위라, 원본의 작은 이미지가 가지고 있었을 특성에 대해 잃어 버리게 되는것을 step-scaling 을 적용 할 경우 시간은 2로 나눠지는 값들에 대해 더욱 더 긴 시간을 소요하게 됩니다만 결과는 매우 좋은 이미지로 확인 될 수 있으며, CrCb 채널을 제외한 Y(흑백) 채널의 경우는 매우 좋은 분석 데이터로 사용이 가능 합니다.
성능
SRCNN 의 특성상 원본 이미지가 커질수록 커널연산이 많아지게 되므로 느려지게 됩니다만, 64x64 RGB 를 7베 ( 내부적으로 3단계 step-scaling 을 거침 ) 로 크기를 조절 할 경우 Intel Core i5-7200U ( 2.5GHz ) 에서 다음과 같은 속도를 가집니다.
저작권
libsrcnn 은 다음과 같은 저작권 및 라이센스를 가지고 있습니다.
- 사용된 SRCNN 에 대한 이론 및 원본 알고리즘 이론
http://mmlab.ie.cuhk.edu.hk/projects/SRCNN.html
Chao Dong, Chen Change Loy, Kaiming He, Xiaoou Tang
Department of Informaiton Engineering, The Chinese University of Hong Kong - OpenCV 를 이용한 SRCNN 구현
https://github.com/shuwang127/SRCNN_Cpp
shuwang127, GPL-2.0 - OpenCV 를 이용한 SRCNN 에 OpenMP 를 이용한 가속
https://github.com/rageworx/SRCNN_OpenCV_GCC
rageworx, GPL-2.0 - libsrcnn, native C++ OpenMP 가속 알고리즘
https://github.com/rageworx/libsrcnn
rageworx, LGPL-.3.0
Windows x86.64 시스템용 DLL
libscrnn-win64dll-v0.1.8.30.zip
import 용 a ( lib ) 및, header 포함.
해당 DLL 의 종속성: