精华内容
下载资源
问答
  • 随着目标检测算法在工程中的广泛应用,视频和批量图片的处理成为重要的环节。在对视频进行目标识别标记,主要采用opencv,每次读取一帧图像,然后送入网络,得到目标物所属类别,框的坐标信息和置信度,然后绘制到...

    引言

    随着目标检测算法在工程中的广泛应用,视频和批量图片的处理成为重要的环节。在对视频进行目标识别标记,主要采用opencv,每次读取一帧图像,然后送入网络,得到目标物所属类别,框的坐标信息和置信度,然后绘制到图像中,并把此帧图像实时显示。但无法保存带识别标记的视频(本人浅薄,暂且未找到opencv中合适方法)故本博客提出一种基于FFmpeg的批量标记帧图像生成视频方法。本文把识别好的每一帧图像按序号保存至某一独立文件夹,在运用FFmpeg将文件夹中的有序帧图像合成视频。

    FFmpeg下载与安装

    方法一:官网下载(非常慢)

    FFmpeg官方下载地址

    方法二:我在外网下载好,提供网盘链接

    链接:ffmpeg-20200628-4cfcfb3-win64-static.zip
    提取码:mmtx

    安装FFmpeg

    下载zip文件,解压,把bin目录下的ffmepg.exe,所在路径加入到系统环境变量path中,即可。参考博客

    验证安装成功

    win + R 打开,输入cmd,打开终端
    输入ffmpeg -version
    出现下图,安装成功。
    安装成功

    探索解决方案

    在对监控视频取帧进行目标识别+存储有序帧后,先后从两大方向,多个角度尝试,皆效果不理想。

    1. 运用opencv来实现有序帧转视频(转换后的视频播放出现帧间闪烁)
    2. 用Win10自带视频编辑器处理(手动调节每一帧播放时间,费时费力)
    3. PR视频剪辑软件生成(对帧的序号有严格要求,如000.jpg、001.jpg·······199.jpg)(而我在目标识别后保存的序号是1.jpg、2.jpg、3.jpg ···50.jpg、51.jpg···198.jpg、199.jpg;是按数字递增的并没有保持序号宽度一致)
      当然,python熟练的可以在保存帧的时候,统一命名为序列宽度一致,并保存。

    最终解决方案

    运用FFmpeg针对有序帧转化为视频。

    前提准备

    安装好ffmpeg
    带有有序标号的标记好的帧图像的文件夹(我的有序命名为 fram1.jpg、fram2.jpg、fram3.jpg···fram712.jpg )

    命令行输入指令

    当运用ffmpeg压缩视频时,推荐用libx264编码格式,根据经验,这样得到的视频,分辨率体积小。不同版本的ffmpeg会得到不同的输出文件。
    例如文件夹中图像格式(fram1.jpg, fram2.jpg…. etc)此时运用以下指令:

    ffmpeg -r 60 -f image2 -s 1920x1080 -i fram%d.jpg -vcodec libx264 -crf 25  -pix_fmt yuv420p test.mp4
    

    主要修改 帧率、输入图片帧命名格式、输出

    %04d 表示用零来填充直到长度为4,i.e 0001…0020…0030…2000 and so on.
    如果没有填充,需要相应更改,如 pic%d.png or %d.png
    
    -r 帧率(fps)
    -f image2 图像合成视频默认设置
    -crf 画质,数值小意味着画质高,通常设置为15-25 
    -s 分辨率(1920x1080)
    -pix_fmt yuv420p 像素格式
    test.mp4 输出在当前文件夹,输出结果为test.mp4
    

    参考资料

    [1]https://blog.csdn.net/kaikai136412162/article/details/80746961
    [2]http://hamelot.io/visualization/using-ffmpeg-to-convert-a-set-of-images-into-a-video/

    展开全文
  • CNN——基于CNN的车牌识别

    万次阅读 多人点赞 2019-04-01 17:35:38
    本例提供的训练集里面的每个图片都是20x20 的二值化后的灰度图,例如: 因此,我们需要使用PIL库或opencv库把灰度图转换为我们方便处理的数据形式。本人是先转化为list of list. picReader.py __author__ = 'jmh...

    car-board-reg

    基于CNN的车牌号识别
    github:https://github.com/jmhIcoding/car-board-reg.git

    数据集介绍

    车牌构成

    为简化实验,在该实验中默认车牌字符已经得到划分,因此车牌识别可以分解为三个区域的字符识别任务(多分类任务),共实现7个字符的识别。
    例如:京A·F0236
    其中第一部分 表示车牌所在的省市,后面紧跟的A是发牌单位,间隔符·后面的5个字符就是序号。
    省市Province:
    (“皖”, “沪”, “津”, “渝”, “冀”, “晋”, “蒙”, “辽”, “吉”, “黑”, “苏”, “浙”, “京”, “闽”, “赣”, “鲁”, “豫”, “鄂”, “湘”, “粤”, “桂”, “琼”, “川”, “贵”, “云”, “藏”, “陕”, “甘”, “青”, “宁”, “新”)
    发牌单位Area:
    (“A”,“B”,“C”,“D”,“E”,“F”,“G”,“H”,“I”,“J”,“K”,“L”,“M”,“N”,“O”,“P”,“Q”,“R”,“S”,“T”,“U”,“V”,“W”,“X”,“Y”,“Z”)
    字符Letter:
    (“0”,“1”,“2”,“3”,“4”,“5”,“6”,“7”,“8”,“9”,“A”,“B”,“C”,“D”,“E”,“F”,“G”,“H”,“J”,“K”,“L”,“M”,“N”,“P”,“Q”,“R”,“S”,“T”,“U”,“V”,“W”,“X”,“Y”,“Z”)

    数据集目录:

    └─dataset
        ├─maps.py    ---->映射关系文件
        ├─train     ---->训练集
        │  ├─area  
        │  ├─letter
        │  └─province
        └─val       ----->验证集
            ├─area
            ├─letter
            └─province
    

    PIL读取Image文件

    本例提供的训练集里面的每个图片都是20x20 的二值化后的灰度图,例如:
    在这里插入图片描述
    因此,我们需要使用PIL库或opencv库把灰度图转换为我们方便处理的数据形式。本人是先转化为list of list.

    picReader.py

    __author__ = 'jmh081701'
    from PIL import  Image
    def img2mat(img_filename):
    #把所有的图片都resize为20x20
        img = Image.open(img_filename)
        img = img.resize((20,20))
        mat = [[img.getpixel((x,y)) for x in range(0,img.size[0])] for y in range(0,img.size[1])]
        return mat
    def test():
        mat = img2mat("dataset\\test\\1.bmp")
        print(mat)
        print(mat[0][0],len(mat),len(mat[0]))
    if __name__ == '__main__':
        test()
    

    样例输出:

    [[0, 0, 0, 0, 144, 212, 74, 17, 15, 60, 60, 62, 64, 67, 67, 68, 35, 0, 0, 0], [0, 0, 0, 0, 28, 119, 255, 101, 61, 233, 255, 255, 255, 255, 255, 255, 241, 44, 0, 0], [0, 0, 0, 0, 0, 15, 170, 92, 8, 14, 34, 31, 29, 29, 24, 74, 226, 38, 0, 0], [0, 0, 67, 220, 83, 4, 0, 0, 0, 84, 160, 0, 0, 0, 0, 52, 170, 11, 0, 0], [0, 0, 71, 255, 105, 10, 0, 0, 75, 230, 246, 124, 5, 0, 0, 49, 188, 19, 0, 0], [0, 0, 64, 255, 113, 15, 152, 216, 246, 255, 255, 255, 226, 225, 27, 46, 255, 59, 0, 0], [0, 0, 53, 255, 120, 22, 172, 249, 255, 255, 255, 255, 255, 255, 35, 33, 213, 61, 0, 0], [0, 0, 43, 255, 139, 105, 243, 254, 130, 231, 255, 139, 217, 255, 37, 35, 234, 63, 0, 0], [0, 0, 34, 247, 151, 68, 166, 248, 143, 225, 255, 159, 219, 255, 41, 37, 240, 50, 0, 0], [0, 0, 26, 240, 136, 38, 143, 246, 255, 255, 255, 255, 255, 255, 43, 29, 168, 0, 0, 0], [0, 0, 18, 231, 142, 44, 135, 246, 255, 255, 255, 230, 190, 98, 6, 25, 210, 49, 2, 0], [0, 0, 17, 223, 147, 49, 112, 214, 123, 226, 255, 147, 0, 0, 0, 28, 218, 10, 1, 0], [0, 0, 16, 212, 154, 56, 0, 0, 4, 69, 249, 149, 148, 216, 46, 18, 205, 94, 13, 0], [0, 0, 15, 200, 157, 59, 0, 11, 45, 255, 255, 242, 244, 255, 57, 3, 33, 13, 2, 0], [0, 0, 15, 196, 164, 66, 0, 66, 253, 198, 198, 198, 200, 225, 154, 87, 252, 90, 18, 0], [0, 0, 14, 184, 171, 73, 0, 8, 31, 1, 0, 0, 1, 16, 8, 13, 255, 110, 25, 0], [0, 0, 13, 175, 177, 79, 0, 0, 0, 0, 0, 0, 0, 0, 8, 37, 255, 117, 30, 0], [0, 0, 10, 134, 147, 69, 0, 0, 0, 0, 0, 0, 0, 0, 29, 127, 230, 24, 5, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 18, 2, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
    0 20 20
    

    模型设计

    数据集已经把一个车牌的三个部分都分开了,所以可以设计三个模型分别去识别这三部分。在本例中,本人为了简单期间,三个部分用了用一个CNN 网络结构,但是每个网络结构里面的具体参数是各自独立的。
    CNN网络结构:

    1. 输入层:20x20
    2. 第一层卷积:卷积核大小:3x3,卷积核个数:32,Stride 步长:1,Same 卷积
    3. 第二层卷积:卷积核大下:3x3,卷积核个数:64,Stride 步长:1,Same卷积
      (两个卷积级联,效果就是5x5的卷积核,但是减少了参数个数)
    4. 第二层池化:池化大小:2x2,max pool,Stride 步长:2
    5. 第三层卷积:卷积核大小:3x3,卷积核个数:8,Stride 步长:1,Same卷积
    6. 第三层池化:池化大小:2x2,max pooling,Stride :2。应该得到8个5x5的特征图。
      平坦化:得到8x5x5=200维的向量
    7. 第四层全连接:512个神经元,激活函数为relu。
    8. 第五层全连接:34个神经元,softmax激活函数。

    第五层是分类层,一共有34个神经元,表示最多有34个类别。对于province来说,只有前31类有效;对于area来说只有前26类有效;对于letter来说,这34个神经元都有效。因此在生成训练集的时候,需要把正确的答案标签编码为34维的one-hot

    数据处理

    数据处理模块,主要仿照minist数据集的写法,编写一个类,实现next_train_batch,next_test_batch,next_valid_batch函数。
    BaseTool.py

    __author__ = 'jmh081701'
    from dataset.map import  maps as aspectMap
    import  os
    from picReader import  img2mat
    import  random
    class data_generator:
        def __init__(self,aspect='area',seperate_ratio=0.1):
            '''
            :param aspect: 打开什么样的训练集,[area,letter,province] 三选一
            :param seperate_ratio: 测试集划分比例 ,从训练集和验证集里面随机抽取seperate_ratio作为训练集
            :return:
            '''
            self.train_dir = "dataset\\train\\%s\\" %aspect
            self.val_dir   = "dataset\\val\\%s\\" % aspect
            self.seperate_ratio = seperate_ratio
    
            self.data_vector_set  = []      #保存所有的图片向量
            self.data_label_set   = []      #保存所有的标签
    
            self.train_set = []             #保存训练集的下标
            self.train_batch_index = 0
            self.valid_set = []             #保存验证集的下标
            self.valid_batch_index = 0
            self.test_set = []              #保存测试集的下标
            self.test_batch_index = 0
    
    
            self.classes = 0                #最大的classes为34,这个值会在载入train和test后有所变化
            self.data_set_cnt = 0
    
            self.load_train()
            self.load_valid()
    
        def load_train(self):
            for rt,dirs,files in os.walk(self.train_dir):
                self.classes = max(self.classes,len(dirs))
                if len(dirs)==0 :
                    #说明到了叶子目录,里面放着就是图片
                    label = int(rt.split('\\')[-1])
                    for name in files:
                        img_filename = os.path.join(rt,name)
                        vec = img2mat(img_filename)
                        self.data_vector_set.append(vec)
                        self.data_label_set.append(label)
                        if random.random() < self.seperate_ratio:
                            self.test_set.append(self.data_set_cnt)
                        else:
                            self.train_set.append(self.data_set_cnt)
                        self.data_set_cnt +=1
        def load_valid(self):
            for rt,dirs,files in os.walk(self.val_dir):
                self.classes = max(self.classes,len(dirs))
                if len(dirs)==0 :
                    #说明到了叶子目录,里面放着就是图片
                    label = int(rt.split('\\')[-1])
                    for name in files:
                        img_filename = os.path.join(rt,name)
                        vec = img2mat(img_filename)
                        self.data_vector_set.append(vec)
                        self.data_label_set.append(label)
                        if random.random() < self.seperate_ratio:
                            self.test_set.append(self.data_set_cnt)
                        else:
                            self.valid_set.append(self.data_set_cnt)
                        self.data_set_cnt +=1
        def next_train_batch(self,batch=100):
            input_x =[]
            input_y =[]
            for i in range(batch):
                input_x.append(self.data_vector_set[self.train_set[(self.train_batch_index + i)%len(self.train_set)]])
                y = [0] * self.classes
                y[self.data_label_set[self.train_set[(self.train_batch_index +i)%len(self.train_set)]]] = 1
                input_y.append(y)
            self.train_batch_index +=batch
            self.train_batch_index %=len(self.train_set)
            return  input_x,input_y
    
        def next_valid_batch(self,batch=100):
            input_x =[]
            input_y =[]
            for i in range(batch):
                index = random.randint(0,len(self.valid_set)-1)
                input_x.append(self.data_vector_set[index])
                y = [0] * 34
                y[self.data_label_set[index]] = 1
                input_y.append(y)
            self.valid_batch_index +=batch
    
            self.valid_batch_index %=len(self.valid_set)
            return  input_x,input_y,self.train_epoch
        def next_test_batch(self,batch=100):
            input_x =[]
            input_y =[]
            for i in range(batch):
                input_x.append(self.data_vector_set[self.test_set[(self.test_batch_index + i)%len(self.test_set)]])
                y = [0] * self.classes
                y[self.data_label_set[self.test_set[(self.test_batch_index +i)%(len(self.test_set))]]] = 1
                input_y.append(y)
            self.test_batch_index +=batch
            self.test_batch_index %=len(self.test_set)
            return  input_x,input_y
    if __name__ == '__main__':
        data_gen = data_generator()
        print(len(data_gen.test_set))
        print(data_gen.next_train_batch(50))
        print(data_gen.next_valid_batch(50)[1])
        print(data_gen.next_train_batch(30))
    

    构建CNN模型

    cnn_model.py

    __author__ = 'jmh081701'
    import  tensorflow as tf
    from BaseTool import  data_generator
    
    batch_size = 100        # 每个batch的大小
    learning_rate=1e-4      #学习速率
    aspect = "area"
    data_gen = data_generator(aspect)
    
    input_x  =tf.placeholder(dtype=tf.float32,shape=[None,20,20],name='input_x')
    input_y  =tf.placeholder(dtype=tf.float32,shape=[None,34],name='input_y')
    
    with tf.name_scope('conv1'):
        W_C1 = tf.Variable(tf.truncated_normal(shape=[3,3,1,32],stddev=0.1))
        b_C1 = tf.Variable(tf.constant(0.1,tf.float32,shape=[32]))
    
        X=tf.reshape(input_x,[-1,20,20,1])
        featureMap_C1 = tf.nn.relu(tf.nn.conv2d(X,W_C1,strides=[1,1,1,1],padding='SAME') + b_C1 )
    
    with tf.name_scope('conv2'):
        W_C2 = tf.Variable(tf.truncated_normal(shape=[3,3,32,64],stddev=0.1))
        b_C2 = tf.Variable(tf.constant(0.1,tf.float32,shape=[64]))
        featureMap_C2 = tf.nn.relu(tf.nn.conv2d(featureMap_C1,W_C2,strides=[1,1,1,1],padding='SAME') + b_C2)
    
    with tf.name_scope('pooling2'):
        featureMap_S2 = tf.nn.max_pool(featureMap_C2,ksize=[1,2,2,1],strides=[1,2,2,1],padding='VALID')
    
    with tf.name_scope('conv3'):
        W_C3 = tf.Variable(tf.truncated_normal(shape=[3,3,64,8],stddev=0.1))
        b_C3 = tf.Variable(tf.constant(0.1,shape=[8],dtype=tf.float32))
        featureMap_C3 = tf.nn.relu(tf.nn.conv2d(featureMap_S2,filter=W_C3,strides=[1,1,1,1],padding='SAME')+ b_C3)
    
    with tf.name_scope('pooling3'):
        featureMap_S3 = tf.nn.max_pool(featureMap_C3,[1,2,2,1],[1,2,2,1],padding='VALID')
    
    with tf.name_scope('fulnet'):
        featureMap_flatten = tf.reshape(featureMap_S3,[-1,5*5*8])
        W_F4 = tf.Variable(tf.truncated_normal(shape=[5*5*8,512],stddev=0.1))
        b_F4 = tf.Variable(tf.constant(0.1,shape=[512],dtype=tf.float32))
        out_F4 = tf.nn.relu(tf.matmul(featureMap_flatten,W_F4) + b_F4)
        #out_F4 =tf.nn.dropout(out_F4,keep_prob=0.5)
    with tf.name_scope('output'):
        W_OUTPUT = tf.Variable(tf.truncated_normal(shape=[512,34],stddev=0.1))
        b_OUTPUT = tf.Variable(tf.constant(0.1,shape=[34],dtype=tf.float32))
        logits = tf.matmul(out_F4,W_OUTPUT)+b_OUTPUT
    
    loss = tf.reduce_sum(tf.nn.softmax_cross_entropy_with_logits(labels=input_y,logits=logits))
    train_op = tf.train.AdamOptimizer(learning_rate).minimize(loss)
    predictY = tf.nn.softmax(logits)
    y_pred=tf.arg_max(predictY,1)
    bool_pred=tf.equal(tf.arg_max(input_y,1),y_pred)
    right_rate=tf.reduce_mean(tf.to_float(bool_pred))
    
    saver = tf.train.Saver()
    def load_model(sess,dir,modelname):
        ckpt=tf.train.get_checkpoint_state(dir)
        if ckpt and ckpt.model_checkpoint_path:
            print("*"*30)
            print("load lastest model......")
            saver.restore(sess,dir+".\\"+modelname)
            print("*"*30)
    def save_model(sess,dir,modelname):
        saver.save(sess,dir+modelname)
    dir = r".//"
    modelname = aspect
    
    with tf.Session() as sess:
        sess.run(tf.initialize_all_variables())
        step = 1
        display_interval=200
        max_epoch = 50
        epoch = 0
        acc = 0
        load_model(sess,dir=dir,modelname=modelname)
        while True  :
            if step % display_interval ==0:
                image_batch,label_batch,epoch = data_gen.next_valid_batch(batch_size)
                acc = sess.run(right_rate,feed_dict={input_x:image_batch,input_y:label_batch})
                print({'!'*30+str(epoch)+":"+str(step):acc})
            image_batch,label_batch,epoch = data_gen.next_train_batch(batch_size)
            sess.run([loss,train_op],{input_x:image_batch,input_y:label_batch})
            if(epoch> max_epoch):
                break
            step +=1
        while True :
            test_img,test_lab,test_epoch = data_gen.next_test_batch(batch_size)
            test_acc = sess.run(right_rate,{input_x:test_img,input_y:test_lab})
            acc = test_acc * 0.8 + acc * 0.2    #指数滑动平均
            if(test_epoch!=epoch):
                print({"Test Over..... acc:":acc})
                break
        save_model(sess,dir,modelname)
    
    

    训练结果:

    area:

    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!3:200': 0.34}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!6:400': 0.61}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!9:600': 0.78}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!13:800': 0.73}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!16:1000': 0.8}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!19:1200': 0.88}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!23:1400': 0.76}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!25:1600': 0.86}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!28:1800': 0.89}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!32:2000': 0.83}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!35:2200': 0.87}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!38:2400': 0.93}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!42:2600': 0.89}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!45:2800': 0.9}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!48:3000': 0.95}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!50:3200': 0.97}
    {'Test Over..... acc:': 0.9042283506058594}
    

    province:

    ******************************
    load lastest model......
    ******************************
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!7:200': 0.9}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!15:400': 0.88}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!22:600': 0.91}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!29:800': 0.92}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!36:1000': 0.95}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!44:1200': 0.99}
    {'Test Over..... acc:': 0.7786719818115235}
    

    可以看到,模型有点过拟合了,因为验证集表现的很好,但是测试gg。
    于是加上dropout

    out_F4 =tf.nn.dropout(out_F4,keep_prob=0.5)
    

    结果,还是很差,哈哈哈,垃圾网络,233

    ******************************
    load lastest model......
    ******************************
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!7:200': 0.91}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!15:400': 0.92}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!24:600': 0.94}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!32:800': 0.92}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!40:1000': 0.95}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!48:1200': 0.98}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!55:1400': 0.94}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!63:1600': 0.96}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!71:1800': 0.95}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!79:2000': 0.99}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!87:2200': 0.95}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!95:2400': 0.98}
    {'Test Over..... acc:': 0.857055978012085}
    

    letter:
    字符比较多,把max_epoch加大到500来,最后测试准确率为96.17%

    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!483:57600': 1.0}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!485:57800': 0.99}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!487:58000': 1.0}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!488:58200': 1.0}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!490:58400': 0.99}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!492:58600': 1.0}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!494:58800': 1.0}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!495:59000': 1.0}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!496:59200': 1.0}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!498:59400': 1.0}
    {'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!499:59600': 1.0}
    {'Test Over..... acc:': 0.9617528679144185}
    

    添加自适应学习速率

    前面的代码中学习速率是固定的,这是不合理的。训练前期模型可以以较高的学习速率学习,后期再以较低的学习速率学习。方法是每隔一定数量的epoch 就让学习速率缩小。

    __author__ = 'jmh081701'
    import  tensorflow as tf
    from BaseTool import  data_generator
    
    batch_size = 100        # 每个batch的大小
    lr=0.001      # 学习速率,每20个epoch 减少为原来的80%
    aspect = "letter"
    data_gen = data_generator(aspect)
    
    input_x  =tf.placeholder(dtype=tf.float32,shape=[None,20,20],name='input_x')
    input_y  =tf.placeholder(dtype=tf.float32,shape=[None,34],name='input_y')
    input_learning_rate = tf.placeholder(dtype=tf.float32,name='learning_rate') #把learning rate变成placeholder就可以啦
    
    with tf.name_scope('conv1'):
        W_C1 = tf.Variable(tf.truncated_normal(shape=[3,3,1,32],stddev=0.1))
        b_C1 = tf.Variable(tf.constant(0.1,tf.float32,shape=[32]))
    
        X=tf.reshape(input_x,[-1,20,20,1])
        featureMap_C1 = tf.nn.relu(tf.nn.conv2d(X,W_C1,strides=[1,1,1,1],padding='SAME') + b_C1 )
    
    with tf.name_scope('conv2'):
        W_C2 = tf.Variable(tf.truncated_normal(shape=[3,3,32,64],stddev=0.1))
        b_C2 = tf.Variable(tf.constant(0.1,tf.float32,shape=[64]))
        featureMap_C2 = tf.nn.relu(tf.nn.conv2d(featureMap_C1,W_C2,strides=[1,1,1,1],padding='SAME') + b_C2)
    
    with tf.name_scope('pooling2'):
        featureMap_S2 = tf.nn.max_pool(featureMap_C2,ksize=[1,2,2,1],strides=[1,2,2,1],padding='VALID')
    
    with tf.name_scope('conv3'):
        W_C3 = tf.Variable(tf.truncated_normal(shape=[3,3,64,8],stddev=0.1))
        b_C3 = tf.Variable(tf.constant(0.1,shape=[8],dtype=tf.float32))
        featureMap_C3 = tf.nn.relu(tf.nn.conv2d(featureMap_S2,filter=W_C3,strides=[1,1,1,1],padding='SAME')+ b_C3)
    
    with tf.name_scope('pooling3'):
        featureMap_S3 = tf.nn.max_pool(featureMap_C3,[1,2,2,1],[1,2,2,1],padding='VALID')
    
    with tf.name_scope('fulnet'):
        featureMap_flatten = tf.reshape(featureMap_S3,[-1,5*5*8])
        W_F4 = tf.Variable(tf.truncated_normal(shape=[5*5*8,512],stddev=0.1))
        b_F4 = tf.Variable(tf.constant(0.1,shape=[512],dtype=tf.float32))
        out_F4 = tf.nn.relu(tf.matmul(featureMap_flatten,W_F4) + b_F4)
        out_F4 =tf.nn.dropout(out_F4,keep_prob=0.5)
    with tf.name_scope('output'):
        W_OUTPUT = tf.Variable(tf.truncated_normal(shape=[512,34],stddev=0.1))
        b_OUTPUT = tf.Variable(tf.constant(0.1,shape=[34],dtype=tf.float32))
        logits = tf.matmul(out_F4,W_OUTPUT)+b_OUTPUT
    
    loss = tf.reduce_sum(tf.nn.softmax_cross_entropy_with_logits(labels=input_y,logits=logits))
    train_op = tf.train.AdamOptimizer(learning_rate=input_learning_rate).minimize(loss)
    predictY = tf.nn.softmax(logits)
    y_pred=tf.arg_max(predictY,1)
    bool_pred=tf.equal(tf.arg_max(input_y,1),y_pred)
    right_rate=tf.reduce_mean(tf.to_float(bool_pred))
    
    saver = tf.train.Saver()
    def load_model(sess,dir,modelname):
        ckpt=tf.train.get_checkpoint_state(dir)
        if ckpt and ckpt.model_checkpoint_path:
            print("*"*30)
            print("load lastest model......")
            saver.restore(sess,dir+".\\"+modelname)
            print("*"*30)
    def save_model(sess,dir,modelname):
        saver.save(sess,dir+modelname)
    dir = r".\\parameter\\%s\\"%aspect
    modelname = aspect
    
    with tf.Session() as sess:
        sess.run(tf.initialize_all_variables())
        step = 1
        display_interval=200
        max_epoch = 500
        epoch = 1
        acc = 0
        load_model(sess,dir=dir,modelname=modelname)
        while True  :
            if step % display_interval ==0:
                image_batch,label_batch,epoch = data_gen.next_valid_batch(batch_size)
                acc = sess.run(right_rate,feed_dict={input_x:image_batch,input_y:label_batch,input_learning_rate:lr})
                print({'!'*30+str(epoch)+":"+str(step):acc})
            image_batch,label_batch,epoch = data_gen.next_train_batch(batch_size)
            sess.run([loss,train_op],{input_x:image_batch,input_y:label_batch})
            if(epoch> max_epoch):
                break
            step +=1
            if (epoch % 20) ==0:
                lr =lr * 0.8
        while True :
            test_img,test_lab,test_epoch = data_gen.next_test_batch(batch_size)
            test_acc = sess.run(right_rate,feed_dict={input_x:test_img,input_y:test_lab,input_learning_rate:lr})
            acc = test_acc * 0.8 + acc * 0.2    #指数滑动平均
            if(test_epoch!=epoch):
                print({"Test Over..... acc:":acc})
                break
    
        save_model(sess,dir,modelname)
    
    
    展开全文
  • Dlib与OpenCV图片转换

    千次阅读 2018-05-06 13:08:24
    本人知乎:Ngxin转载请注明出处!在做人脸关键点检测时候碰到Dlib的图片格式转换以及Dlib与OpenCV图片格式的互转,找了不少资料,现总结如下:1:首先,Dlib图片格式与OpenCV还是有一定区别的,dlib是以dlib::...

    本人知乎号:Ngxin

    转载请注明出处!

    在做人脸关键点检测时候碰到Dlib的图片格式转换以及Dlib与OpenCV图片格式的互转,找了不少资料,现总结如下:

    1:首先,Dlib图片格式与OpenCV还是有一定区别的,dlib是以dlib::array2d的形式存在,而oepncv是以cv::Mat的形式存在,关于opencv图像之间的转换,网上有很多资料,这里不再赘述,仅介绍一下dlib的图片格式转换以及dlib与opencv之间图片格式的互转。

    2:dlib中读取图片:

    dlib::array2d<dlib::rgb_pixel> img_rgb;
    dlib::load_image(img_rgb, "test_image.jpg");
    

    3:dlib rgb图片转换成灰度图片:

    dlib::array2d<unsigned char> img_gray;
    dlib::assign_image(img_gray, img_rgb);
    

    4:dlib转换成OpenCV图片:

    #include <dlib/opencv.h>
    #include <opencv2/opencv.hpp>
    cv::Mat img = dlib::toMat(img_gray);
    

    5:OpenCV转Dlib:

    #include<dlib/opencv.h>
    #include<opencv2/opencv.hpp>
    cv::Mat img =cv::imread("test_image.jpg");
    dlib::cv_image<rgb_pixel>=dlib_img(img);
    

    6:Opencv灰度图片转Dlib灰度图片:

    #include<dlib/opencv.h>
    #include<opencv2/opencv.hpp>
    cv::gray_img
    cv::Mat rgb_img = cv::imread("test_image.jpg");
    cv::cvtcolor(rgb_img,gray_img,cv::COLOR_BGR2GRAY);
    dlib::cv_image(uchar)=dlib_gray_img(gray_img);
    

    参考链接:

    Convert RGB Image to Grayscale Image in DLIB

    dlib.net/imaging.html

    展开全文
  • 思路:由于详情文本有图片图片地址含数字,本人正则水平有限是先把图片地址取出来,然后在过滤手机等联系方式,最后再替换图片地址,功能实现 实现方式(正则,preg_replace) 取出文本中的图片地址 //匹配...

    需求:过滤公司详情的联系方式(手机,qq,email等)

    思路:由于详情文本有图片且图片地址含数字,本人正则水平有限是先把图片地址取出来,然后在过滤手机号等联系方式,最后再替换图片地址,功能实现

    实现方式(正则,preg_replace,str_replace)

    1. 取出文本中的图片地址
    //匹配图片地址的正则
    $pattern="/<[img|IMG].*?src=[\'|\"](.*?(?:[\.gif|\.jpg]))[\'|\"].*?[\/]?>/";
    preg_match_all($pattern,$str,$picsrc);
    //图片地址存在	$picsrc中,如下图
    

    在这里插入图片描述
    2. 过滤联系方式

    
    //过滤内容的手机号 座机号 QQ号 邮箱地址的正则
    $patterns  = array(
    	"/(1[3578]{1}[0-9])[0-9]{4}([0-9]{4})/",
    	"/(0[0-9]{2,3}[\-]?[2-9])[0-9]{3,4}([0-9]{3}[\-]?[0-9]?)/i",
    	"/(\d{5,10})/",
    	"/([a-z0-9\-_\.])[a-z0-9\-_\.]{4}(([a-z0-9\-_\.])@[a-z0-9]+\.[a-z0-9\-_\.]+)/",
    	"/([a-z0-9\-_\.]+@[a-z0-9]+\.[a-z0-9\-_\.]+)+/i");
    $str = preg_replace($patterns,'********',$str);		
    
    1. 替换图片
    //取出要查找的图片地址
    preg_match_all($pattern,$str,$nmatch);
    //进行替换
    $str = str_replace($nmatch[0],$picsrc[0],$str);
    
    展开全文
  • 本人笔记本了新账户就是了管理员,然后用新账户连不上sqlserver2008了。安装时是用旧帐户安装,现在了新账户后连不上了。不知道该如何解决,求大佬帮忙。难道要卸载重装?感觉卸载干净也很麻烦。。感觉自己...
  • 这是本人在刚学完java基础部分写的,没写过什么代码,所以命名不规范,应该不容易读懂代码。 功能是登陆游戏后移动至亚贝罗人物兑换材料材料,每个角色循环。结束后切换账号,登陆下一个账号。 仅支持1080p分辨率、720p...
  • 批量添加PDF帐号目录

    2018-08-23 16:14:36
    如作者介意请留言,本人会尽快处理! 准备材料: 下载工具FreePic2Pdf(在本博客上传资料上... 找到您要添加的目录(可以做直接百度或者在PDF上复制文件本身目录,或者用图片转换工具进行) 下载一个支持...
  • ueditor上传图片视频Java-前后端分离

    千次阅读 2018-07-30 11:46:49
    1、本人下载版本是:1.4.3.3 完整源码,后台需要改的东西。 (1)完整版本里有源码:ueditor-1.4.3.3\ueditor-1.4.3.3\jsp\src,下面所有源码复制到项目src下面。 (2)找到BinaryUploader类用以下代码替换。 ...
  • 我的一个MFC的vs2010工程,能够实现串口通信。之前,在笔记本A上实验,串口是...但是我的两个笔记本A和B中的f盘里都没有这样一个文件夹啊,我觉得好奇怪,一时不知道改如何去差错,大神们快帮帮我吧,本人c++小白。。
  • 验证码--在输入验证码框中点击回车键 或 点击 验证码图片. 出现验证码 既可输入验证码 等待提交 (在等待延时时 出现验证码后也既可输入验证码等待提交) 提交--输入4位验证码后 自动提交 无须点击其它任何键. ...
  • 验证码--在输入验证码框中点击回车键 或 点击 验证码图片. 出现验证码 既可输入验证码 等待提交 (在等待延时时 出现验证码后也既可输入验证码等待提交) 提交--输入4位验证码后 自动提交 无须点击其它任何键. 自动...
  • 提问的智慧 How To Ask Questions The Smart Way ... Raymond, Rick Moen 本指南英文版版权为 Eric S.... ...Copyleft 2001 by D.H.Grand(nOBODY/Ginux), 2010 by Gasolin, 2015 by Ryan Wu 本中文指南是基于原文 3.10 版...
  • qq头像接口网页引用

    2021-04-24 21:49:12
    qq头像的url: <img class="avatar" src="//q.qlogo.cn/g?b=qq&nk=你的QQ&s=图片大小"/> “图片大小”替换成: 原图:0; 中等:100; 最小:1; 效果:(本人头像) 求赞,求这次一定
  • 庆幸本人在台资工厂呆过5年,对台湾的IT习语大都了解,所以把很多台湾的习语都替换过来了。还有5处我觉得应该替换的习语,由于项目使用的较多,情况比较复杂,暂时不知道应该替换成什么。大家可以给些意见继续完善...
  • 献出本网吧使用了5年的网吧留言本,此留言程序本网吧从2005-12-13 开始...头部横幅图片原文件背景源文件.psd已经放在加压包目录里.Photoshop 7.0 中文版可以修改成你的网吧名字.修改后把图片覆盖到images目录bg.jpg文件.
  • 本源码仅限于交流学习,凡涉及到法律问题与本人无关 English 捐赠: 您的捐赠是我们开源最大的动力 BTC/USDT(比特币/USDT):1Dwwqhw9pV9iSSQwuJc8nAygda7XfahaoW ETH/USDT(以太坊/USDT):0x4f1ea0f10aa99f...
  • 孤心夜雪联系册V2.15

    2006-11-10 13:28:51
    3、图片文件的类型转换; 此软件的初始帐号信息: 帐号:admin 密码:12345 此软件是用VB。NET开发所以需要.NET框架支持 如果你的系统是WINDOWS 2003 ,或你的系统上装了.NET框架,则可以直接使用本软件,...
  • 黄金贵金属投资网站源码采用常用的.NET2.0版本,方便...3、因为它本来是我打算给别人正式商用的网站,所以本源码下的所有代码与设计,都是本人原创,会有任何版权问题,大家可以放心使用(个别演示图片注意替换就OK)。
  • 为了方便阅读,本人在上传前添加了完整的书签。 全书压缩打包成3部分,这是第2部分。 注:本系列图书的第I、II卷再版时均相应改名为《xxx开发实例大全》(基础卷)及(提高卷),但内容基本无变化,需要的童鞋可自由...
  • 为了方便阅读,本人在上传前添加了完整的书签。 全书压缩打包成3部分,这是第3部分。 注:本系列图书的第I、II卷再版时均相应改名为《xxx开发实例大全》(基础卷)及(提高卷),但内容基本无变化,需要的童鞋可自由...
  • 4)新增GetImagesUrl属性,可以通过该属性获取控件提交内容里所有图片的URL地址(Webeditor1.GetImagesUrl[图片序号].ToString()),得到的图片地址将可用于首页新闻的图片显示或幻灯片显示。 2008/2/28 Version ...
  • 星星整站程序 v1.1.rar

    2019-08-30 09:21:49
    7.由于本人技术有限,所以难免会出现问题。如果你是高手,请帮我继续 完善一下这个程序! 一、前台: 1.除去所有多余图片及文件,全面优化各部分代码 2.首页暂时保留蓝雨风格,以便于使用蓝雨整站者的自行风格修改 ...
  • 3、因为它本来是我打算给别人正式商用的网站,所以本源码下的所有代码与设计,都是本人原创,会有任何版权问题,大家可以放心使用(个别演示图片注意替换就OK)        相关阅读 同类推荐:企业网站...
  • WP主题:HotNewspro 2.72

    2013-10-05 09:45:41
    这个东西一直是本人自己用的,虽然很早就集成在主题中,但从未写过使用方法,主要用于转载文章时,尊重原文作者而增添的功能。 如果文章是自己写的:添加自定义栏目:original,值:自已的名字或链接地址什么都行 ...
  • 也许是偶太笨了,嘿嘿,不过还是有点难度的),想恢复动网默认风格,只需替换他原来的图片和CSS样式即可,而很多朋友提供的都是一种新的风格,不是说他不好,而且借此强调,本人风格虽不是原创,但完全是自己修改而...
  • 图文自由转OCR软件

    热门讨论 2012-10-09 12:08:24
    也经过本人再三测试,可以完美运行在XP系统和VISTA、WIN7系统! 开发商意识到它潜在的巨大价值,所以已经不再独立发售软件,而是将这种技术开发了每台500元的名片识别机。可见这款软件和其它同款软件的与众不同。 ...
  • 图文自由转OCR软件_卷2

    热门讨论 2012-10-10 10:16:48
    也经过本人再三测试,可以完美运行在XP系统和VISTA、WIN7系统! 开发商意识到它潜在的巨大价值,所以已经不再独立发售软件,而是将这种技术开发了每台500元的名片识别机。可见这款软件和其它同款软件的与众不同。 ...
  • 枫の网络整站程序

    2006-02-23 09:05:59
    mdb.asp login/conn.asp 调试地址:../../index.asp ===========版本信息=============== 修改版本为:各站此程序大集合 版本名称:枫の网络 版 本 :V8.1 数 据 库:ACCESS 2000 发布日期:2004-03-12 网站地址:...
  • 但作为设计师本人也要仔细思考,先尝试关键部分的内容修改,比如尝试新的字体,去掉多余元素等等。 有一种网站叫大气,有一种大气叫只可意会不可言传……不断的探索和尝试,所有的大气都是浮云。 艺帆房地产置业...
  • 8,安装使用方便,你只需把头部文件top.asp成你的就可以了 后台管理登陆地址:http://你的网站地址/admin/ 后台管理 用户名:admin 密码是:www.oyaya.net -----------------------------------------------------...

空空如也

空空如也

1 2 3 4
收藏数 80
精华内容 32
关键字:

本人换号图片