대회에서의 train, test set 데이터 크기가 달라서 train 데이터의 이미지 크기를 조정하였다.
이전에 영상처리 강의자료에서 보았듯이 해당 예제에서는 0, 1만을 가지고 인코딩을 수행했지만 이 범위는 더 넓을 수 있고 형태는 "위치, 횟수" 자료구조가 연속적으로 나오는 것이라 할 수 있다.
1. 입력받은 이미지 크기 만큼의 행렬을 만들어 모두 0으로 초기화한다.
2. 현재 mask가 0으로만 이루어져 있다면 반환한다.
3. mask 값을 split() 연산하여 "위치, 횟수"의 구조로 인식할 수 있게 한다.
4. 0으로 초기화된 배열의 해당 위치에서 횟수만큼 값들을 1로 변경한다.
해당 수도코드는 0, 1에 대해서만 처리한 것이다.
데이터의 수
데이터의 통일성
새로운 데이터 nan
import os
import cv2
import pandas as pd
import numpy as np
from PIL import Image
# RLE 디코딩 함수
def rle_decode(mask_rle, shape):
# upsample된 경우는 사진에 건물이 없는 경우도 있어 nan을 판단하여 반환한다.
img = np.zeros(shape[0] * shape[1], dtype=np.uint8)
if pd.isnull(mask_rle):
return img.reshape(shape)
s = mask_rle.split()
starts, lengths = [np.asarray(x, dtype=int) for x in (s[0:][::2], s[1:][::2])]
starts -= 1
ends = starts + lengths
for lo, hi in zip(starts, ends):
img[lo:hi] = 1
return img.reshape(shape)
# RLE 인코딩 함수
def rle_encode(mask):
pixels = mask.flatten()
pixels = np.concatenate([[0], pixels, [0]])
runs = np.where(pixels[1:] != pixels[:-1])[0] + 1
runs[1::2] -= runs[::2]
return ' '.join(str(x) for x in runs)
# 저장하기 위한 경로로 upsample이란 폴더가 존재해야함
relative_folder_path = 'upsample'
absolute_folder_path = os.path.join(os.getcwd(), relative_folder_path)
if not os.path.exists(absolute_folder_path):
os.makedirs(absolute_folder_path)
relative_folder_path = 'upsample/train_img'
absolute_folder_path = os.path.join(os.getcwd(), relative_folder_path)
if not os.path.exists(absolute_folder_path):
os.makedirs(absolute_folder_path)
upsample_csv = "./upsample/train.csv"
data = pd.read_csv("./train.csv")
cnt = 0
columns = ['img_id', 'img_path', 'mask_rle']
df_upsample_csv = pd.DataFrame(columns=columns)
for idx in range(len(data)):
# image 개수를 제한해서 upsample함.
if idx == 3:
break
img_id, img_path, mask_rle = data.iloc[idx]
image = cv2.imread(img_path)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
mask = rle_decode(mask_rle, (image.shape[0], image.shape[1]))
# 나누기의 값을 바꾸는 것으로 데이터의 개수를 더 늘릴 수 있다.
for row in range(0, image.shape[0], (224 // 3)):
for col in range(0, image.shape[1], (224 // 3)):
# 크기를 제한하기 위한 조건이다.
if row + (224 * 1) >= image.shape[0] or col + (224 * 1) >= image.shape[1]:
continue
temp_img = image[row:row + (224 * 1), col:col + (224 * 1)]
temp_mask = mask[row:row + (224 * 1), col:col + (224 * 1)]
# 제작된 img, mask를 다시 이미지 타입과 인코딩된 형태로 변경한다.
temp_img = Image.fromarray(temp_img)
temp_encode_mask = rle_encode(temp_mask)
# 이미지를 저장하기 위해선 train_img라는 폴더가 upsample내부에 있어야 한다.
temp_id = f"train{cnt}"
image_path = f"./upsample/train_img/{temp_id}.png"
temp_img.save(image_path, format="PNG")
cnt += 1
new_data = {
columns[0] : temp_id,
columns[1] : image_path,
columns[2] : temp_encode_mask
}
df_upsample_csv = df_upsample_csv.append(new_data, ignore_index=True)
df_upsample_csv.to_csv(upsample_csv, index=False)