wangzhibo
2022-03-23 c23ad3443b2e04036ad5dffd4dd337ad4724134b
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
from cv2 import waitKey
import numpy
import pickle
import cv2
import os
import uuid
 
#图片预处理
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 feature(A):
    midx=int(A.shape[1]/2)+1
    midy=int(A.shape[0]/2)+1
    A1=cv2.mean(A[0:int(A.shape[0]/5),0:A.shape[1]])
    A2=cv2.mean(A[0:midy,0:int(A.shape[1]/3)])
    A3=cv2.mean(A[0:midy,int(A.shape[1]*2/3):A.shape[1]])
    A4=cv2.mean(A[int(A.shape[0]*3/5):int(A.shape[0]*4/5),0:A.shape[1]])
    A5=cv2.mean(A[midy:A.shape[0],0:int(A.shape[1]/3)])
    A6=cv2.mean(A[midy:A.shape[0],int(A.shape[1]*2/3):A.shape[1]])
    A7=cv2.mean(A[int(A.shape[0]*4/5):A.shape[0],0:A.shape[1]])
    if A1[0] >128 :
        A1=1
    else:
        A1=0
    if A2[0] >128 :
        A2=1
    else:
        A2=0
    if A3[0] >128 :
        A3=1
    else:
        A3=0
    if A4[0] >128 :
        A4=1
    else:
        A4=0
    if A5[0] >128 :
        A5=1
    else:
        A5=0
    if A6[0] >128 :
        A6=1
    else:
        A6=0
    if A7[0] >128 :
        A7=1
    else:
        A7=0
           
    AF=[A1,A2,A3,A4,A5,A6,A7]
    #print(AF)
    i=0
    tube=0
    onenumber=0
    while(i < 7):
        if(AF[i]==1):
            tube = tube + pow(2,i)
        i +=1
    if(tube==63):
        onenumber = 0
    elif(tube==6):
        onenumber = 1
    elif(tube==91):
        onenumber = 2
    elif(tube==79):
        onenumber = 3
    elif(tube==102 or tube==110):
    #110是因为有干扰情况
        onenumber = 4
    elif(tube==109):
        onenumber = 5
    elif(tube==125):
        onenumber = 6
    elif(tube==7):
        onenumber = 7
    elif(tube==127):
        onenumber = 8
    elif(tube==103):
        onenumber = 9
    else:
        onenumber = -1 
               
    return AF,onenumber
 
      
 
#训练已知图片的特征         
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('./data/'+str(i)+'.jpg',0)
            AF,nmber = 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):
    key=knn(train_set,AF,k)
    return key
 
#识别文件夹中的所有图片上的数据并输出到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中
    path = "./images4"
    i=0
    filename = os.listdir(path)    # 获取文件夹文件
    for file in filename:
        img = cv2.imread(path + "/" + file,0)    # 读取图片
        AF,nmber=feature(img)
        print(AF,nmber)
        result=identification(train_set,AF,k)
        cv2.imwrite('./images4_infer/'+str(result)+'_'+str(uuid.uuid4())+".jpg",img)
        i = i+ 1
        if i >200 :
            break
 
main(1,0)  #表示:4近邻,还没有训练集备份,还没有昨日数据备份