1. Mahotas
1.1 Mahotas
https://mahotas.readthedocs.io/en/latest/
- pip install mahotas
- Mahotas는 Python 용 컴퓨터 비전 및 이미지 처리 라이브러리
- 여기에는 속도를 위해 C ++로 구현 된 많은 알고리즘이 포함되어 있으며 매우 깨끗한 Python 인터페이스를 사용하여 numpy 배열에서 작동함
2. 실습
2.1 데이터 설명
https://github.com/luispedro/BuildingMachineLearningSystemsWithPython/tree/master/SimpleImageDataset
- 건물, 자연경관, 문서 각 30장짜리 데이터
- Building Machine Learning Systems with Python의 예제 자료
2.2 Data Load
1
2
3
4
5
6
7
from glob import glob
import mahotas as mh
import numpy as np
import matplotlib.pyplot as plt
images = glob('./data/SimpleImageDataset/*.jpg')
images[:5]
1
2
3
4
5
['./data/SimpleImageDataset/text20.jpg',
'./data/SimpleImageDataset/building13.jpg',
'./data/SimpleImageDataset/text08.jpg',
'./data/SimpleImageDataset/building07.jpg',
'./data/SimpleImageDataset/scene07.jpg']
- 필요한 패키지를 불러오고, glob을 활용하여 각 이미지경로를 list에 담음
2.3 라벨 처리
1
images[0][26:-len('00.jpg')]
1
'text'
- 파일의 라벨을 보면 text20.jpg 처럼 text의 20번째 jpg 파일이란 뜻
- 라벨 뒤의 번호는 버리고 text만 가져옴
- 이미지 파일이 있는 경로가 다르기 떄문에 오프셋인덱스의 26은 각자 상황에 맞게 바꿔야함
2.4 Gray로 변경
1
2
3
im = mh.imread(images[0])
im = mh.colors.rgb2gray(im, dtype=np.uint8)
im
1
2
3
4
5
6
7
array([[156, 176, 175, ..., 189, 187, 186],
[154, 171, 169, ..., 188, 186, 185],
[161, 175, 170, ..., 187, 186, 186],
...,
[152, 153, 153, ..., 181, 181, 182],
[152, 152, 152, ..., 181, 180, 182],
[151, 152, 152, ..., 182, 181, 183]], dtype=uint8)
- 이미지들을 Gray 컬러로 변경함
2.5 Haralick 적용
1
mh.features.haralick(im)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
array([[ 3.66204021e-03, 7.44385321e+01, 9.69875419e-01,
1.23551148e+03, 4.76090180e-01, 3.21647886e+02,
4.86760740e+03, 7.07458389e+00, 9.51129063e+00,
1.00520606e-03, 2.93680057e+00, -4.35358414e-01,
9.97483493e-01],
[ 2.84549272e-03, 1.19362555e+02, 9.51673431e-01,
1.23495790e+03, 4.04957709e-01, 3.21652894e+02,
4.82046903e+03, 7.07435139e+00, 9.86550048e+00,
8.21391898e-04, 3.27570061e+00, -3.76958948e-01,
9.94872815e-01],
[ 3.66198391e-03, 5.61980068e+01, 9.77246908e-01,
1.23495320e+03, 4.78601123e-01, 3.21649202e+02,
4.88361480e+03, 7.07197481e+00, 9.44835451e+00,
1.03328177e-03, 2.83518971e+00, -4.45619712e-01,
9.97778262e-01],
[ 2.82616958e-03, 1.26394950e+02, 9.48826212e-01,
1.23495792e+03, 4.03305323e-01, 3.21652893e+02,
4.81343672e+03, 7.07529020e+00, 9.88137065e+00,
8.17570442e-04, 3.28551507e+00, -3.74348101e-01,
9.94707031e-01]])
- Haralick는 이미지의 날카로움을 잘 나타낸다고 알려져 있음
- Haralick는 이미지의 질감에 대해 2차원 특징을 추출하는 알고리즘
2.6 이미지를 특성 데이터로 전환
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import time
features = []
labels = []
start = time.time()
for im in images:
labels.append(im[26:-len('00.jpg')])
im = mh.imread(im)
im = mh.colors.rgb2gray(im, dtype = np.uint8)
features.append(mh.features.haralick(im).ravel())
print(f'fit time : {time.time() - start}')
1
fit time : 26.879966974258423
- 이미지간 유사도 검출을 위해 이미지를 특성 데이터로 전환함
2.7 Array 전환
1
2
3
features = np.array(features)
labels = np.array(labels)
features
1
2
3
4
5
6
7
8
9
10
11
12
13
array([[ 3.66204021e-03, 7.44385321e+01, 9.69875419e-01, ...,
3.28551507e+00, -3.74348101e-01, 9.94707031e-01],
[ 1.28249663e-02, 4.87581223e+01, 9.94975935e-01, ...,
3.91602238e+00, -3.87974632e-01, 9.97929776e-01],
[ 7.63507483e-04, 4.50258748e+01, 9.89989318e-01, ...,
3.76396230e+00, -3.97447535e-01, 9.98546677e-01],
...,
[ 2.75960062e-03, 1.08364337e+02, 9.54449800e-01, ...,
3.44586857e+00, -3.70228466e-01, 9.95528380e-01],
[ 4.44557401e-03, 5.74946979e+01, 9.54265194e-01, ...,
3.42370629e+00, -3.36906001e-01, 9.90473989e-01],
[ 3.85204285e-04, 8.62514064e+01, 9.89901742e-01, ...,
4.11483879e+00, -3.67041452e-01, 9.98309470e-01]])
- 생성한 결과를 array로 변경함
2.8 Logistic Regression 적용
1
2
3
4
5
6
7
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
clf = Pipeline([('preproc', StandardScaler()),
('classifier', LogisticRegression())])
clf
1
2
Pipeline(steps=[('preproc', StandardScaler()),
('classifier', LogisticRegression())])
- Standardscaler와, LogisticRegression을 pipeline으로 생성
2.9 Cross Validation
1
2
3
4
from sklearn.model_selection import cross_val_score
scores = cross_val_score(clf, features, labels)
scores
1
array([0.77777778, 0.88888889, 0.83333333, 0.88888889, 0.77777778])
- CV를 5번 진행하였을떄 라벨(text 등)을 맞춘 확률
1
print('Accuracy: {:2%}'.format(scores.mean()))
1
Accuracy: 83.333333%
- CV의 Accuracy는 83%정도 나온다
2.10 Scaler
1
2
3
4
5
6
from scipy.spatial import distance
sc = StandardScaler()
features = sc.fit_transform(features)
dists = distance.squareform(distance.pdist(features))
- feature에 scaler를 손으로 적용
2.11 Dists는?
1
dists[0]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
array([ 0. , 9.52430388, 6.80370623, 9.32497065, 11.25987833,
10.61131364, 9.4115134 , 10.59962453, 1.77757172, 9.41331504,
13.44918325, 3.00852352, 6.28968132, 8.65644664, 10.61250131,
14.90126811, 16.93407315, 8.82744014, 13.01219666, 12.19972587,
7.91865399, 3.32765773, 10.00279286, 9.30144472, 6.9250823 ,
5.90013122, 9.86700903, 14.41636827, 11.73352847, 7.69310467,
14.42948581, 11.93597518, 8.64056175, 4.14724299, 10.57420591,
9.42784866, 2.71311061, 9.60793104, 9.13885778, 3.21521643,
7.92824414, 8.97416642, 11.45093424, 10.59822376, 1.63251016,
9.21061649, 7.58279627, 10.7034599 , 7.53869737, 3.80226852,
3.70638927, 8.66907659, 12.77482358, 10.85494835, 3.99808513,
10.18964684, 3.56897747, 16.7687143 , 10.46788865, 5.13169458,
6.0190094 , 10.50286623, 14.49668247, 16.94976398, 11.12082812,
8.78755595, 14.83611024, 5.64524318, 11.34606274, 3.85074009,
9.24280937, 8.01420865, 6.93247105, 4.90357171, 10.93565002,
12.63837001, 19.37773956, 9.68593925, 10.77371778, 3.27491197,
2.13785205, 10.99261702, 8.97774871, 4.225051 , 4.6199186 ,
11.70321631, 15.44084137, 2.30388604, 3.66714748, 10.50795977])
- dists 행렬은 각 이미지가 어떤 이미지와 가장 비슷한지 거리를 보여주는것임
- dists[0]은 0번째 이미지가 다른 나머지 이미지들과의 거리를 나타냄
2.12 유사한 이미지를 찾는 함수
1
2
3
4
def selectimage(n, m, dists, images):
image_position = dists[n].argsort()[m]
image = mh.imread(images[image_position])
return image
- n : 유사한 이미지를 찾을 이미지
- m : 찾을 갯수
2.13 유사한 이미지 4개를 그리는 함수
1
2
3
4
5
6
7
8
9
def plotImages(n):
fig, ax = plt.subplots(1,4, figsize = (15,5))
for i in range(4):
ax[i].imshow(selectimage(n,i, dists, images))
ax[i].set_xticks([])
ax[i].set_yticks([])
plt.show()
- 유사한 이미지를 찾을 번호를 입력하면 비슷한 이미지 4개를 출력해준다
2.14 유사한 이미지 찾기
1
plotImages(10)
- 10번 이미지와 비슷한 사진을 찾아봤음
1
plotImages(11)
- 11번 이미지와 비슷한 사진을 찾았고, 문서 이미지는 잘 찾는듯 함
1
plotImages(32)
- 32번 이미지와 비슷한 사진을 찾았고, 건물도 잘찾음
3. 요약
3.1 요약
- 이미지를 처리하는 알고리즘을 사용하여 유사 이미지 검색을 해보았는데 생각보다 잘 나와서 신기했다.
- 또한 이미지에 대한 라벨을 넣고 그 라벨을 맞추는 것도 83%라고 하니 낮은 수준은 아닌듯 하다
- 하지만 이미지는 딥러닝 부분이 더 강력한것으로 알고 있으니, 나중에 딥러닝도 해보는것이 좋을듯 하다
- 유사 이미지라는게 사실 추천 시스템과도 맥락을 같이 한다.