Knowhow/Vision

Opencv imread/imwrite vs PIL open/save speed 및 memory 비교

침닦는수건 2024. 6. 22. 00:52
반응형

이미지 파일을 읽을 때 opencv 혹은 PIL을 쓴다. 두 라이브러리의 기능적 차이는 없다만 경험적으로 보면 읽는 속도와 쓰는 속도가 다름을 알 수 있다. 
 
상황에 따라서 opencv가 효율적일 때도, PIL이 효율적일 때도 있는데 각각 어떤 상황인지 파악해두었다. 왜 차이가 발생하는지 알 수 있는 경우는 이유도 같이 적는다.
 

이미지 읽기

확장자가 PNG일 때 : opencv 써야 빠르다.

cv2.imread/imwrite가 훨씬 빠르다. meta 정보를 포함한 DSLR 12MB 이미지의 경우, 10초 가량 차이가 날 때도 있다.  차이가 적을 땐 적지만 클 땐 10배도 난다. 웬만하면 opencv로 png 읽자.

확장자가 JPG일 때 : PIL 써야 빠르다.

Image.open으로 읽는 것이 약 2배 빠르다. 왠지 모르겠다... jpeg 압축률이 얼마냐에 따라 상관없이 PIL이 더 빠르게 읽는다. 보통 편차없이 2배 정도 빠르다.
(설마 PIL은 읽을 때도 이미지퀄리티 75%로 읽어서 그런가?)
 

이미지 쓰기

확장자가 PNG일 때 : opencv 써야 빠르다. 용량도 더 가볍다.

읽을 때와 마찬가지로 opencv가 훨씬 빠르다. 위에 말한 DSLR 이미지 조건에서 역시나 10배까지도 차이난다.
용량도 이유는 모르겠으나 opencv로 저장한 png가 더 가볍다.
 

확장자가 JPG일 때 :  PIL이 빠르다.  용량도 더 가볍다. (압축을 더 많이 한다.)

기본적으론 PIL이 이미지 읽을 때와 마찬가지로 더 빠르다. 웬만해선 PIL 쓰는게 빠르다. 
 
용량의 경우도 PIL이 더 가볍게 저장하는 것을 확인했으나 이는 jpeg 압축률 차이로 인한 속도 차이임을 확인했다. 
 
cv2.imwrite의 경우, 이미지 퀄리티 95%로 최소 압축하여 저장하고 Image.save의 경우, 이미지 퀄리티 75%로 압축하여 저장한다. 
 
따라서 압축을 더 하는 PIL이 가벼울 수 밖에 없는 것.  Image.save(img, quality=95)로 설정해줄 경우, opencv와 용량이 같아진다.

속도는 PIL이 빠름.
 

결론

웬만하면 jpg로 읽고 쓰고, PIL로 읽고 쓰는 것이 빠르다.
 
단, PIL의 경우 DSLR같이 meta 정보가 있는 이미지의 경우, 카메라 회전 상태를 반영해서 스스로 이미지를 돌려버릴 때가 있는데 이를 잘 처리해줘야 한다. 
 
Image.open 이후에 ImageOps.exif_transpose(img)를 꼭 적용해주자. 이 2개를 다 통과시켜도 opencv보다 빠르다.
 
(괜히 요즘 PIL로 읽는게 아닌 듯)
 

 

반응형