컴퓨터가 이미지를 분류하도록 만들기 (KNN) - 실패

상상·2022년 11월 30일
0

Tasks

목록 보기
1/1

K-nearest neighbor - 😎 머신러닝 중 가장 간단한 알고리즘 이다.

위 그림의 점들이 하나에 🖼️이미지 라고 가정해보자.

이때 찾고자 하는 이미지를 좌표상에 표시하고 가장 가까운 점들이 어떤그룹에 속해있는지 체크해 이미지를 분류하는 방법이다.

✔ 문제를 ️2가지로 세분화 할 수 있다.

  1. 어떻게 이미지를 좌표에 표시할 것인가?
  2. 어떻게 거리를 계산할 것인가.

어떻게 거리를 계산할 수 있나?

- 유클리드 거리

d(A,B)=(x1x2)2+(y2y1)2d(A,B) = \sqrt{(x_1-x_2)^2 + (y_2-y_1)^2}

피타고라스 이용한거

- 맨해튼 거리

d(A,B)=x1x2+y1y2d(A,B)=∣x1−x2∣+∣y1−y2∣

가로세로 더하는 방법 이다

❗거리계산보다 x, y 범위를 일치시키는게 중요하다.

예를들어 y 는 1000씩 증가하는데 x 는 1씩 증가하면 x 값이 아무리 변해도 두 점 사이의 거리는 y 값만 영향을 받게 되기 때문

- 최소 최대 정규화

Z=(Xmin(X))(max(X)min(X))Z = \frac {(X-min(X))} {(max(X)-min(X))}

복잡해보이는데 그냥 퍼센트로 표시하는방법

  • 최대, 최소값을 정해야하는데 가끔 입력데이터가 범위를 벗어나는게 문제

- z점수 표준화

z=Xμσz=\frac{X-\mu}{\sigma}

σ\sigma 는 표준편차, μ\mu 는 평균이다.

  • 평균 으로부터의 변화량 이라고 설명하면 되려나?
  • 보통 -2 ~ 2 사이의값으로 표현된다.

문제 - 어떻게 이미지를 좌표에 표시할 것인가.

- 이게 문제다

위 예시들은 데이터에 변수가 2가지 일때 이다. (크기와 무게 , 온도와 습도 같은)

하지만 이미지 같은경우는 FHD사이즈에 rgb 이미지만 하더라고 6,220,800 개의 변수가 존재하게된다. (1920 x 1080 x 3)

2개의 FHD이미지 (I1I_1, I2I_2)의 거리를 맨해튼 방식을 이용해 구하는 수식이다. (변수 범위는 rgb 가 0-255 사이이므로 고려하지 않아도 된다.)

d(I1 , I2)=6220800I16220800 I26220800d(I_1\ ,\ I_2) = \sum_{6220800}|I_1^{6220800}\ - I_2^{6220800}|

벌써 뭔가 이상하다


파이썬 으로 작성해보면 (같은사이즈 이미지 3장을 준비한다)
import numpy as np
import cv2

image1 = cv2.imread("test1.jpg")
image2 = cv2.imread("test2.jpg")
image3 = cv2.imread("test3.jpg")

distance1 = 0
for i in range(len(np.ravel(image1))):
    distance1 += np.abs(int(np.ravel(image1)[i]) - int(np.ravel(image2)[i]))
print(distance1) #867735388


distance2 = 0
for i in range(len(np.ravel(image1))):
    distance2 += np.abs(int(np.ravel(image1)[i]) - int(np.ravel(image3)[i]))
print(distance2) #417102106

=> test1.jpg
=> test2.jpg
=> test3.jpg

- 결과

위 알고리즘이 이미지 분류를 잘 했다면 distance1 의 값이 distance2 보다 작아야하지만 반대로 나왔다.
픽셀단위로 비교하다보니 test1 이랑 test3 이 초록색이 많아서 인지 훨씬 값이 적게 나온다.

=> test4.jpg
test4랑 test2랑 비교하면

import numpy as np
import cv2
import time

image1 = cv2.imread("test2.jpg")
image2 = cv2.imread("test4.jpg")

startTime = time.time()

distance = 0
for i in range(len(np.ravel(image1))):
    distance += np.abs(int(np.ravel(image1)[i]) - int(np.ravel(image2)[i]))

duration = time.time() - startTime

print("time: ", duration) # time : 9.515893936157227
print("distance : ", distance) # distance : 240185135

윈도우 12세대 intel i7 인데 FHD 2장 비교하는데 9초 걸리는 거면 글러먹은듯 하다.

이미지 분류 알고리즘이 아니라 비슷한 색 찾는 알고리즘을 만든거 같다.


성능개선 버전

import numpy as np
import cv2
import time

image1 = cv2.imread("test2.jpg")
image2 = cv2.imread("test4.jpg")

startTime = time.time()

typeChangedImage1 = np.array(image1, dtype=np.int16)
typeChangedImage2 = np.array(image2, dtype=np.int16)

imageDifferenct = np.abs(typeChangedImage1 - typeChangedImage2)

### imageDIfferenct를 볼 수도 있다.
# cv2.imshow(
#    'image',np.array(np.reshape(imageDifferenct, image1.shape), dtype=np.uint8)
#)
# cv2.waitKey(0)
# cv2.destroyAllWindows()

distance = np.sum(imageDifferenct)

duration = time.time() - startTime
print("time: ", duration) #time : 0.014093875885009766
print("distance : ", distance) #distance : 240185135

차이를 이미지로 출력한건데 비슷할수록 어두운 사진이 나오는거 같다.

profile
열심히 이것저것 해보는중!

0개의 댓글