새로새록
python - opencv: Filtering. KNN 본문
Filtering
- 특정한 이미지에서 커널(Kernel)을 적용해 컨볼루션 계산하여 필터링을 수행할 수 있습니다.
직접 필터 적용하기
import cv2
import matplotlib.pyplot as plt
import numpy as np
image = cv2.imread('Downloads/gray_image.png')
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.show()
size =4
kernel= np.ones((size, size), np.float32)/ (size**2)
print(kernel)
dst =cv2.filter2D(image, -1, kernel)
plt.imshow(cv2.cvtColor(dst, cv2.COLOR_BGR2RGB))
plt.show()
직접 커널을 생성하여 필터 적용하기
import cv2
import matplotlib.pyplot as plt
import numpy as np
image = cv2.imread('gray_image.jpg')
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.show()
size = 4
kernel = np.ones((size, size), np.float32) / (size ** 2)
print(kernel) dst = cv2.filter2D(image, -1, kernel)
plt.imshow(cv2.cvtColor(dst, cv2.COLOR_BGR2RGB))
plt.show()
[[0.0625 0.0625 0.0625 0.0625] [0.0625 0.0625 0.0625 0.0625] [0.0625 0.0625 0.0625 0.0625] [0.0625 0.0625 0.0625 0.0625]]
Basic Blurring
import cv2
import matplotlib.pyplot as plt
image = cv2.imread('gray_image.jpg')
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.show()
dst = cv2.blur(image, (4, 4))
plt.imshow(cv2.cvtColor(dst, cv2.COLOR_BGR2RGB))
plt.show()
Gaussian Blur
import cv2
image = cv2.imread('gray_image.jpg')
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.show()
# kernel_size: 홀수
dst = cv2.GaussianBlur(image, (5, 5), 0)
plt.imshow(cv2.cvtColor(dst, cv2.COLOR_BGR2RGB))
plt.show()
KNN
import cv2
import numpy as np
from matplotlib import pyplot as plt
# 각 데이터의 위치: 25 X 2 크기에 각각 0 ~ 100
trainData = np.random.randint(0, 100, (25, 2)).astype(np.float32)
# 각 데이터는 0 or 1
response = np.random.randint(0, 2, (25, 1)).astype(np.float32)
# 값이 0인 데이터를 각각 (x, y) 위치에 빨간색으로 칠합니다.
red = trainData[response.ravel() == 0]
plt.scatter(red[:, 0], red[:, 1], 80, 'r', '^')
# 값이 1인 데이터를 각각 (x, y) 위치에 파란색으로 칠합니다.
blue = trainData[response.ravel() == 1]
plt.scatter(blue[:, 0], blue[:, 1], 80, 'b', 's')
# (0 ~ 100, 0 ~ 100) 위치의 데이터를 하나 생성해 칠합니다.
newcomer = np.random.randint(0, 100, (1, 2)).astype(np.float32)
plt.scatter(newcomer[:, 0], newcomer[:, 1], 80, 'g', 'o')
knn = cv2.ml.KNearest_create()
knn.train(trainData, cv2.ml.ROW_SAMPLE, response)
ret, results, neighbours, dist = knn.findNearest(newcomer, 3)
# 가까운 3개를 찾고, 거리를 고려하여 자신을 정합니다.
print("result : ", results)
print("neighbours :", neighbours)
print("distance: ", dist)
plt.show()
KNN숫자인식
숫자 이미지 분류하여 저장하기
import cv2
import numpy as np
img = cv2.imread('digits.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 세로로 50줄, 가로로 100줄로 사진을 나눕니다.
cells = [np.hsplit(row, 100) for row in np.vsplit(gray, 50)]
x = np.array(cells)
# 각 (20 X 20) 크기의 사진을 한 줄(1 X 400)으로 바꿉니다.
train = x[:, :].reshape(-1, 400).astype(np.float32)
# 0이 500개, 1이 500개, ... 로 총 5,000개가 들어가는 (1 x 5000) 배열을 만듭니다.
k = np.arange(10)
train_labels = np.repeat(k, 500)[:, np.newaxis]
np.savez("trained.npz", train=train, train_labels=train_labels)
import matplotlib.pyplot as plt
# 다음과 같이 하나씩 글자를 출력할 수 있습니다.
plt.imshow(cv2.cvtColor(x[0, 0], cv2.COLOR_GRAY2RGB))
plt.show()
# 다음과 같이 하나씩 글자를 저장할 수 있습니다.
cv2.imwrite('test_0.png', x[0, 0]) cv2.imwrite('test_1.png', x[5, 0])
cv2.imwrite('test_2.png', x[10, 0]) cv2.imwrite('test_3.png', x[15, 0])
cv2.imwrite('test_4.png', x[20, 0]) cv2.imwrite('test_5.png', x[25, 0])
cv2.imwrite('test_6.png', x[30, 0]) cv2.imwrite('test_7.png', x[35, 0])
cv2.imwrite('test_8.png', x[40, 0])
cv2.imwrite('test_9.png', x[45, 0])
Out[43]:
True
KNN 숫자 인식
import cv2
import numpy as np
import glob
FILE_NAME = 'trained.npz'
# 파일로부터 학습 데이터를 불러옵니다.
def load_train_data(file_name):
with np.load(file_name) as data:
train = data['train']
train_labels = data['train_labels']
return train, train_labels
# 손 글씨 이미지를 (20 x 20) 크기로 Scaling합니다.
def resize20(image):
img = cv2.imread(image)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray_resize = cv2.resize(gray, (20, 20))
plt.imshow(cv2.cvtColor(gray_resize, cv2.COLOR_GRAY2RGB))
plt.show()
# 최종적으로는 (1 x 400) 크기로 반환합니다.
return gray_resize.reshape(-1, 400).astype(np.float32)
def check(test, train, train_labels):
knn = cv2.ml.KNearest_create()
knn.train(train, cv2.ml.ROW_SAMPLE, train_labels)
# 가장 가까운 5개의 글자를 찾아, 어떤 숫자에 해당하는지 찾습니다.
ret, result, neighbours, dist = knn.findNearest(test, k=5)
return result
train, train_labels = load_train_data(FILE_NAME)
for file_name in glob.glob('./test_*.png'):
test = resize20(file_name)
result = check(test, train, train_labe
[[5.]]
[[3.]]
[[6.]]
[[8.]]
[[4.]]
[[2.]]
[[7.]]
[[0.]]
[[1.]]
[[9.]]
코드/소스참고: 나동빈
'소프트웨어융합 > 파이썬 기타.py' 카테고리의 다른 글
opencv 연습(1) (0) | 2021.10.10 |
---|---|
모두의 딥러닝 개정2판 (1) | 2021.10.07 |
python - opencv: 사진 윤곽선 기본(2) (0) | 2021.09.27 |
python: opencv: 툴이해 기본(1) (0) | 2021.09.27 |
2004-2020 변화한 것들.pandas (0) | 2021.09.11 |