어떻게 이미지 데이터를 모을 것인가? (Data Gathering)


머신러닝 알고리즘을 이용하여 얼굴을 인식하는 프로그램을 만들기 위해서는

모델을 학습시킬만한 충분한 이미지 데이터를 모으는 것이 필수입니다.

제 프로젝트에서는 사람 한명당 30장 정도의 사진을 이용할 예정인데

네이버나 구글에서 일일이 그사람 이름을 검색하여 폴더에 따로 저장하기란

여간 귀찮은 일입니다. 그렇기에 키워드를 입력하기만 하면 여러 포털을 통해

검색한 이미지 데이터를 자동으로 PC로 다운로드 시켜주는 응용프로그램을 소개하겠습니다.




Extreme Picture Finder



위 제목을 클릭하시면 다운로드가 가능합니다.



프로젝트 메뉴 -> 새검색을 클릭한 뒤 원하는 키워드를 입력하시면 위 사진과 같이 관련 

이미지를 자동으로 PC로 다운로드 시켜주며 정지버튼을 눌러 정지할 수 있습니다.


정확한 검색기준은 모르겠으나(아마도 키워드에 해당하는 사진을 죄다 다운로드시키는 듯)

같은사진이 상당히 많고 다른 인물의 사진까지 다운로드되는 경우도 많습니다.


이는 다음의 두가지를 이용하여 해결가능합니다.





Visipics



위 제목을 클릭하시면 다운로드 가능합니다. (좌측메뉴->다운로드)



위에 보여지는 것처럼 중복된 사진들을 묶어서 보여주며 여러 유용한 버튼들을 이용하여

원하는 사진만 남기고 삭제할 수 있습니다. 예를 들면 중복된 사진들 중 낮은해상도를 갖는 사진 삭제 등






Clova Face Recognition API



Visipics를 사용하여 중복된 이미지 데이터를 제거 했음에도 여전히 의도에 맞지 않는

데이터들이 있을 것입니다. Extreme Picture Finder를 통해 원하는 이미지 데이터를 다운받은 뒤

Visipics를 이용하여 중복을 제거하였다면 이제 Naver Developers에서 제공하는 

Clova Face Recognition API를 이용하여 다운로드받은 이미지 데이터가 정말 내가 원하는

인물의 얼굴인지, 그 인물과 어느 정도 닮았는지 등의 JSON형식의 데이터를 얻을 수 있습니다.








API를 이용하는 방법은 위 소제목 하이퍼링크를 눌러 보시면 자세히 나와 있으니 참고하시면 됩니다.

Java PHP Node.js Python C# 각 언어별로 구현 예제를 제공하고 있으니 별 무리 없이 원하는

데이터를 얻을 수 있도록 프로그래밍 할 수 있을 겁니다. 저는 파이썬으로 해보았는데 return 데이터 타입의

한계로 인해 아무래도 Node.js를 사용하시는 편이 데이터를 처리하기 좋을 것 같습니다.




아래는 CFR API에서 제공하는 예제를 응용하여 제가 갖고 있는 이미지 데이터를 유명인 얼굴 인식 서버에

전달하여 확인한 뒤 해당 연예인 얼굴이면서 사진에 얼굴이 그 연예인 하나만 있는 경우 다른 폴더에 

저장시키는 코드입니다. (반드시 네이버에서 제공하는 예제를 먼저 학습한 뒤 제 코드를 봐야 이해가 됩니다)




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import os
import sys
import requests
from shutil import copyfile
path = "faces\\siun"
imagePaths = [os.path.join(path,file_name) for file_name in os.listdir(path)]
count = 0
client_id = "Your_Client_ID"
client_secret = "Your_Client_Secret"
# url = "얼굴감지 URL" // 얼굴감지
url = "얼굴인식 URL" # 유명인 얼굴인식
for imagePath in imagePaths:
    files = {'image'open(imagePath, 'rb')}
    headers = {'X-Naver-Client-Id': client_id, 'X-Naver-Client-Secret': client_secret }
    response = requests.post(url,  files=files, headers=headers)
    rescode = response.status_code
    if(rescode==200):
        if(response.text.find("이시언"!= -1 and response.text.find("\"faceCount\":1}"!= -1):
            print (response.text)
            count += 1
            copyfile(imagePath, "faces\\siun2\\User.1." + str(count) + ".jpg")
    #else:
    #    print("Error Code:" + rescode)
cs



8, 9행의 client_id와 client_secret는 naver developers 지시에 따라 본인의 App을 등록하시면
받을 수 있습니다. 저 자리에 본인 것을 써 넣으시면 됩니다.


10, 11행의 url도 naver 코드를 복사하면 원래 url 주소가 기입되어 있는데 
여기에 서버주소를 공개해도 되는지 몰라서 일단은 지웠습니다. 앞서 말한 url로 들어가 보면 확인가능합니다. 


저는 배우 이시언의 이미지 데이터를 이용하여 진행하였습니다. 간단히 제가 짠 코드만 리뷰해 보면 다음과 같습니다.


path = "faces\\siun"

imagePaths = [os.path.join(path,file_name) for file_name in os.listdir(path)]

소스코드와 faces 폴더를 같은 디렉토리에 위치시켰고 이미지 데이터가 있는 디렉토리 경로를 
path에 지정했습니다. 이후 os.listdir()을 이용하면 해당 path 폴더 내의 모든 파일 이름을 
list 형태로 반환받을 수 있습니다. 그런 뒤 join()을 이용하여 상대 경로를 얻어 옵니다.


for imagePath in imagePaths:

각 이미지 데이터에 대해서

if(response.text.find("이시언"!= -1 and response.text.find("\"faceCount\":1}"!= -1):
copyfile(imagePath, "faces\\siun2\\User.1." + str(count) + ".jpg")

위 코드는 서버에 이미지 데이터를 전달한 뒤 반환받은 값에 대해서
사진이 "이시언"이라고 응답했으면서 사진에 얼굴이 하나뿐인 경우
파일을 다른 폴더에 복사하겠다는 코드입니다.



return 값이 json이 아니라 말 그대로 json 형식이더라구요....
response.text의 return 타입이 json 형식의 str object 타입이므로 키 값으로 접근할 수 가 없어
저는 find() 함수를 사용하여 위와 같이 원하는 값을 처리하였습니다.
(response에서 key 값으로 접근 가능한 json 데이터를 얻는 법을 아시는 분은 댓글 달아주시면 감사하겠습니다)



실행 결과는 다음과 같습니다.






그리고 이와 동시에 새 폴더에 아래와 같은 원하는 데이터를 얻을 수 있습니다.

(데이터를 얻은 뒤 수작업으로 몇개를 삭제하여 중간중간 번호가 비어있으니 무시하셔도 됩니다.)








Naver Developers에서 아주 마음에 드는 API를 제공하긴 했지만...

구체적인 내용은 공개하지 않아서 조금 답답하긴 하네요 ㅎ.ㅎ















더보기

댓글,

jayharvey

머신러닝/딥러닝 관련 글을 포스팅할 예정입니다 :)