Я реализовал нейронную сеть, которая распознает рукописные цифры на основе набора данных MNIST .Я использую чистый python / numpy, и теперь я хочу проверить свои собственные рукописные изображения в сети.Однако я хотел бы автоматизировать процесс обрезки и масштабирования, чтобы я мог предоставить изображение, снятое смартфоном, и получить массив numy в формате mnist.
До сих пор у меня было некоторое успех, но я действительно не знаю, как двигаться дальше.Это два примера изображения и ниже соответствующих маскированных изображений, которые представляют собой обрезку в два раза меньше исходного изображения, чтобы сузить область поиска вниз:
Как видите, что-то происходит, но это не является удовлетворительным.Я также не знал бы, как поступить, если бы я сегментировал и отлично маскировал «4» и «7». Как вы получаете точное положение, чтобы я мог обрезать и уменьшить его до 28x28 пикселей?
Код, создавший эти изображения, выглядит следующим образом.Он в основном вычисляет пространственную гистограмму осей пространства пикселей x и y, а затем затемняет все, что не содержит достаточно черного для написания чего-либо.plot () и hist () - это просто вспомогательные функции, но они создают изображение, которое вы видите, поэтому я включил их.
import matplotlib.pyplot as plt
from matplotlib.ticker import NullFormatter
import numpy as np
from PIL import Image
def hists(x, y):
histx,_ = np.histogram(np.arange(len(x)), bins=len(x), weights=x)
histy,_ = np.histogram(np.arange(len(y)), bins=len(y), weights=y)
return histx, histy
def plot(ndimg):
w, h = ndimg.shape
x = np.mean(ndimg, axis=0)
x -= np.mean(x)
y = np.mean(ndimg, axis=1)
y -= np.mean(y)
nullfmt = NullFormatter()
left, width = 0.1, 0.65*h/w if w > h else 0.65
bottom, height = 0.1, 0.65*w/h if h > w else 0.65
left_h = left + width + 0.02
bottom_h = bottom + height + 0.02
rect_img = [left, bottom, width, height]
rect_histx = [left, bottom_h, width, 0.2]
rect_histy = [left_h, bottom, 0.2, height]
plt.figure(1, figsize=(8, 8))
axImg = plt.axes(rect_img)
axHistx = plt.axes(rect_histx)
axHisty = plt.axes(rect_histy)
axHistx.xaxis.set_major_formatter(nullfmt)
axHisty.yaxis.set_major_formatter(nullfmt)
axImg.imshow(ndimg, cmap=plt.get_cmap('gray'))
axHistx.hist(np.arange(len(x)), bins=int(0.03*len(x)), weights=x)
axHisty.hist(np.arange(len(y)), bins=int(0.03*len(y)), weights=y,
orientation='horizontal')
axHistx.set_xlim(axImg.get_xlim())
axHisty.set_ylim(axImg.get_ylim())
plt.show()
def mask(ndimg, bw_threshhold=0.6, mask_threshhold=5e-3):
ndimg = ndimg / np.max(ndimg)
ndimg = np.where(ndimg < bw_threshhold, 0.0, 1.0)
#ndimg = np.exp(-np.logaddexp(0, -10*(ndimg-0.6)))
x = np.mean(ndimg, axis=0)
#x = x - np.mean(x)
y = np.mean(ndimg, axis=1)
#y = y - np.mean(y)
histx, histy = hists(x, y)
histx = histx - np.mean(histx)
histy = histy - np.mean(histy)
#histx -= (histx.max() + histx.min())/2
#histy -= (histy.max() + histy.min())/2
maskx = np.where(histx < mask_threshhold, False, True)
masky = np.where(histy < mask_threshhold, False, True)
ndimg[masky, :] = 0.
ndimg[:, maskx] = 0.
return ndimg
img = Image.open('C:/Users/maxid/Desktop/Pics/7_1.jpg')
.convert(mode='L')
w, h = img.size
img = img.crop((0.25*w, 0.25*h, 0.75*w, 0.75*h))
ndimg = np.asarray(img)
plot(ndimg)
ndimg = mask(ndimg, )
plot(ndimg)
a, b = hists(np.mean(ndimg, axis=0), np.mean(ndimg, axis=1))
print((a.max()+a.min())/2, np.mean(a), np.median(a))
plt.plot(a)
Итак, я хотел бы получить квадратное изображение рукописной цифрыотображается примерно в середине изображения.Для этого, вероятно, было бы достаточно получить середину цифры, но я не могу придумать простой и полу-надежный (не обязательно производственный класс) способ сделать это.