Trouble/OpenCV

C++ OpenCV cvtColor memory leakage 문제

침닦는수건 2024. 2. 5. 21:24
반응형

C++로 코드를 구현하던 중 갑자기 다음와 같은 오류가 났다.

terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
Aborted (core dumped)

 

보통 힙 메모리 부족할 때 발생하는 오류인데, 딱히 동적 할당을 무한히 반복하거나 객체 생성을 무한히 하는 것도 아닌데 갑자기 메모리 부족하다고 떴다. 

 

메모리 사용이 폭발적으로 증가하는 병목 지점을 찾아보니 cv::cvtColor() 호출 지점이었다.

 cv::Mat cvimg = cv::imread(img_path);
 cv::Mat cvimg_gray;
 cv::cvtColor(cvimg, cvimg_gray, cv::COLOR_BGR2GRAY); // memory leakage

 

cvtColor 라인에서 메모리가 폭발적으로 증가하다가 용량을 초과해서 코드가 죽었다. 이 부분에서 memory leak이 발생하는 듯 하다.

 

구글링을 해보니 비슷한 이슈가 2020년에도 있었는데 아직까지도 원인 불명이고 해결되지 않은 듯하다. 4.x 버전에서 출현하는 오류인 것 같다. 

 

https://github.com/opencv/opencv/issues/23633

https://github.com/opencv/opencv/issues/16466

 

실제로 여러 시도를 해보았는데 나도 명확한 방법을 찾을 수가 없었다. 

cv::imread(img_path, cv::IMREAD_GRAYSCALE);

 

애초에 읽을 때부터 GRAYSCALE로 지정해서 읽는 방법으로 우회하는 것이 그나마 해결 방법이었다. 

 

이부분은 원인과 해결 방법이 명확하지 않으므로 사용할 때마다 계속 체크해줘야 안전할 것 같다.

 

Note

python에서도 cvtColor 사용 시 메모리 누수 문제가 있다. 다행히 이 문제는 color convert 전 array가 dtype이 np.float64일 때 발생하는 문제로 원인이 있다. 

 

0~1로 표현된 이미지라면 np.float32, 0~255로 표현된 이미지라면 np.uint8로 표현해둔 뒤, cvtColor를 사용하면 메모리 누수 문제를 피할 수 있다. 

반응형