[opencv]url로 온라인 이미지 읽어오기, gif이미지 읽어오기

chaewon Im·2022년 1월 16일
0

트러블슈팅

목록 보기
5/10

cv2.error: OpenCV(4.5.5) /Users/runner/work/opencv-python/opencv-python/opencv/modules/imgproc/src/color.cpp:182: error: (-215:Assertion failed) !_src.empty() in function 'cvtColor'

퍼스널컬러 모듈을 적용하는 과정에서 요 에러에 계속 시달렸다. 보아하니 이미지의 경로가 제대로 전달되지 않는 것 같았다. 프로그램을 들여다보니 첫 번째는 웹 url 경로를 인식하지 못해서 발생했고, 두 번째는 url중에 gif 타입이 존재해서 발생한 문제였다.

이 두 가지 문제를 해결한 과정에 대해 정리해보았다.


문제 1. 웹 이미지 url경로를 인식하지 못한다.

opencv로 만들어둔 모듈에 썸네일이미지 url을 인자로 전달하니, opencv가 이미지 경로를 인식하지 못하는 문제가 발생했다.

url은 단순히 폴더에서 이미지를 가져올때와는 다르게 처리해야 한다. url을 통해 응답받은 이미지를 numpy 배열 형태로 바꾸고, 이를 decode해서 opencv에서 사용하는 이미지 방식으로 변환해야 한다고 한다.

[참고 링크]
https://nyagya.tistory.com/8

위 링크를 참고해 색상 추출 모듈을 조금 수정해주었다.

<기존>
기존에는 이미지 확장자에 따라 차이를 줘야하는 것을 모르고 cv2.imread(url) 한 줄만 존재했다.

img = cv2.imread(self.URL)

<변경 후>
우선은 기본적인 이미지 파일(jpg,png)을 처리하는 메소드이다.

def get_normal_image(self,url):
	image_nparray = np.asarray(bytearray(requests.get(url).content), dtype=np.uint8)
        image = cv2.imdecode(image_nparray, cv2.IMREAD_COLOR)
        return image

썸네일 이미지의 URL을 배열로 변환 후 디코딩하는 작업으로 변경해주었다.

  • IMREAD_COLOR란?
    IMREAD_COLOR가 무엇인지 찾아보았는데, 이미지를 읽을때 어떻게 읽을지 설정하는 것 같다.
    IMREAD_COLOR는 default 값이고, 이미지의 투명한 부분을 제외하고 컬러로 가져온다.
    자매품
    - IMREAD_GRAYSCALE(흑백으로 가져오기)
    - IMREAD_UNCHANGED(알파채널까지 다 포함해서 가져오기)

이렇게 해주니 웹 이미지 url을 인식하고 모듈이 정상적으로 동작한다.


문제 2.gif 확장자가 껴있다.

위에서 구현한 메소드 내의 코드만으로 모든 링크를 처리했을 때 아래와 같은 오류가 특정 행에서 나타났다.

에러가 나는 행을 확인해본 결과 문제는 gif 파일에서 나타났다.

gif 확장자는 연속된 이미지들이 모여 하나의 이미지를 구성하는 형태이다. 영상과 유사한 형태이기 때문에 일반 이미지와 다르게 frame을 읽어야 한다. 따라서 파일이 gif인 경우에는 frame의 가장 첫번째 이미지를 읽도록 다른 메소드를 구현해주었다.

def get_gif_image(self,url):
        gif = cv2.VideoCapture(url)
        ret,frame = gif.read()
        if ret:
            return frame

이와 같이 gif 이미지는 cv2.VideoCapture()로 이미지를 읽고, 프레임이 제대로 읽히면 첫 프레임을 출력하도록 하였다.

확인을 위해 확장자와 함께 분석 내용을 출력시켰는데, 다음과 같이 잘 동작한다.


로직 추가

기존에는 단순하게 이미지를 읽고, RGB로 변환하는 코드 두 줄만으로 구성되어있었다.

img = cv2.imread(self.URL)
img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)

오류를 해결한 뒤에는 이미지를 읽는 메소드를 따로 추가하여 이미지 형식에 따라 다르게 이미지를 읽고, 그 이미지를 RGB형태로 변환하여 return하는 메소드를 추가하였다.

def read_image(self,image_type):
        if image_type == 'gif':
            img = self.get_gif_image(self.URL)
        else:
            img = self.get_normal_image(self.URL)

        img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
        return img

그리고 메인 함수에서는 url에서 이미지 확장자를 찾아내는 메소드를 먼저 수행 후, 이미지를 읽는 메소드를 수행하도록 변경하였다.

image_type = self.get_image_type(self.URL)
img = self.read_image(image_type)

끝!

profile
빙글빙글 돌아가는 주니어 프론트엔드 개발자

0개의 댓글