不说废话,也不解释原理了,请自行搜索。上代码!
# -*- coding: utf-8 -*-
import cv2
import numpy
import os
import time
for num in range(10):
codebook_for_pixal=[] #定义像素编码本
for i in range(28):
for j in range(28):
codebook_for_pixal.append([]) #定义编码本结构,使编码本一维化
path=r'/home/waking/Desktop/python/mnist/train/'+str(num)+'/'
file_list=os.listdir(path) #os.listdir()函数得到的是仅当前路径下的文件名,不包括子目录中的文件,所有需要使用递归的方法得到全部文件名。
file_nums=len(file_list) #用于展示百分比的的基数
show_num=0 #用于展示百分比的的分子
for filename in file_list:
show_num+=1
run_count=show_num/file_nums*100
print(str(num)+'赋值列表运行完成:'+str(round(run_count,2))+'%') #输出进度显示,round是四舍五入函数
if run_count==100:
print('~~~~~~~~~~~~~~~~~~~~~~~~~~~赋值列表已完成~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
image = cv2.imread(path+filename)
#####灰度值版##############
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
######二值化版############################
# ret,thresh = cv2.threshold(gray,127,255,0) #二值化函数
count_num=0
for i in range(28):
for j in range(28):
pixal_value=gray[i][j] #获取像素值
codebook_for_pixal[count_num].append(pixal_value) #编码本赋值
count_num+=1 #列表索引累加器,例遍编码本列表作用
with open(r'/home/waking/Desktop/python/mnist/'+str(num)+'_codebook_for_pixal.txt','w') as f:
f.write(str(codebook_for_pixal))
print('~~~~~~~~~~~~~~~~~~~~~~~~~~~列表文件写入文件已完成~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
with open(r'/home/waking/Desktop/python/mnist/'+str(num)+'_codebook_for_pixal.txt','r') as f:
list_readed=f.read()
print(str(num)+'读取文件结束:'+str(time.time()))
codebook_for_pixal=eval(list_readed)
print(str(num)+'翻译文件完毕:'+str(time.time()))
codebook_for_pixal_dict=[] #定义像素字典编码本
for i in range(28):
for j in range(28):
codebook_for_pixal_dict.append({}) #定义字典编码本结构
count_dict_num=0 #用于列表中字典的索引计数
show_dic_num=0
list_nums=len(codebook_for_pixal)
print(str(num)+'开始赋值')
for list_in_book in codebook_for_pixal:
show_dic_num+=1
run_count2=show_dic_num/list_nums*100
print(str(num)+'赋值字典运行完成:'+str(round(run_count2,2))+'%') #输出进度显示,round是四舍五入函数
# print(show_dic_num)
if run_count2==100:
print('~~~~~~~~~~~~~~~~~~~~~~~~~~~赋值字典已完成~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
for pix_value_for_count in range(256):
# print(time.time())
count_result=list_in_book.count(pix_value_for_count)
codebook_for_pixal_dict[count_dict_num][pix_value_for_count]=(count_result+1)/(file_nums+1) #给像素统计字典赋值,直接求出每个像素值的概率(频率),但分子分母都要加上1(好像叫拉普拉斯常数)为了防止,有零的出现,要是为零,那么以后的相乘就没有意义了
count_dict_num+=1
with open(r'/home/waking/Desktop/python/mnist/'+str(num)+'_codebook_for_pixal_dict.txt','w') as f:
f.write(str(codebook_for_pixal_dict))
print('~~~~~~~~~~~~~~~~~~~~~~~~~~~字典写入文件已完成~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
# print(codebook_for_pixal)
# print(gray[0][0])
# image[0][0][0]=8
# image[0][0][1]=8
# image[0][0][2]=8
# print(image[0][0])
# -*- coding: utf-8 -*-
from PIL import Image
import struct
import time
import os
path_num_pic_in=r'/home/waking/Desktop/python/mnist/'
for num_dir in range(10):
if os.path.exists(path_num_pic_in+str(num_dir)):
print('文件夹已经存在')
else:
os.makedirs(path_num_pic_in+str(num_dir)) #生成10个以数字命名的文件夹
def extract_save_mnist(filename_pics,filename_labels):
index = 0
index2 = 0
with open(filename_pics, 'rb') as f:
buf=f.read()
with open(filename_labels, 'rb') as f2:
buf2=f2.read()
magic, labels = struct.unpack_from('>II' , buf , index) #读出有多少个标签,为以后循环定量。
index2 += struct.calcsize('>II') #索引跟随
magic, images, rows, columns = struct.unpack_from('>IIII' , buf , index)
index += struct.calcsize('>IIII')
for i in range(labels):
image = Image.new('L', (columns, rows))
for x in range(rows): ## 把一维的数据赋值到二维中,每次读取一个byte,付给一个像素值 struct函数解码的应该是列表形式所以用[0]提取)
for y in range(columns):
image.putpixel((y, x), int(struct.unpack_from('>B', buf, index)[0]))
index += struct.calcsize('>B') #索引计数用的,主要方便记录读取到哪一个数据值了。
label_num= struct.unpack_from('>B', buf2, index2)[0] ##这个本身就是int类型的了,就没必要加int()了。
index2 += struct.calcsize('>B') #索引跟随
image.save(path_num_pic_in+str(label_num)+'/'+str(label_num)+'_'+str(time.time()) + '.png')
if __name__ == '__main__':
extract_save_mnist(r't10k-images.idx3-ubyte',r't10k-labels.idx1-ubyte')
# -*- coding: utf-8 -*-
import cv2
import numpy
import os
import time
from decimal import Decimal #引用python高精度模块
def list_multiply(one_list): #列表内所有元素相乘函数
res=Decimal('1') #高精度模块赋值
for i in one_list:
i=Decimal(str(i)) #把列表中的数字也变成高精度模块数字,注意输入的是字符串形式,Python里传参基本都是字符串模式,因为没有真正意义的二进制,都是底层转换
res*=i
return res
###############定义几个常量############################################
final_test_dict={} #建立一个测试结果字典,存放最终测试结果
model_list_list=[] #用于存放模型list的list,节省读取文件时间,但是占用大量内存,试试!
##################一次性批量读取文件,并赋予列表值,节省运行时间######################
for num in range(10):
with open(r'/home/waking/Desktop/python/mnist/model/'+str(num)+'_codebook_for_pixal_dict.txt','r') as f:
model_readed=f.read() #读数据
eval_time_1=time.time()
model_list=eval(model_readed) #把字符串数据翻译成列表数据
eval_time_2=time.time()
time_eval_diff=eval_time_2-eval_time_1
print('eval所用时间为:'+str(time_eval_diff))
model_list_list.append(model_list)
#################################################################################
for test_num in range(10): #例遍每一个 test 测试数据的文件夹了(0----9)
path=r'/home/waking/Desktop/python/mnist/test/'+str(test_num)+'/'
file_list=os.listdir(path) #os.listdir()函数得到的是仅当前路径下的文件名,不包括子目录中的文件,所有需要使用递归的方法得到全部文件名。
file_nums=len(file_list) #用于展示百分比的的基数
#####最终测试用的变量定义################
test_fail_num=0 #定义测试数据中没有识别准确的数字个数
total_test_nums=file_nums
########################################
show_num=0 #用于展示百分比的的分子
for filename in file_list:
show_num+=1
# run_count=show_num/file_nums*100
# print('赋值列表运行完成:'+str(round(run_count,2))+'%') #输出进度显示,round是四舍五入函数
# if run_count==100:
# print('~~~~~~~~~~~~~~~~~~~~~~~~~~~赋值列表已完成~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
print('测试图片:~~~'+str(show_num))
image = cv2.imread(path+filename)
#####灰度值版##############
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
index_list=[] #用于存放每个数字模型对应的图片总概率值
for num in range(10):
# with open(r'/home/waking/Desktop/python/mnist/model/'+str(num)+'_codebook_for_pixal_dict.txt','r') as f:
# model_readed=f.read() #读数据
# eval_time_1=time.time()
# model_list=eval(model_readed) #把字符串数据翻译成列表数据
# eval_time_2=time.time()
# time_eval_diff=eval_time_2-eval_time_1
# print('eval所用时间为:'+str(time_eval_diff))
print('正在测试模型'+str(num))
model_list=model_list_list[num]
count_dict_num=0 #用于列表中字典的索引计数
pic_probability_list=[] #用于收集本图片,所有像素值的概率
for i in range(28):
for j in range(28):
pixal_value=gray[i][j] #获取像素值
model_dict=model_list[count_dict_num] #获取像素位置的各个像素值概率的字典
# print(model_dict)
value_probability=model_dict[pixal_value] #获取本图片像素值在模型中的概率
# print(value_probability)
pic_probability_list.append(value_probability)
count_dict_num+=1
# print('求得的概率列表元素个数为:'+str(len(pic_probability_list)))
# print(pic_probability_list)
pic_probability_value=list_multiply(pic_probability_list) #列表所有元素相乘,得到改图片在对应模型中的概率值
# print(len(pic_probability_list))
# print('#######################::::::'+str(pic_probability_value))
index_list.append(pic_probability_value)
final_num=index_list.index(max(index_list)) #找到列表里最大概率值的所在列表中的位置,这里也巧,也就是对应的数字值
if final_num==test_num:
pass
else:
test_fail_num+=1
# print('对应的概率为:'+str(index_list))
print('测试文件夹为:'+str(test_num)+'~~~~~~~~~~~~~~~~~~~~最终经过贝叶斯分类得到的值为:~~~~~~~~~~~~~~~~~~'+str(final_num))
accuracy_rate_test=(total_test_nums-test_fail_num)/total_test_nums*100
print('数字'+str(test_num)+'测试的准确率为:'+str(accuracy_rate_test)+' %')
final_test_dict['数字'+str(test_num)+'测试的准确率']=str(accuracy_rate_test)+' %'
print(final_test_dict)
with open(r'/home/waking/Desktop/python/mnist/final_test_result.txt','w') as f:
f.write(str(final_test_dict))
共三段代码,路径问题自己定义,有问题请留言,大家一起讨论,吃饭去了,拜!