使用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)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM