Computer Science/DL, ML

욜로(YOLO) Cannot load image, Couldn't open file, Segmentation fault 에러 해결 방법

TwinParadox 2020. 2. 19. 22:07
728x90

YOLO로 객체 탐지(Object Detection)을 할 일이 생겨서 이런저런 설정을 해주면서 작업을 진행했다. Bounding Box를 치고 Labelling을 하는 작업도 순조롭게 마치고, 이제 리눅스 환경으로 옮겨서 라벨링한 데이터들을 darknet 내부 디렉토리에 적절하게 위치시키고서 학습을 시키려니까 문제가 발생했다.

 

 

Cannot load image ~~

Couldn't open file ~~

 

 

dimension과 wieght 불러오는 등 설정 파일까지 다 읽어온 상태에서 학습용 이미지 파일과 bounding box 좌표값을 담은 같은 이름의 파일을 불러오지 못하는 에러가 잔뜩 발생했다. 이럴 때는 대부분 아래의 방식을 따르면 해결이 된다. 아래 내용은 실제 darknet repository인 AlexeyAB darknet과 pjreddie darknet의 issue에서도 언급된 내용이다.

 

 

1. .data 파일에서 지정한 train.txt(또는 valid, test)의 파일 내부에 주소가 잘못된 경우

흔히 경로를 착각해서 발생하는 문제다. YOLO_mark를 이용해서 Labeling을 해주면, train.txt에는 상대 경로로 이미지의 경로가 기록된다. 상대 경로를 사용하다 보니까 종종 발생하는 문제인데, 이럴 때는 경로만 잘 지정해주면 해결이 된다.

 

 

train.txt

 

예를 들어, train.txt 내부에 data/img/100_002.jpg라고 되어 있으면, 여기서 상대 경로의 기준점은 명령어를 실행하는 위치, 즉, darknet 디렉토리를 뜻한다. 따라서, 100_002.jpg와 100_002.txt는 반드시 darknet 디렉토리 내부에서 data/img(data 디렉토리 내부의 img 디렉토리)라는 디렉토리에 위치해야 한다.

 

2. 경로가 맞음에도 되지 않는 경우

이런 경우가 간혹 있을 수 있다고 하고, 이럴 때는 절대경로로 치환해서 사용하라고 하는데, 경험 상 상대 경로에 아무 문제가 없는데 경로를 절대 경로로 지정해준다고 되는 경우는 많지 않았다. 실제로 이 방법이 해결 방법으로 제시됐던 글에서도 issue를 제기했던 사람은 이 방법이 통하지 않는다고 말했다.

 

 

3. 인코딩 문제

간혹 EUC-KR, ANSI 등의 인코딩으로 되어 있어 경로를 읽어오지 못할 때 발생한다.

 

 

iconv -f=euc-kr -t=UTF-8 train.txt

 

 

명령어 하나면 간단하게 인코딩 변경이 가능하다. iconv가 없으면 apt install를 통해 설치해주면 된다.

 

사실 이 문제도, 대부분 문제를 인지하고 텍스트 에디터를 열었을 때 알아차리게 되는 경우가 대부분이다. 만약에 이 문제를 겪고 있는 상황에서 텍스트 에디터를 열었을 때 흔히 보이는 인코딩 문제로 인한 텍스트 깨짐 현상이 나타나지 않는다면 아주 높은 확률로 인코딩에는 문제가 없다는 이야기가 된다.

 

 

문제는 위 세 가지 방법이 필자한테는 전혀 먹히지 않았다는 점이다. 1번은 몇번이고 확인했고, 2번 같은 경우는 애당초 다른 사람들은 상대 경로로 잘만 되는데, 같은 환경에서 나만 절대경로로 하면 될 거라는 점도 이해가 안 갔고, 실제 해당 방법으로 시도한 사람은 여전히 문제가 해결되지 않았다는 답변을 남겨놨다. 그래서 3번 인코딩 문제도 인코딩 변환을 이용해서 변환을 해줬는데, 여전히 같은 문제로 학습시도조차 하지 못했다. 그러다 문득 떠오른 게 하나 있다.

 

 

4. 윈도우(Windows)의 CRLF와 리눅스(Linux)의 LF

흔히 말하는 개행 표기 방식의 문제다. 윈도우와 리눅스는 개행(줄바꿈) 문자가 다르다. 한 플랫폼에서 사용할 때는 이 문제를 체감할 일이 거의 없다. 주로 아두이노 IDE의 시리얼 모니터를 활용할 때 CRLF 문제를 겪는 경우가 많다. 요약하자면 윈도우는 개행에서 CRLF(Carriage Return/Line Feed, \r\n)을 사용하고 리눅스는 LF(Line Feed, \n)만 사용해서 발생하는 문제다. 이런 경우는 아주 간단하게 해결 가능하다.

 

 

텍스트 에디터를 열어서 새로운 파일에다가 안에 있는 내용들을 모두 복사해서 붙여넣으면 끝이다.

 

 

대부분 라벨링 작업을 하는 Yolo_mark와 darknet을 같은 OS에서 같은 설정으로 돌리는 편인데, 필자는 그러지 않았다. Yolo 외에도 해야할 작업이 있어서 급한대로 Yolo_mark만 윈도우(Windows 10)에서

그냥 리눅스에서 AlexeyAB Yolo_mark를 사용해서 라벨링을 진행했으면 전혀 문제될 일이 없었던 일인데, 라벨링은 윈도우에서 하고 그 파일들을 그대로 가져와 리눅스에서 쓰려고 하니 개행 방식이 달라 생긴 문제였다.

 

 

 

[Reference]

https://kamjum.tistory.com/archive/20090825

https://github.com/pjreddie/darknet/issues/611

 

728x90
728x90