wangzhibo
2022-03-24 b11e5057bae461476c4392482e23dee9f38c0599
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import numpy
import pickle
import cv2
 
#图片预处理
def pretreatment(image):
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    thresh = cv2.threshold(gray, 0, 255,cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
    return thresh
 
#提取图片特征
def feature(A):
    midx=int(A.shape[1]/2)+1
    midy=int(A.shape[0]/2)+1
    A1=cv2.mean(A[0:midy,0:midx])
    A2=cv2.mean(A[midy:A.shape[0],0:midx])
    A3=cv2.mean(A[0:midy,midx:A.shape[1]])
    A4=cv2.mean(A[midy:A.shape[0],midx:A.shape[1]])
    A5=cv2.mean(A)
    AF=[A1,A2,A3,A4,A5]
    return AF
 
 
#训练已知图片的特征         
def training():
    train_set={}
    for i in range(11):
        value=[]
        for j in range(10):
            print('./'+str(i)+'/'+str(i)+'-'+str(j)+'.jpg')
            ima=cv2.imread('./'+str(i)+'/'+str(i)+'-'+str(j)+'.jpg',0)
            if ima is None:
                print('image is none !')
            print(ima.shape)
            AF = feature(ima)
            value.append(AF)
            #print(value)
        train_set[i]=value
    #把训练结果存为永久文件,以备下次使用
    output=open('./train_set.pkl','wb')
    pickle.dump(train_set,output)
    output.close()
    return train_set
    
#计算两向量的距离
def distance(v1,v2):
    vector1=numpy.array(v1)
    vector2=numpy.array(v2) 
    Vector=(vector1-vector2)**2
    distance = Vector.sum()**0.5
    return distance
 
#用最近邻算法识别单个数字
def knn(train_set,V,k):
    key_sort=[11]*k
    value_sort=[11]*k
    for key in range(11):
        for value in train_set[key]:
            d=distance(V,value)
            for i in range(k):#从小到大排序
                if d<value_sort[i]:
                    for j in range(k-2,i-1,-1):
                        key_sort[j+1]=key_sort[j]
                        value_sort[j+1]=value_sort[j]
                    key_sort[i]=key
                    value_sort[i]=d
                    break
    max_key_count=-1
    key_set=set(key_sort)
    for key in key_set:   #统计每个类别出现的次数
        if max_key_count<key_sort.count(key):
            max_key_count=key_sort.count(key)
            max_key=key
    return max_key
 
#合并一副图片的所有数字
def identification(train_set,AF,k):
    result=''
    for i in AF:
        key=knn(train_set,i,k)
        if key==10:
            key='.'
        result=result+str(key)
    return float(result)
 
#识别文件夹中的所有图片上的数据并输出到EXCELL中
def main(k,trained=None):
    # k:knn算法的的k,即取训练集中最相邻前k个样本进行判别
    #trained:trained=0则程序会开始训练出训练集,否则会用已保存的训练集
    if trained==0:
        train_set=training()
    else:
        pkl_file=open('train_set.pkl','rb')
        train_set=pickle.load(pkl_file)
        pkl_file.close()
    #识别所有图片的数字并输出到EXCELL中
    for i in range(1,21):
        ima=cv2.imread('./test/'+str(i)+'.jpg')
        #im=pretreatment(ima)
        AF=feature(ima)
        result=identification(train_set,AF,k)
 
main(4,0)  #表示:4近邻,还没有训练集备份,还没有昨日数据备份