山内セミナー(2019/07/03)

関連サイトと資料

サンプル画像


digits.png

サンプルプログラム(1)

knn_introduction.py
import cv2
import numpy as np
import matplotlib.pyplot as plt
	
data = np.random.randint(0, 100, (16, 2)).astype(np.float32)
labels = np.random.randint(0, 2, (16, 1)).astype(np.float32)
sample = np.random.randint(0, 100, (1, 2)).astype(np.float32)
	
knn = cv2.ml.KNearest_create()
knn.train(data, cv2.ml.ROW_SAMPLE, labels)
	
k = 3
ret, results, neighbours, dist = knn.findNearest(sample, k)
	
fig = plt.figure(figsize=(8, 6))
fig.patch.set_facecolor('silver')
red_triangles = data[labels.ravel() == 0]
plt.scatter(red_triangles[:, 0], red_triangles[:, 1], 200, 'r', '^')
	
blue_squares = data[labels.ravel() == 1]
plt.scatter(blue_squares[:, 0], blue_squares[:, 1], 200, 'b', 's')
plt.scatter(sample[:, 0], sample[:, 1], 200, 'g', 'o')
	
print("result: {}".format(results))
print("neighbours: {}".format(neighbours))
print("distance: {}".format(dist))
	
if results[0][0] > 0:
    plt.suptitle("k-NN algorithm: sample green point is classified as blue (k = " + str(k) + ")", fontsize=14,
                 fontweight='bold')
else:
    plt.suptitle("k-NN algorithm: sample green point is classified as red (k = " + str(k) + ")", fontsize=14,
                 fontweight='bold')
	
plt.show()

サンプルプログラム(2)

knn_handwritten_digits_recognition_introduction.py
import cv2
import numpy as np
	
SIZE_IMAGE = 20
NUMBER_CLASSES = 10
	
def load_digits_and_labels(big_image):
    digits_img = cv2.imread(big_image, 0)
    number_rows = digits_img.shape[1] / SIZE_IMAGE
    rows = np.vsplit(digits_img, digits_img.shape[0] / SIZE_IMAGE)
	
    digits = []
    for row in rows:
        row_cells = np.hsplit(row, number_rows)
        for digit in row_cells:
            digits.append(digit)
    digits = np.array(digits)
	
    labels = np.repeat(np.arange(NUMBER_CLASSES), len(digits) / NUMBER_CLASSES)
    return digits, labels
	
def get_accuracy(predictions, labels):
    accuracy = (np.squeeze(predictions) == labels).mean()
    return accuracy * 100
	
def raw_pixels(img):
    return img.flatten()
	
digits, labels = load_digits_and_labels('digits.png')
rand = np.random.RandomState(1234)
shuffle = rand.permutation(len(digits))
digits, labels = digits[shuffle], labels[shuffle]
	
raw_descriptors = []
for img in digits:
    raw_descriptors.append(np.float32(raw_pixels(img)))
raw_descriptors = np.squeeze(raw_descriptors)
	
partition = int(0.5 * len(raw_descriptors))
raw_descriptors_train, raw_descriptors_test = np.split(raw_descriptors, [partition])
labels_train, labels_test = np.split(labels, [partition])
	
print('Training KNN model - raw pixels as features')
knn = cv2.ml.KNearest_create()
knn.train(raw_descriptors_train, cv2.ml.ROW_SAMPLE, labels_train)
	
k = 5
ret, result, neighbours, dist = knn.findNearest(raw_descriptors_test, k)
	
acc = get_accuracy(result, labels_test)
print("Accuracy: {}".format(acc))

サンプルプログラム(3)

knn_handwritten_digits_recognition_k.py
import cv2
import numpy as np
import matplotlib.pyplot as plt
from collections import defaultdict
	
SIZE_IMAGE = 20
NUMBER_CLASSES = 10
	
def load_digits_and_labels(big_image):
    digits_img = cv2.imread(big_image, 0)
    number_rows = digits_img.shape[1] / SIZE_IMAGE
    rows = np.vsplit(digits_img, digits_img.shape[0] / SIZE_IMAGE)
	
    digits = []
    for row in rows:
        row_cells = np.hsplit(row, number_rows)
        for digit in row_cells:
            digits.append(digit)
    digits = np.array(digits)
	
    labels = np.repeat(np.arange(NUMBER_CLASSES), len(digits) / NUMBER_CLASSES)
    return digits, labels
	
def get_accuracy(predictions, labels):
    accuracy = (np.squeeze(predictions) == labels).mean()
    return accuracy * 100
	
def raw_pixels(img):
    return img.flatten()
	
digits, labels = load_digits_and_labels('digits.png')
rand = np.random.RandomState(1234)
shuffle = rand.permutation(len(digits))
digits, labels = digits[shuffle], labels[shuffle]
	
raw_descriptors = []
for img in digits:
    raw_descriptors.append(np.float32(raw_pixels(img)))
raw_descriptors = np.squeeze(raw_descriptors)
	
partition = int(0.5 * len(raw_descriptors))
raw_descriptors_train, raw_descriptors_test = np.split(raw_descriptors, [partition])
labels_train, labels_test = np.split(labels, [partition])
	
print('Training KNN model - raw pixels as features')
knn = cv2.ml.KNearest_create()
knn.train(raw_descriptors_train, cv2.ml.ROW_SAMPLE, labels_train)
	
results = defaultdict(list)
for k in np.arange(1, 10):
    ret, result, neighbours, dist = knn.findNearest(raw_descriptors_test, k)
    acc = get_accuracy(result, labels_test)
    print(" {}".format("%.2f" % acc))
    results['50'].append(acc)
	
fig = plt.figure(figsize=(12, 5))
plt.suptitle("k-NN handwritten digits recognition", fontsize=14, fontweight='bold')
fig.patch.set_facecolor('silver')
	
ax = plt.subplot(1, 1, 1)
ax.set_xlim(0, 10)
dim = np.arange(1, 10)
	
for key in results:
    ax.plot(dim, results[key], linestyle='--', marker='o', label="50%")
	
plt.legend(loc='upper left', title="% training")
plt.title('Accuracy of the K-NN model varying k')
plt.xlabel("number of k")
plt.ylabel("accuracy")
plt.show()

サンプルプログラム(4)

knn_handwritten_digits_recognition_k_training_testing.py
import cv2
import numpy as np
import matplotlib.pyplot as plt
from collections import defaultdict
	
SIZE_IMAGE = 20
NUMBER_CLASSES = 10
	
def load_digits_and_labels(big_image):
    digits_img = cv2.imread(big_image, 0)
    number_rows = digits_img.shape[1] / SIZE_IMAGE
    rows = np.vsplit(digits_img, digits_img.shape[0] / SIZE_IMAGE)
	
    digits = []
    for row in rows:
        row_cells = np.hsplit(row, number_rows)
        for digit in row_cells:
            digits.append(digit)
    digits = np.array(digits)
	
    labels = np.repeat(np.arange(NUMBER_CLASSES), len(digits) / NUMBER_CLASSES)
    return digits, labels
	
def get_accuracy(predictions, labels):
    accuracy = (np.squeeze(predictions) == labels).mean()
    return accuracy * 100
	
def raw_pixels(img):
    return img.flatten()
	
digits, labels = load_digits_and_labels('digits.png')
rand = np.random.RandomState(1234)
shuffle = rand.permutation(len(digits))
digits, labels = digits[shuffle], labels[shuffle]
	
raw_descriptors = []
for img in digits:
    raw_descriptors.append(np.float32(raw_pixels(img)))
raw_descriptors = np.squeeze(raw_descriptors)
	
split_values = np.arange(0.1, 1, 0.1)
	
results = defaultdict(list)
knn = cv2.ml.KNearest_create()
for split_value in split_values:
    partition = int(split_value * len(raw_descriptors))
    raw_descriptors_train, raw_descriptors_test = np.split(raw_descriptors, [partition])
    labels_train, labels_test = np.split(labels, [partition])
	
    print('Training KNN model - raw pixels as features')
    knn.train(raw_descriptors_train, cv2.ml.ROW_SAMPLE, labels_train)
	
    for k in np.arange(1, 10):
        ret, result, neighbours, dist = knn.findNearest(raw_descriptors_test, k)
        acc = get_accuracy(result, labels_test)
        print(" {}".format("%.2f" % acc))
        results[int(split_value * 100)].append(acc)
	
fig = plt.figure(figsize=(12, 5))
plt.suptitle("k-NN handwritten digits recognition", fontsize=14, fontweight='bold')
fig.patch.set_facecolor('silver')
	
ax = plt.subplot(1, 1, 1)
ax.set_xlim(0, 10)
dim = np.arange(1, 10)
	
for key in results:
    ax.plot(dim, results[key], linestyle='--', marker='o', label=str(key) + "%")
	
plt.legend(loc='upper left', title="% training")
plt.title('Accuracy of the KNN model varying both k and the percentage of images to train/test')
plt.xlabel("number of k")
plt.ylabel("accuracy")
plt.show()

サンプルプログラム(5)

knn_handwritten_digits_recognition_k_training_testing_preprocessing.py
import cv2
import numpy as np
import matplotlib.pyplot as plt
from collections import defaultdict
	
SIZE_IMAGE = 20
NUMBER_CLASSES = 10
	
def load_digits_and_labels(big_image):
    digits_img = cv2.imread(big_image, 0)
    number_rows = digits_img.shape[1] / SIZE_IMAGE
    rows = np.vsplit(digits_img, digits_img.shape[0] / SIZE_IMAGE)
	
    digits = []
    for row in rows:
        row_cells = np.hsplit(row, number_rows)
        for digit in row_cells:
            digits.append(digit)
    digits = np.array(digits)
	
    labels = np.repeat(np.arange(NUMBER_CLASSES), len(digits) / NUMBER_CLASSES)
    return digits, labels
	
def deskew(img):
    m = cv2.moments(img)
    if abs(m['mu02']) < 1e-2:
        return img.copy()
    skew = m['mu11'] / m['mu02']
    M = np.float32([[1, skew, -0.5 * SIZE_IMAGE * skew], [0, 1, 0]])
    img = cv2.warpAffine(img, M, (SIZE_IMAGE, SIZE_IMAGE), flags=cv2.WARP_INVERSE_MAP | cv2.INTER_LINEAR)
    return img
	
def get_accuracy(predictions, labels):
    accuracy = (np.squeeze(predictions) == labels).mean()
    return accuracy * 100
	
def raw_pixels(img):
    return img.flatten()
	
digits, labels = load_digits_and_labels('digits.png')
rand = np.random.RandomState(1234)
shuffle = rand.permutation(len(digits))
digits, labels = digits[shuffle], labels[shuffle]
	
raw_descriptors = []
for img in digits:
    raw_descriptors.append(np.float32(raw_pixels(deskew(img))))
raw_descriptors = np.squeeze(raw_descriptors)
	
split_values = np.arange(0.1, 1, 0.1)
	
results = defaultdict(list)
knn = cv2.ml.KNearest_create()
for split_value in split_values:
    partition = int(split_value * len(raw_descriptors))
    raw_descriptors_train, raw_descriptors_test = np.split(raw_descriptors, [partition])
    labels_train, labels_test = np.split(labels, [partition])
	
    print('Training KNN model - raw pixels as features')
    knn.train(raw_descriptors_train, cv2.ml.ROW_SAMPLE, labels_train)
	
    for k in np.arange(1, 10):
        ret, result, neighbours, dist = knn.findNearest(raw_descriptors_test, k)
        acc = get_accuracy(result, labels_test)
        print(" {}".format("%.2f" % acc))
        results[int(split_value * 100)].append(acc)
	
fig = plt.figure(figsize=(12, 5))
plt.suptitle("k-NN handwritten digits recognition", fontsize=14, fontweight='bold')
fig.patch.set_facecolor('silver')
	
ax = plt.subplot(1, 1, 1)
ax.set_xlim(0, 10)
dim = np.arange(1, 10)
	
for key in results:
    ax.plot(dim, results[key], linestyle='--', marker='o', label=str(key) + "%")
	
plt.legend(loc='upper left', title="% training")
plt.title('Accuracy of the k-NN model varying both k and the percentage of images to train/test with pre-processing')
plt.xlabel("number of k")
plt.ylabel("accuracy")
plt.show()

サンプルプログラム(6)

knn_handwritten_digits_recognition_k_training_testing_preprocessing_hog.py
import cv2
import numpy as np
import matplotlib.pyplot as plt
from collections import defaultdict
	
SIZE_IMAGE = 20
NUMBER_CLASSES = 10
	
def load_digits_and_labels(big_image):
    digits_img = cv2.imread(big_image, 0)
    number_rows = digits_img.shape[1] / SIZE_IMAGE
    rows = np.vsplit(digits_img, digits_img.shape[0] / SIZE_IMAGE)
	
    digits = []
    for row in rows:
        row_cells = np.hsplit(row, number_rows)
        for digit in row_cells:
            digits.append(digit)
    digits = np.array(digits)
	
    labels = np.repeat(np.arange(NUMBER_CLASSES), len(digits) / NUMBER_CLASSES)
    return digits, labels
	
def deskew(img):
    m = cv2.moments(img)
    if abs(m['mu02']) < 1e-2:
        return img.copy()
    skew = m['mu11'] / m['mu02']
    M = np.float32([[1, skew, -0.5 * SIZE_IMAGE * skew], [0, 1, 0]])
    img = cv2.warpAffine(img, M, (SIZE_IMAGE, SIZE_IMAGE), flags=cv2.WARP_INVERSE_MAP | cv2.INTER_LINEAR)
    return img
	
def get_accuracy(predictions, labels):
    accuracy = (np.squeeze(predictions) == labels).mean()
    return accuracy * 100
	
def get_hog():
    hog = cv2.HOGDescriptor((SIZE_IMAGE, SIZE_IMAGE), (8, 8), (4, 4), (8, 8), 9, 1, -1, 0, 0.2, 1, 64, True)
    print("hog descriptor size: '{}'".format(hog.getDescriptorSize()))
    return hog
	
def raw_pixels(img):
    return img.flatten()
	
digits, labels = load_digits_and_labels('digits.png')
rand = np.random.RandomState(1234)
shuffle = rand.permutation(len(digits))
digits, labels = digits[shuffle], labels[shuffle]
	
hog = get_hog()
hog_descriptors = []
for img in digits:
    hog_descriptors.append(hog.compute(deskew(img)))
hog_descriptors = np.squeeze(hog_descriptors)
	
split_values = np.arange(0.1, 1, 0.1)
	
results = defaultdict(list)
knn = cv2.ml.KNearest_create()
for split_value in split_values:
    partition = int(split_value * len(hog_descriptors))
    hog_descriptors_train, hog_descriptors_test = np.split(hog_descriptors, [partition])
    labels_train, labels_test = np.split(labels, [partition])
	
    print('Training KNN model - HOG features')
    knn.train(hog_descriptors_train, cv2.ml.ROW_SAMPLE, labels_train)
	
    for k in np.arange(1, 10):
        ret, result, neighbours, dist = knn.findNearest(hog_descriptors_test, k)
        acc = get_accuracy(result, labels_test)
        print(" {}".format("%.2f" % acc))
        results[int(split_value * 100)].append(acc)
	
fig = plt.figure(figsize=(12, 5))
plt.suptitle("k-NN handwritten digits recognition", fontsize=14, fontweight='bold')
fig.patch.set_facecolor('silver')
	
ax = plt.subplot(1, 1, 1)
ax.set_xlim(0, 10)
dim = np.arange(1, 10)
	
for key in results:
    ax.plot(dim, results[key], linestyle='--', marker='o', label=str(key) + "%")
	
plt.legend(loc='upper left', title="% training")
plt.title('Accuracy of the k-NN model varying both k and the percentage of images to train/test with pre-processing '
          'and HoG features')
plt.xlabel("number of k")
plt.ylabel("accuracy")
plt.show()