내 프로젝트의 핵심 구현이 여기다.
넘 듀근 거린다.
난항이 예상된다.
1) 연동한 media 폴더 내에 있는 데이터를 주피터 노트북에서 딥러닝 코드로 처리
2) 안드로이드에서 이미지를 media 폴더로 넣고, 1) 과정과 연결
일단 이번 주에 최소 1) 까지는 끝내는 게 목표다.
__________________________________________________________________________________________________________
1) serializer.py
직렬화하는 클래스로, DB안에 사용자 프로필 사진, 이메일, 이름, 성별이 있다고 가정하면 사용자의 모델 인스턴스를 JSON 형태 혹은 Dictionary 형태로 직렬화 해주는 파일이다.
2) 딥러닝 코드를 views 에서 돌리기
def main():
# --------- 1. get image path and name ---------
print('main 1')
model_name = 'u2netp' # u2netp
# image_dir = os.path.join(os.getcwd(), 'test_data', 'test_images')
# prediction_dir = os.path.join(os.getcwd(), 'test_data', model_name + '_results' + os.sep)
model_dir = os.path.join(os.getcwd(), 'mytestsite/saved_models', model_name, model_name + '.pth')
image_dir = os.path.join(os.getcwd(), 'mytestsite/images')
prediction_dir = os.path.join(os.getcwd(), 'mytestsite/results' + os.sep)
이런 식으로 각각 u2net_train.py 에서 model, image, prediction 이 저장된 디렉토리를 변경해주었다.
그리고 views.py 에서도 그냥 어제 만들어 놓은 클래스 안에서 u2net_train.py 스크립트를 돌렸다.
다 익숙하지 않은 기술 스택이라 잘 몰랐었는데, 딥러닝 모델 그냥 파이참에서 돌릴 수 있다.
구글 코랩 -> 주피터 노트북 -> 파이참 까지. 약간의 코드 변형들을 계속 하면서
이해 안 되던 tmi 딥러닝 모델 돌리는 부분도 조금 이해가 되는 것 같다.
오픈소스 변형하는 재미가 쏠쏠하다.
class PostViewset(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
# 나중에 서버에 올릴 때 이 경로 처리하기
os.system('python C:/Users/sewon/django_test/mytestsite/mytestsite/u2net_test.py')
이 경로는 나중에 aws 서버 사서 올릴 때 따로 처리해줘야 할 듯 싶다.
쨋든 그 부분은 나중에 생각하도록 하고,
이제 이미지 포스트 해서 media에 넣은 다음에 바로 저 코드가 돌아가는지 확인해야겠다.
교훈 : 쫄지말고 에러 trace back 하기
오늘 할당량에서 중요한 부분을 끝내서 감격스럽다.
3) POST 가 들어올 때 마다 비동기로 처리하기
위의 2) 번을 일찍 구현하고 신나하다가 알게 된 사실은 저
os.system('python C:/Users/sewon/django_test/mytestsite/bg_removal/u2net_test.py')
이 부분이 $ python manage.py runserver 을 했을 때 한 번 만 돌아가고, 매번 새로운 POST가 들어올 때 마다 처리하지 못한다는 것이었다.
그래서 나는 비동기 처리가 가능한지 마구마구 찾아봤다.
정보가 많이 없었다.
정보가 많이 없을 땐 쎄한 느낌이 든다.
웬만하면 잘못된 접근을 하고 있다는 뜻이다.
보니 내가 import 해서 사용하는 viewsets 라이브러리는 Views의 get, post 이런 메소드는 없지만 대신
POST 가 들어올 때 마다 처리할 수 있는 create 메소드가 있다.
create 메소드를 사용해보니 또 당면한 문제는,
def create 메소드는 데이터를 받고 media 폴더 등 데이터를 저장하기 전에 실행되기 때문에,
딥러닝이 돌아가는 프로그램 파일을 그 안에서 돌리면,
이미지 파일이 디렉토리에 들어오기 전에 실행이 돼서 당연히 이미지 처리를 할 수가 없었다.
그래서 여기서 한참 헤메이다가,
def create(self, request):
post_data = request.data
fileObj = request.FILES['image'] # 파일 이름을 받는다. [필드명]
file_name = str(request.FILES['image']).split('.') # 이름 추출을 위해 확장자를 제거해줬다.
file_name = file_name[0]
fs = FileSystemStorage() # 이 메소드를 위해 해당 라이브러리 import 한다.
filePathName = fs.save(fileObj.name, fileObj)
filePathName = fs.url(filePathName)
testimage = '.' + filePathName
img = load_img(testimage) # 저기서 media 폴더에 저장되기 이전에 채온 이미지를 불러와서 image라는 폴더에 저장했다.
directory = os.path.join(os.getcwd(), 'bg_removal/images' + os.sep) # + os.sep 이거 붙여줘야함
img.save(directory + file_name+'.jpg')
요런 식으로 media 폴더에 데이터가 저장되기 이전에 이미지를 사용할 수 있었다. 저 이후에서 해당 img로 딥러닝 프로그램을 돌렸다.
아 참고로 클래스형 view와 함수형 view은 구현의 방식이 다른 것이지 하나로 표현이 가능하고 다른 하나로 표현이 불가능 한 것은 없다.
이런 개념을 처음 봐서 멘붕이었는데, 어차피 클래스면 안에서 함수 선언 및 호출도 가능하지 않나 싶어 해보니 다 된다. 교훈은, 로직은 거기서 다 거기다.
그리고 남들이 했으면 응용했다 해도 웬만하면 다 된다.
쫄지 말자!
어제 구현한 부분에 이어 127.0.0.1:8000/posts 이 주소에서 이미지를 넣으면 저렇게 매번의 이미지 POST 마다 이미지 처리되어 results 폴더에 들어간다.
추후 서버에 올릴 때 고려해줘야 하는 것 (코드 상) :
1) 파일 확장자
2) 디렉토리
REFERENCE
1) 비동기 처리 (POST 받고 이미지 따로 받아서 처리하는 과정이 필요해서 참고했는데, 아주 유용했다.)
www.youtube.com/watch?v=mgX-2_ybqNk&list=PLArOU0Emh-VEuIC7_h-twa5ZD9Ha8wwMi&index=6
github.com/sharmasw/ImageClassification_DjangoApp
2) viewsets 를 활용한 클래스형 views에서 get, post 등의 request를 처리하는 메소드들과 활용 예시
stackoverflow.com/questions/48901823/post-request-handling-in-django-rest-framework
viewsets 라이브러리 관련 공식문서 및 번역본 (CRUD 메소드 참고)
www.django-rest-framework.org/api-guide/viewsets/
3) 함수형 view를 클래스형 view로 표현하는 방법. 사용법에 대한 설명. 10분 정도 길이로 개념 파악하는데 유용했다.
역시 유튜브엔 없는게 없다.
www.youtube.com/watch?v=-tqhhT3R6VY&list=PLArOU0Emh-VEuIC7_h-twa5ZD9Ha8wwMi&index=15
다음 포스팅은 안드로이드에서 이미지를 보내는 부분을 추가해보려고 한다.
원래는 카메라로 사진을 찍고 전송하는 것이 original 기획이지만,
일단 사진첩에서 이미지를 업로드하는 식으로 먼저 구현하려고 한다.
아 그리고,
지금은 images 폴더에서 이미지 하나씩만 있어야 돌아가게 구현되어 있다.
이 부분 처리해야 한다!
내일은 칭구 졸업식이라 쉴거다.
굳밤!
'모바일앱 프로젝트' 카테고리의 다른 글
MySql (0) | 2021.03.03 |
---|---|
[안드로이드 스튜디오] 기본 (1) (0) | 2021.02.27 |
Django + Android 이미지 주고 받기 (3) (0) | 2021.02.24 |
Django + Android + MySql (2) (0) | 2021.02.24 |
RESTful API 만들기 (0) | 2021.02.23 |
댓글