使用TensorFlow的卷积神经网络识别手写数字(1)-预处理篇

 

功能:

  将文件夹下的20*20像素黑白图片,根据重心位置绘制到28*28图片上,然后保存。经过预处理的图片有利于数字的准确识别。参见MNIST对图片的要求。

   

  此处可下载已处理好的图片:

  https://files.cnblogs.com/files/hatemath/20-pixel-numbers.zip

  https://files.cnblogs.com/files/hatemath/28-pixel-numbers.zip

  1 # encoding: utf-8
  2 import os
  3 
  4 
  5 from PIL import Image
  6 import numpy as np
  7 import cv2
  8 import matplotlib.pyplot as plt
  9 import matplotlib.cm as cm
 10 
 11 srcDir = '20-pixel-numbers'
 12 dstDir = '28-pixel-numbers'
 13 
 14 #显示图片
 15 def showImg(image):
 16     plt.imshow(image,cmap=cm.binary)
 17     plt.show()
 18 
 19 #按比例调整图片大小
 20 def resizeImage(image,width=None,height=None,inter=cv2.INTER_AREA):
 21     
 22     #获取图像尺寸
 23     (h,w) = image.shape[:2]
 24     if width is None and height is None:
 25         return image
 26     
 27     #高度算缩放比例
 28 
 29     if(w > h):
 30         newsize = (width,round(h / (w/width)))
 31     else:
 32         newsize = (round(w/ (h/height)), height)
 33 
 34         #print(newsize)
 35     
 36 
 37         
 38     # 缩放图像
 39     newimage = cv2.resize(image, newsize, interpolation=inter)
 40     return newimage
 41 
 42 #创建新的黑色图片 
 43 def createBianryImage(bg=(0,0,0), width=28, height=28):
 44 
 45     channels = 1
 46 
 47     image = np.zeros((width,height,channels),np.uint8)#生成一个空灰度图像
 48     #cv2.rectangle(image,(0,0),(width,height),bg,1, -1)
 49     
 50     return image.reshape(width, height)
 51 
 52 #两个不同大小的图片合并
 53 def mergeImage(bg, fg, x, y):
 54     bgH, bgW = bg.shape[:2]
 55     fgH, fgW = fg.shape[:2]
 56     
 57     for i in range(fgH):
 58         for j in range(fgW):
 59             if(y+i < bgH and x+j < bgW):
 60                 #print('xx', y+i, x+j)
 61                 bg[y+i, x+j] = fg[i,j] # 这里可以处理每个像素点
 62         
 63     return bg
 64 
 65 # 求像素重心。传入二值图像,其中白色点算重量,黑色点为空
 66 def getBarycentre(image):
 67 
 68     h, w = image.shape[:2]
 69     
 70     sumWeightW = 0
 71     sumWeightH = 0
 72 
 73     count = 0
 74     
 75     for i in range(h):
 76         for j in range(w):
 77             if(image[i,j] > 128):
 78                 sumWeightW += j
 79                 sumWeightH += i
 80                 count += 1
 81 
 82     if(count == 0):
 83         count = 1
 84         
 85     print('getBarycentre: ', round(sumWeightW/count), round(sumWeightH/count) )               
 86     return (round(sumWeightW/count), round(sumWeightH/count))
 87 
 88 
 89 
 90 def getFileList(strDir, strType='.png'):
 91     lstSrcFiles = []
 92 
 93     files = os.listdir(strDir)                   
 94     for file in files:
 95         if os.path.splitext(file)[1] == strType:
 96             lstSrcFiles.append(file)
 97 
 98     return lstSrcFiles
 99             
100     
101 # 读取指定目录下的图片文件,图片为黑白格式,长、宽的最大值为20像素。
102 lstSrcFiles = getFileList(srcDir)
103 print (lstSrcFiles)
104 
105 
106 for file in lstSrcFiles:
107     binary = cv2.imread(srcDir + '/' + file, cv2.IMREAD_GRAYSCALE)
108     
109     # 求像素重心
110     bcW, bcH = getBarycentre(binary)
111 
112     # 叠加到28x28的黑色图片上
113     xOffset = round(28/2 - bcW)
114     yOffset = round(28/2 - bcH)    
115 
116     print('offset', xOffset, yOffset)
117     
118     # 另存为
119     cv2.imwrite(dstDir + '/' + file,
120                     mergeImage(createBianryImage(), binary, xOffset, yOffset))
121                     #binary)
本文由hATEmATH原创 转载请注明出处:http://www.cnblogs.com/hatemath/
原文地址:https://www.cnblogs.com/hatemath/p/8513826.html