Virtual fitting(feat. cp-vton)

dobby
5 min readJun 13, 2021

드디어 , cp-vton 돌려보자.

아이유 사진에 Lee 옷을 합성할것이다.

저 데이터 mask랑 segmentation하느라 2틀을 써버렷다 어후..
이미지 딥러닝쪽은 처음이라 그런지 삽질을 많이함.

RUN: CUDA_VISIBLE_DEVICES=1 python test.py — name my_own_dataset — stage GMM — workers 4 — dataroot my_own_data — datamode test — data_list test_pairs.txt — checkpoint checkpoints/gmm_train_new/gmm_final.pth

Error: File “/data/juhwan/project/fashion/CP-VTON/cp-vton/cp_dataset.py”, line 99, in __getitem__
pose_data = pose_label[‘people’][0][‘pose_keypoints’]
KeyError: ‘pose_keypoints’

pose_keypoint 데이터 포맷이 달라서 그런거 같다… 맞춰주자.

참고로, openpose 툴을 사용함.

import json, ast
import sys
from os import path
#$1 $2 $3

#print(sys.argv[1])
if len(sys.argv) != 2:
print(“Insufficient arguments”)
sys.exit()

file_name = sys.argv[1]
print(file_name)

with open(sys.argv[1]) as f:
data = json.load(f)
key_value = data[‘people’][0][‘pose_keypoints_2d’]

file_path = path.relpath(“/data/juhwan/keypoints.json”)
with open(file_path) as f:
data2 = json.load(f)

data2[‘people’][0][‘pose_keypoints’] = key_value

#save
with open(sys.argv[1]+”_keypoints.json”,’w’) as outfile:
json.dump(data2, outfile, indent=4)

포맷맞추기 끗-

Run: CUDA_VISIBLE_DEVICES=1 python test.py — name my_own_dataset — stage GMM — workers 4 — dataroot my_own_data — datamode test — data_list test_pairs.txt — checkpoint checkpoints/gmm_train_new/gmm_final.pth

Error:Traceback (most recent call last):
File “test.py”, line 163, in <module>
main()
File “test.py”, line 151, in main
test_gmm(opt, train_loader, model, board)
File “test.py”, line 55, in test_gmm
for step, inputs in enumerate(test_loader.data_loader):
File “/data/juhwan/anaconda3/envs/cp-vton/lib/python3.6/site-packages/torch/utils/data/dataloader.py”, line 517, in __next__
data = self._next_data()
File “/data/juhwan/anaconda3/envs/cp-vton/lib/python3.6/site-packages/torch/utils/data/dataloader.py”, line 1199, in _next_data
return self._process_data(data)
File “/data/juhwan/anaconda3/envs/cp-vton/lib/python3.6/site-packages/torch/utils/data/dataloader.py”, line 1225, in _process_data
data.reraise()
File “/data/juhwan/anaconda3/envs/cp-vton/lib/python3.6/site-packages/torch/_utils.py”, line 429, in reraise
raise self.exc_type(msg)
RuntimeError: Caught RuntimeError in DataLoader worker process 0.
Original Traceback (most recent call last):
File “/data/juhwan/anaconda3/envs/cp-vton/lib/python3.6/site-packages/torch/utils/data/_utils/worker.py”, line 202, in _worker_loop
data = fetcher.fetch(index)
File “/data/juhwan/anaconda3/envs/cp-vton/lib/python3.6/site-packages/torch/utils/data/_utils/fetch.py”, line 44, in fetch
data = [self.dataset[idx] for idx in possibly_batched_index]
File “/data/juhwan/anaconda3/envs/cp-vton/lib/python3.6/site-packages/torch/utils/data/_utils/fetch.py”, line 44, in <listcomp>
data = [self.dataset[idx] for idx in possibly_batched_index]
File “/data/juhwan/project/fashion/CP-VTON/cp-vton/cp_dataset.py”, line 123, in __getitem__
agnostic = torch.cat([shape, im_h, pose_map], 0)
RuntimeError: Sizes of tensors must match except in dimension 0. Got 256 and 1080 in dimension 1 (The offending index is 1)

이미지 사이즈 안맞는듯. 256 X 192로 resize해보자.

파이프라인 만들기 여간 귀찮네..

import sys
from PIL import Image

if len(sys.argv) != 2:
print(“Insufficient arguments”)
sys.exit()

img = Image.open(sys.argv[1])
img_resize = img.resize((256, 192))
img_resize.save(‘resize_’+sys.argv[1])

아.. pose 데이터도 차원이 달라서그러겠지..?

resize해두고 다시해보자 아…………..256X192가아니라 / 192 X 256임..

#

Run: CUDA_VISIBLE_DEVICES=1 python test.py — name my_own_dataset — stage GMM — workers 1 — dataroot my_own_data — datamode test — data_list test_pairs.txt — checkpoint checkpoints/gmm_train_new/gmm_final.pth

Error: RuntimeError: Given groups=1, weight of size [64, 22, 4, 4], expected input[1, 30, 256, 192] to have 22 channels, but got 30 channels instead

채널개수가 다르단다. segmentation을 다른 툴을 써서그런가..

나와 같은 issue가있는사람이있다. 그대로 해보자.

안되네..

channel 이 8개나 더많네..

각각 채널 몇개씩인지 찍어보자.

data/test 에서 (height, width, channel)

cloth → (256, 192, 3)
cloth-mask → (256, 192, 3)
image → (256, 192, 3)
image-parse → (256, 192, 3)

my_own_data/test 의 경우는

cloth → (256, 192, 3)
cloth-mask → (256, 192, 3)
image → (256, 192, 3)
image-parse → (256, 192, 3)

똑같다………………………

음……. 만약 test 셋 1개 데이터만 하면어떨까? 잘 작동하네….

내생각에 문제는 pose heatmap 이문제다! 우리는 28개로 잡히는듯싶다.

아님 segmentation 툴을 다른거 써서 channel 개수가 다른건가….? 감이안오네;

pose 만 바꿔서 돌려보자.

역시 안된다 똑같은 에러가 뜬다. → 일단 확실히 pose 가 문제 → pose에서 18channel 이 만들어져야한다. → cp-vton에서는 전처리를 한번수행하긴함. 이를 따라가야할듯.

convert_data.m (사실데이터 이걸로 만들면되는거같긴한데; matlab이없긴한데)

convert_data.m

이거 코드만보면.. 데이터 input으로 들어갈 형태를 만들어준다.

……………… 어떡하지? 무료평가판잇긴한데…

python code로 짜보지머

pose에 관련된 코드는

#load
pose = importdata([source_root_dir '/' 'pose/' s_name]);
key_points = zeros(point_num,3);
for j = 1:point_num
index = int32(pose.subset(j))+1;
if index ~= 0
key_points(j,:) = pose.candidate(index,1:3);
end
end
#resize
for j = 1:point_num
key_points(j,1) = key_points(j,1) / w * fine_width;
key_points(j,2) = key_points(j,2) / h * fine_height;
end
#save the pose info
key_name = strrep(imname, '.jpg', '_keypoints.json');
f = fopen([target_root_dir '/' mode '/pose/' key_name], 'w');
fprintf(f,'{"version": 1.0, "people": [{"face_keypoints": [], "pose_keypoints": ');
key_points = reshape(key_points', 1, 54);
str_key_points = mat2str(key_points);
str_key_points = strrep(str_key_points,' ', ', ');
fprintf(f,str_key_points);
fprintf(f,', "hand_right_keypoints": [], "hand_left_keypoints": []}]} ');
fclose(f);

하나씩 보자.

pose = importdata([source_root_dir ‘/’ ‘pose/’ s_name]);
VITON데이터셋에서 불러와야지 어떻게 생겨먹은지 알텐데.. VITON에서 비공개해놔서 알수가없다..

아……………..VITON에서는 Realtime multiperson 2d pose estimation using part affinity fields. 논문가지고 pose estimation을한거고.. Openpose format에 맞추어서 설정한거라한다…..

그럼 Realtime multiperson 2d pose estimation using part affinity fields.(2017) 논문에서 output 어떻게 나오는지 살펴보자. 엥 저게 Openpose(2019)논문이라네 ㅋㅋ

내가 뽑아낸 keypoint는 Openpose이다.

차이점이 무엇인지살펴보자.

아 내머리 돌아버리겠네

Openpose .bin — help 하니깐

model_pose (Model to be used. E.g., `BODY_25` (fastest for CUDA version,^M
most accurate, and includes foot keypoints), `COCO` (18 keypoints), `MPI`^M
(15 keypoints, least accurate model but fastest on CPU), `MPI_4_layers`^M
(15 keypoints, even faster but less accurate).) type: string^M

이런 말이있다. COCO로 설정해두고 18keypoints를 뽑아보자.

원래는 default(body_25)로해서 차원이 높아진듯하다.

cd models
bash getModels.sh

CUDA_VISIBLE_DEVICES=1,2 ./build/examples/openpose/openpose.bin — model_pose COCO — image_dir tmp_input/ — write_json tmp_keypoint/

아………….. 다시 돌려보니깐 이제는 23channel 이라고한다. 어디가 문제일까;

1개의 channel이 더있는거네;;

#Because your images in image-parse are 24 bit RGB images, and the images in image-parse in dataset are indexed images.
You should save the parsed images as indexed color image format or grayscale.

내가 만든 image-parse
논문 dataset의 image-parse

따라서 위의 #은 문제없는거같은데.

그러면 결국엔 RGB 채널이 4개인거같은데……….?

내파일이 애초에 PNG 파일이였는데 이름을 linux에서 jpg로바꿧는데 이것이 문제가 생긴거같다.

참… 이미지 처음이라 이런 삽질은 당연하게 느껴야하는건가;

from PIL import Image
import sys

if len(sys.argv) != 2:
print(“Insufficient arguments”)
sys.exit()

img = Image.open(sys.argv[1], mode=’r’, formats=None)
img = img.convert(“RGB”)
sep=’.’

new_name = sys.argv[1].split(sep,1)[0] + ‘.jpg’

img.save(new_name)

PNG → JPG로 바꾸니 채널 22개로 딱맞아서 돌아간다.

결과는 성능완전후지다. 왜후진지 찾아보자. 어떤데이터가 눈으로보기에 안좋은지 살펴보고, 어떤 모델등,이제부터는 수식, 데이터, 모델 전부 뜯어보자 // 학습을더해야하나? // 원래 차원29개였으니, keypoint 더 많은거 사용해볼까?

일단 코드부터정리좀하자;;

--

--