• Python识别二维码(与生成二维码的代码一同使用)


    在二维码识别过程中需要做两部分工作

    1.生成分析模型

    2.验证码图片识别

    建议这两部分分开做,因为在进行模型分析时非常慢,要运行好几个小时,所以可以先设置一个小的区间,看能否成功产生模型,成功后生成所有模型,然后再对其进行分析

    from 深度学习.生成二维码 import gen_captcha_text_and_image
    from 深度学习.生成二维码 import number
    from 深度学习.生成二维码 import alphabet
    from 深度学习.生成二维码 import ALPHABET
    import numpy as np
    from PIL import Image
    import tensorflow as tf
    import time
    import matplotlib.pyplot as plt
    import cv2
    import os
    
    #设置训练参数
    IMAGE_HEIGHT=60
    IMAGE_WIDTH=160
    MAX_CAPTCHA=4
    
    CAPTCHA_IMAGE_PATH="./image"
    def get_image_file_name(imgpath=CAPTCHA_IMAGE_PATH):
        filename=[]
        total=0
        for filePath in os.listdir(imgpath):
            captcha_name=filePath.split('/')[-1]
            filename.append(captcha_name)
            total+=1
        return filename
    
    def gen_data_and_label(i,filePath=CAPTCHA_IMAGE_PATH):
        FileName=get_image_file_name()[i]
        pathName=os.path.join(filePath,FileName)
        img=Image.open(pathName)
        captcha_image=np.array(img)
        text = FileName.replace(".jpg", "")
        return text,captcha_image
    
    #自定义一个函数,用来将图片颜色转换成灰色
    def convert2gray(img):
        if len(img.shape)>2:
            gray=np.mean(img,-1)
            return gray
        else:
            return img
    char_set=number+alphabet+ALPHABET+['_']
    CHAR_SET_LEN=len(char_set)
    #自定义一个函数,将文本转换成向量
    def text2vec(text):
        text_len=len(text)
        if text_len>MAX_CAPTCHA:
            raise ValueError("captcha <=4")
        vector=np.zeros(MAX_CAPTCHA*CHAR_SET_LEN)
        def char2pos(c):
            if c=='_':
                k=62
                return k
            k=ord(c)-48
            if k>9:
                k=ord(c)-55
                if k>35:
                    k=ord(c)-61
                    if k>61:
                        raise ValueError("No Map")
            return k
        for i,c in enumerate(text):
            idx=i* CHAR_SET_LEN+char2pos(c)
            vector[idx]=1
        return vector
    #自定义一个函数将向量转换成文本
    def vec2text(vec):
        # char_pos=vec.nonzero()[0]  
        text=[]
        # for i,c in enumerate(char_pos):  
        for i, c in enumerate(vec):
            char_at_pos=i
            char_idx=c%CHAR_SET_LEN
            if char_idx<10:
                char_code=char_idx+ord('0')
            elif char_idx<36:
                char_code=char_idx-10+ord("A")
            elif char_idx<62:
                char_code=char_idx-36+ord('a')
            elif char_idx==62:
                char_code=ord('_')
            else:
                raise ValueError('error')
            text.append(chr(char_code))
        return "".join(text)
    
    #自定义一个函数,生成一个训练batch
    def get_next_batch(batch_size=128):
        batch_x=np.zeros([batch_size,IMAGE_HEIGHT*IMAGE_WIDTH])
        batch_y=np.zeros([batch_size,MAX_CAPTCHA*CHAR_SET_LEN])
    
        def wrap_gen_captcha_text_and_image():
            while True:
                text,image=gen_captcha_text_and_image()
                if image.shape==(60,160,3):
                    return text,image
    
        for i in range(batch_size):
            text,image=wrap_gen_captcha_text_and_image()
            image=convert2gray(image)
    
            batch_x[i,:]=image.flatten()/255
            batch_y[i,:]=text2vec(text)
        return batch_x,batch_y
    #定义X,Y,keep_prob变量
    X=tf.placeholder(tf.float32,[None,IMAGE_HEIGHT*IMAGE_WIDTH], name='data-input')
    Y=tf.placeholder(tf.float32,[None,MAX_CAPTCHA*CHAR_SET_LEN], name='label-input')
    keep_prob=tf.placeholder(tf.float32, name='keep-prob')
    #定义一个有3个卷积层的卷积神经网络函数,用来训练
    def crack_captcha_cnn(w_alpha=0.01,b_alpha=0.1):
        x=tf.reshape(X,shape=(-1,IMAGE_HEIGHT,IMAGE_WIDTH,1))
        #conv1  
        # shape[33132]里前两个参数表示卷积核尺寸大小,即patch;  
        # 第三个参数是图像通道数,第四个参数是该层卷积核的数量,有多少个卷积核就会输出多少个卷积特征图像  
        w_c1=tf.Variable(w_alpha*tf.random_normal([3,3,1,32]))
        # 每个卷积核都配置一个偏置量,该层有多少个输出,就应该配置多少个偏置量  
        b_c1=tf.Variable(b_alpha*tf.random_normal([32]))
        # 图片和卷积核卷积,并加上偏执量,卷积结果28x28x32  
        # tf.nn.conv2d() 函数实现卷积操作  
        # tf.nn.conv2d()中的padding用于设置卷积操作对边缘像素的处理方式,在tf中有VALID和SAME两种模式  
        # padding='SAME'会对图像边缘补0,完成图像上所有像素(特别是边缘象素)的卷积操作  
        # padding='VALID'会直接丢弃掉图像边缘上不够卷积的像素  
        # strides:卷积时在图像每一维的步长,是一个一维的向量,长度4,并且strides[0]=strides[3]=1  
        # tf.nn.bias_add() 函数的作用是将偏置项b_c1加到卷积结果value上去;  
        # tf.nn.relu() 函数是relu激活函数,实现输出结果的非线性转换,即features=max(features, 0),输出tensor的形状和输入一致  
        conv1=tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(x,w_c1,strides=[1,1,1,1],padding='SAME'),b_c1))
        # tf.nn.max_pool()函数实现最大池化操作,进一步提取图像的抽象特征,并且降低特征维度  
        # ksize=[1221]定义最大池化操作的核尺寸为2*2, 池化结果14x14x32 卷积结果乘以池化卷积核  
        conv1=tf.nn.max_pool(conv1,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
        # tf.nn.dropout是tf里为了防止或减轻过拟合而使用的函数,一般用在全连接层;  
        conv1=tf.nn.dropout(conv1,keep_prob)
    
        #conv2  
        w_c2=tf.Variable(w_alpha*tf.random_normal([3,3,32,64]))
        b_c2=tf.Variable(b_alpha*tf.random_normal([64]))
        conv2=tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(conv1,w_c2,strides=[1,1,1,1],padding='SAME'),b_c2))
        conv2=tf.nn.max_pool(conv2,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
        conv2=tf.nn.dropout(conv2,keep_prob)
        # 原图像HEIGHT 60 WIDTH = 160,经过神经网络第一层后输出大小为 30*80*32  
        #conv3  
        w_c3=tf.Variable(w_alpha*tf.random_normal([3,3,64,64]))
        b_c3=tf.Variable(b_alpha*tf.random_normal([64]))
        conv3=tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(conv2,w_c3,strides=[1,1,1,1],padding='SAME'),b_c3))
        conv3=tf.nn.max_pool(conv3,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
        conv3=tf.nn.dropout(conv3,keep_prob)
        # 经过神经网络第二层运算后输出为 16*40*64 ; 经过第三层输出为 8*20*64,这个参数很重要,决定量后边全连接层的维度  
        #Fully connected layer  
        w_d=tf.Variable(w_alpha*tf.random_normal([8*20*64,1024]))
        b_d=tf.Variable(w_alpha*tf.random_normal([1024]))
        dense=tf.reshape(conv3,[-1,w_d.get_shape().as_list()[0]])
        dense=tf.nn.relu(tf.add(tf.matmul(dense,w_d),b_d))
        dense=tf.nn.dropout(dense,keep_prob)
        w_out=tf.Variable(w_alpha*tf.random_normal([1024,MAX_CAPTCHA*CHAR_SET_LEN]))
        b_out=tf.Variable(b_alpha*tf.random_normal([MAX_CAPTCHA*CHAR_SET_LEN]))
        out=tf.add(tf.matmul(dense,w_out),b_out)
        return out
    #定义一个训练函数,用来训练模型,并把准确率达到90%的模型保存下来
    def train_crack_captcha_cnn():
        output=crack_captcha_cnn()
        # tf.nn.sigmoid_cross_entropy_with_logits()函数计算交叉熵,输出的是一个向量而不是数;  
        # 交叉熵刻画的是实际输出(概率)与期望输出(概率)的距离,也就是交叉熵的值越小,两个概率分布就越接近  
        # tf.reduce_mean()函数求矩阵的均值  
        loss=tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=output,labels=Y))
        # tf.train.AdamOptimizer()函数实现了Adam算法的优化器  
        optimizer=tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss)
        predict=tf.reshape(output,[-1,MAX_CAPTCHA,CHAR_SET_LEN])
        max_idx_p=tf.argmax(predict,2,name='predict_max_idx')
        max_idx_l=tf.argmax(tf.reshape(Y,[-1,MAX_CAPTCHA,CHAR_SET_LEN]),2, name='labels_max_idx')
        correct_pred=tf.equal(max_idx_p,max_idx_l)
        accuracy=tf.reduce_mean(tf.cast(correct_pred,tf.float32))
        saver=tf.train.Saver()
        init=tf.global_variables_initializer()
        with tf.Session() as sess:
            sess.run(init)
            for step in range(1,12000+1):
                step_time = time.time()
                batch_x,batch_y=get_next_batch(64)
                _,loss_=sess.run([optimizer,loss],feed_dict={X:batch_x,Y:batch_y, keep_prob:0.75})
                if step % 400 ==0 or step==1:
                    batch_x_test,batch_y_test=get_next_batch(100)
                    acc=sess.run(accuracy,feed_dict={X:batch_x_test,Y:batch_y_test, keep_prob:1.})
                    print("Step="+str(step)+",time:"+str(step_time)+",Training Accuracy="+"{:.3f}".format(acc))
                    if acc>=0.9 or step==12000:
                        saver.save(sess,"./test/crack_captcha.model",global_step=step)
            print("Optimization Finished!")
    
    #train_crack_captcha_cnn()    #生成模型的方法,这部分代码执行很慢
    
    #定义一个测试函数
    def crack_captcha_test():
        output = crack_captcha_cnn()
        MODEL_SAVE_PATH = './t1/'
        saver = tf.train.Saver()
        with tf.Session() as sess:
            saver.restore(sess, tf.train.latest_checkpoint(MODEL_SAVE_PATH))
            predict = tf.argmax(tf.reshape(output, [-1, MAX_CAPTCHA, CHAR_SET_LEN]), 2)
            count = 0
            for i in range(100):
                text, image = gen_data_and_label(i)
                image = convert2gray(image)
                captcha_image = image.flatten() / 255
                text_list = sess.run(predict, feed_dict={X: [captcha_image], keep_prob: 1})
                predict_text = text_list[0]
                print(predict_text)
                predict_text = vec2text(predict_text)
                print(predict_text)
                filePathName = './image/' + text+'.jpg'
                img=Image.open(filePathName)
                plt.imshow(img)
                plt.suptitle(text+'.jpg')
                plt.subplots_adjust(top=1.3)
                plt.axis('off')
                if text == predict_text:
                    count += 1
                    check_result = " predictions are correct"
                else:
                    check_result = " predictions are incorrect"
                plt.title("actual value :{0},predict value:{1},".format(text, predict_text) + check_result)
                # plt.show()  
                print("actual value :{0},predict value:{1},".format(text, predict_text) + check_result)
            print("correct rate:" + str(count) + "/100")
    crack_captcha_test()#模型生成后使用此方法进行分析
  • 相关阅读:
    设计模式:生产者消费者模式
    图解SSH原理
    监听Google Player下载并获取包名等信息
    android targetSdkVersion>=26收不到广播的处理
    ant property file刷新不及时
    maven的pom文件报错: must be "pom" but is "jar"
    AJAX其实就是一个异步网络请求
    String、StringBuffer、StringBuilder的区别
    Properties、ResourceBundle
    JavaWeb--Listener
  • 原文地址:https://www.cnblogs.com/1gaoyu/p/12708234.html
Copyright © 2020-2023  润新知