사실 이 프로젝트를 시작하기 전까지 JNI와 openGL, openCV에 대해 전혀 알지 못했다. 그래서 어떻게 작동하는지 어떤 일을 하는지도 모른채 혼자 프로젝트를 맡아서 작업을 하게 되어서 밤새며 공부와 작업을 병행하게 되었고 잘만들지는 못했지만 결과물은 제대로 완성했고 어느정도 이해를 하게 되어 해당 부분을 정리하고자 한다.
우선 프로젝트에 대해서 설명하자면 광각이 넓은 어안렌즈로 된 usb 카메라를 안드로이드 기기에 장착한 후 렌즈로부터 받은 데이터를 openCV를 통해 왜곡을 일반 렌즈처럼 보정을 한 후 안드로이드 기기에 보여주는 작업이다.
말로 하면 쉬워보이지만 일단 카메라나 영상, 이미지에 로우레벨 부분의 지식이 전혀 없었기 때문에 사실 시작부터 어려웠다. 우선 다행히 usb 카메라 연결은 오픈소스로 만든 라이브러리가 있었기 때문에 해당 라이브러리를 참고하여 만들었고 그 후 왜곡과 저장 및 서버 통신은 개별로 작업을 진행했다. 여기서는 왜곡 보정에 대해 알아보려고 한다.
프로젝트 개요에서 설명했듯이 어안렌즈로 촬영된 내용을 다시 보정하여 화각이 넓은 렌즈로 찍는거 처럼 보이는 작업을 하려고 하는것이다.
근데 해당 작업을 하기 위해서는 우선 usb 카메라가 어떻게 촬영된 영상을 안드로이드 기기에 보여주게 되는지를 이해해야 한다.
우선 전체적인 촬영부터 촬영된 영상 표시까지 흐름을 간단하게 설명하고자 한다.
이 프로세스는 카메라가 캡처한 모든 프레임에서 반복되고 그 결과 안드로이드 화면에서 비디오 촬영이 보이게 된다.
이제 카메라가 어떻게 이미지를 표현하는지 간단하게 이해 했으니 여기서 어느 순서에 왜곡 보정을 넣는지 생각해봐야 하는데 MJPEG 형식을 왜곡 보정해서 보정된 프레임을 보여주는 방법과 MJPEG 형식을 RGBX8888로 변환 후 왜곡 보정하는 방법 총 2가지가 존재한다.
그럼 MJPEG와 RGBX8888의 차이에 대해 이해 해야 한다.
MJPEG는 JPEG 이미지의 시퀸스다. 그래서 JPEG로 압축된 이미지를 표시하는 형식이고 이걸 손실 압축 형식이라고 한다. 때문에 MJPEG의 각 프레임은 이미 압축이 되어 있어 일부 이미지 세부 정보가 손실될 수 있다.
RGBX8888의 경우 픽셀을 빨강, 녹색, 파랑로 표현하는 비압축 이미지 형식이다. 때문에 압축을 풀 필요 없이 픽셀 값에 직접 엑세스 할 수 있다.
그럼 다시 문제로 돌아와서 왜곡 보정을 하기 위해서는 비압축된 이미지를 보정해야 화질저하나 왜곡 없이 잘 표현할 수 있을 것이다.
그래서 나는 2번째 방법인 변환 후 왜곡 보정하는 방향으로 작업을 시작했다.