3. About Program - min942773/PR_Project GitHub Wiki
이미지 불러오기
caltech_dir = "/content/train/"
lists = paths.list_images(caltech_dir)
X = []
y = []
for l in lists:
path = os.path.dirname(l)
X.append(cv2.imread(l))
y.append(os.path.basename(path))
print(len(X))
train 파일을 불러와 이미지는 X라는 배열에, label은 y라는 배열에 저장합니다.
caltech_dir = "/content/testAll_v2/"
lists = paths.list_images(caltech_dir)
X_final = []
img_name = []
for l in lists:
path = os.path.dirname(l)
X_final.append(cv2.imread(l))
img_name.append(l[-14:])
X_final = np.array(X_final)
img_name = np.array(img_name)
test 파일은 이미지의 이름이 제출 시 들어가게되므로 이미지는 X_final이라는 배열에, 이미지 이름은 img_name이라는 배열에 저장하였습니다.
denseSIFT descriptor구하기
def computeSIFT(data):
x = []
for i in range(0, len(data)):
sift = cv2.xfeatures2d.SIFT_create()
img = data[i]
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
step_size = 8
kp = [cv2.KeyPoint(x, y, step_size)
for x in range(0, img_gray.shape[0], step_size)
for y in range(0, img_gray.shape[1], step_size)]
dense_feat = sift.compute(img_gray, kp)
x.append(dense_feat[1])
return x
X_sift = computeSIFT(X)
all_train_desc = np.vstack((descriptor for descriptor in X_sift))
step size가 8인 dense sift를 구해주는 함수인 computeSIFT입니다. train 이미지를 이 함수를 이용하여 descriptor를 구합니다.
codebook 계산하기
def clusterFeatures(all_train_desc, k):
seeding = kmc2.kmc2(all_train_desc, k)
model = MiniBatchKMeans(k, init=seeding).fit(all_train_desc)
return model
kmeans = clusterFeatures(all_train_desc, 600)
아까 구한 descriptor에 kmeans를 이용하여 600 size의 codebook를 구합니다.
SPM으로 histogram 구하기
def getImageFeaturesSPM(L, img, kmeans, k):
W = 256
H = 256
step_size=8
W_des = int(W/step_size)
H_des = int(H/step_size)
h = []
img = img.reshape(H_des, W_des, 128)
for l in range(L+1):
w_step = math.floor(W/(2**l))
h_step = math.floor(H/(2**l))
x, y = 0, 0
for i in range(1,2**l + 1):
x = 0
for j in range(1, 2**l + 1):
desc = X_sift[y:y+h_step, x:x+w_step, :].reshape(-1, 128)
histo = input_vector_encoder(desc, kmeans.cluster_centers_)
weight = 2**(l-L)
h.append(weight*histo)
x = x + w_step
y = y + h_step
hist = np.array(h).ravel()
if L == 0:
hist = hist.astype('float64')
dev = np.std(hist)
hist -= np.mean(hist)
hist /= dev
return hist
def getHistogramSPM(L, data, kmeans, k):
x = []
for i in range(len(data)):
hist = getImageFeaturesSPM(L, data[i], kmeans, k)
x.append(hist)
return np.array(x)
train_histo = getHistogramSPM(2, X, kmeans, 600)
getImageFeaturesSPM에서는 이미지를 레벨에 맞춰 자른 뒤 자른 이미지의 descriptor를 구한 뒤 histogram을 구합니다.
SVM 학습
C_range = 10.0 ** np.arange(-3, 3)
param_grid = dict(C=C_range.tolist())
clf = GridSearchCV(LinearSVC(), param_grid, cv=5, n_jobs=-2)
clf.fit(train_histo, y)
구한 histogram을 LinearSVC와 GridSearch를 이용하여 학습시켰습니다.
TEST
X_histo = getHistogramSPM(2, X_final, kmeans, 600)
y_predict = clf.predict(X_histo)
test 이미지를 위와 같은 방법으로 histogram을 만들어준 뒤 학습시킨 모델로 예측값을 얻습니다.
submit file 만들기
df = pd.read_csv('/content/Label2Names.csv')
df = np.array(df)
result = []
for i in range(len(y_predict)):
flag = 0
if y_predict[i] == 'BACKGROUND_Google':
flag = 1
result.append(102)
else:
for j in range(len(df)):
if y_predict[i] == df[j][1]:
result.append(df[j][0])
flag = 1
if flag != 1:
result.append(1)
result = np.array(result)
img_name = np.array(img_name)
result = result.reshape(-1, 1)
img_name = img_name.reshape(-1, 1)
total_result = np.hstack([img_name, result])
df = pd.DataFrame(total_result, columns=['Id', 'Category'])
df.to_csv('results-mjkim-v4.csv', index=False, header=True)
! kaggle competitions submit -c 2019-ml-finalproject -f results-mjkim-v4.csv -m "mjkim-20191123"
label과 이름이 적힌 csv 파일을 불러온 뒤 이를 이용해 predict값을 label로 바꿔줍니다. (numpy array로 변환하니 1번 label이 잘려서 따로 처리해주었습니다..) 그 후 csv 파일로 변환하여 제출하였습니다.
level | codebook size | stepsize | accuracy |
---|---|---|---|
0 | 200 | 4 | 32 |
1 | 200 | 4 | 48 |
2 | 200 | 4 | 57 |
0 | 600 | 8 | 46 |
1 | 600 | 8 | 51 |
2 | 600 | 8 | 57 |