• 基于人工神经网络识别手写数字


    1、隐藏节点:60
    训练样本:50000
    阶段:10

    import gzip
    import pickle
    import cv2
    import numpy as np
    
    • 1
    • 2
    • 3
    • 4

    2 training_images:numpy 数组,由6000副图像组成,其中每幅图像都是由784个像素值组成的向量(从28×28像素的原始形状展平而来)
    像素值:0.0(黑)~1.0(白)的浮点值
    3 training_ids:numpy 数组,包含60000个数字ID
    4 test_images:1000幅图像组成的numpy数组,每幅图像都是由784个像素值组成的向量(从原始28×28组成)
    5 test_ids:numpy 数组 10000个数字ID
    6编写辅助函数

    def load_data():
        mnist=gzip.open('./digits_data/mnist.pkl.gz','rb')
        training_data,test_data=pickle.load(mnist)
        mnist.close()
        return (training_data,test_data)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    7重新格式化原始数据,以匹配opencv所期望的格式
    zip:以元组形式遍历输入和输出向量的匹配对

    def wrap_data():
        tr_d,te_d=load_data()
        training_inputs=tr_d[0]
        trainging_results=[vectorized_result(y) for y in tr_d[1])
        trainging_data=zip(training_inputs,trainging_results)
        test_data=zip(te_d[0],te_d[1])
        return (trainging_data,test_data)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    8将ID转换为一个分类向量

    def wrap_data():
        tr_d,te_d=load_data()
        training_inputs=tr_d[0]
        trainging_results=[vectorized_result(y) for y in tr_d[1])
        trainging_data=zip(training_inputs,trainging_results)
        test_data=zip(te_d[0],te_d[1])
        return (trainging_data,test_data)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    9、创建未训练的人工神经网络

    def create_ann(hidden_nodes=60):
        ann=cv2.m1.ANN_MLP_create()
        ann.setLayerSizes(np.array([784,hidden_nodes,10]))
        ann.setActivationFunction(cv2.m1.ANN_MLP_SIGMOID_SYM,0.6,1.0)
        ann.setTrainMethod(cv2.m1.ANN_MLP_BACKPROP,0.1,0.1)
        ann.setTermCriteria(cv2.TERM_CRITERIA_MAX_ITER| cv2.TERM_CRITERIA_EPS,100,1.0)
        return ann
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    10、训练函数

    def train(ann,samples=50000,epochs=10):
        tr,test=wrap_data()
        tr=list(tr)
        for epoch in range(epochs):
            print("Completed %d/%d epochs" % (epoch,epochs))
            counter=0
            for  img in tr:
                if(counter>samples):
                    break;
                if(counter%1000==0):
                    print("Epoch %d: Trained on %d/%d samples" %\ (epoch,counter,samples))
                    counter+=1
                    samples,response=img
                    data=cv.m1.ANN_MLP_createTrainData_create(np.array([sample],dtype=np.float32),cv2.ma.ROW_SAMPLE,
                                                              np.array([response],dtype=np.float32))
                    if ann.isTrained():
                        ann.train(data,cv2.m1.ANN_MLP_UPDATE_WEIGHTS |
                                cv2.m1.ANN_MLP_NO_INPUT_SCALE|cv2.m1.ANN_MLP_NO_OUTPUT_SCALE)
                    else:
                        ann.train(data,cv2.m1.ANN_MLP_NO_OUTPUT_SCALE|
                                  cv2.m1.ANN_MLP_NO_INPUT_SCALE)
                        print("Completed all epochs!")
                        
                        return ann,test
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    11预测

    def predict(ann,sample):
        if sample.shape!=(784,):
            if sample.shape !=(28,28):
                sample=cv2.resize(sample,(28,28),interpolation=cv2.INTER_LINEAR)
            sample=sample.reshape(784,)
        return ann.predict(np.array([sample],dtype=np.float32))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    12测试
    def tedt(ann,test_data): num_tests=0 num_correct=0 for img in test_data: num_tests+=1 sample,correct_digit_class=img digit_class=predict(ann,sample)[0] if digit_class==correct_digit_class: num_correct+=1 print("Accuracy:%.2f%%"%(100.0*num_correct/num_tests))

    13、运行脚本

    from digits_ann import create_ann,train,test
    ann,test_data=train(create_ann())
    test(ann,test_data)
    
    • 1
    • 2
    • 3

    实现主模块
    1、导包

    import cv2
    import numpy as np
    import digits_ann
    
    • 1
    • 2
    • 3

    2、编写2个辅助函数

    def inside(r1,r2):
        x1,y1,w1,h1=r1
        x2,y2,w2,h2=r2
        return (x1>x2)and (y1>y2)and (x1+w1<x2+w2)and \(y1+h1<y2+h2)
    
    • 1
    • 2
    • 3
    • 4

    选择每个数字最外层的边框
    3、修改矩形的较短边(不管是宽还是高),使其等于较长的边,修改矩形的x或y位置,使宗信保持不变

    def warp_digit(rect,img_w,img_h):
        x,y,w,h=rect
    x_center=x+w//2
    y_center=y+h//2
    if(h>w):
        w=h
        x=x_center-(w//2)
    else:
        h=w
        y=y_center-(h//2)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    4、在四周添加5个像素

    padding=5
    x-=padding
    y-=padding
    w+=2*padding
    h+=2*padding
    
    • 1
    • 2
    • 3
    • 4
    • 5

    此时,修改的矩形可能会延申到图像外部
    5、为避免越界问题,裁剪矩形使矩形完全位于图像内,下面是边缘检查和裁剪矩形的代码:

    if x<0:
        x=0
    elif x>img_w:
        x=img_w
    if y<0:
        y=0
    elif y>img_h:
        y=img_h
    if x+w>img_w:
        w=img_w-x
    if y+h>img_h:
        h=img_h-y
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    6、返回修改后的矩形代码

    return x,y,w,h
    
    • 1

    7、主程序:创建人工神经网络,在MNIST数据集上对其训练

    nn,test_data=digits_ann.train(digits_ann.create_ann(60),50000,10)
    
    • 1

    60隐藏节点,50000训练样本,10阶段
    8、加载测试图像

    img_path="./digit_images/digits_0.jpg"
    img=cv2.imread(img_path,cv2.IMREAD_COLOR)
    
    • 1
    • 2

    9、把图像转换为灰度图像并进行模糊,以去噪声,使墨水的颜色均匀一点

    gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    cv2.GaussianBlur(gray,(7,7),0,gray)
    
    • 1
    • 2

    10、阈值、形态学运算:确保数字从背景中脱颖而出

    ret,thresh=cv2.threshold(gray,127,255,cv2.THRESH_BINARY_INV)
    erode_kernel=np.ones((2,2),np.uint8)
    thresh=cv2.erode(thresh,erode_kernel,thresh,iterations=2)
    
    
    • 1
    • 2
    • 3
    • 4

    cv2.THRESH_BINARY_INV:逆二值阈值
    数据集是黑底白字
    11、形态学运算过后,分别检测图片中的每个数字,首先找到轮廓

    contours,hier=cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
    
    • 1

    12\遍历轮廓找到矩形框。丢弃所有太大或太小而不能视为数字的矩形,同时丢弃所有完全包含在其他矩形中的矩形。
    把其他矩形添加到好的矩形列表中

    rectangles=[]
    img_h,img_w=img.shape[:2]
    img_area=img_w*img_h
    for c in contours:
        a=cv2.contourArea(c)
        if a>=0.98 *img_area or a<=0.0001*img_area:
            continue
        r=cv2.boundingRect()
        is_inside=False
        for q in rectangles:
            if inside(r,q):
                is_inside=True
                break
        if not is_inside:
            rectangles.append(r)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    13、对该列表清理,并对图像数据分类

    for r in rectangles:
        x,y,w,h=wrap_digit(r,img_w,img_h)
        roi=thresh[y:y+h,x:x+w]
        digit_class=int(digits_ann.predict(ann,roi)[0])
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    14、对每个数字分类后,绘制经过清理的矩形框及分类结果

    cv2.rectangles(img,(x,y),(x+w,y+h),(0,255,0),2)
    cv2.putText(img,"%d"%digit_class,(x,y-5),cv2.FONT_HERSHEY_SIMPLEX,1,(255,0,0),2)
    
    • 1
    • 2

    15、保存图像,指导用户按下任意键结束程序

    cv2.imwrite("detected_and_classified_digits_thresh.png",thresh)
    cv2.imwrite("detected_and_classified_digits.png",img)
    cv2.imshow("thresh",thresh)
    cv2.imshow("detected_and_classified_digits",img)
    cv2.waitKey()
    
    • 1
    • 2
    • 3
    • 4
    • 5

    总结:
    1、激活函数
    cv2.m1.ANN_MLP_SIGMOID_SYM
    cv2.m1.ANN_MLP_IDENTITY
    cv2.m1.ANN_MLP_GAUSSIAN
    cv2.m1.ANN_MLP_RELU
    cv2.m1.ANN_MLP_LEAKYRELU
    2\训练方法
    cv2.m1.ANN_MLP_BACKPROP
    cv2.m1.ANN_MLP_RPROP
    cv2.ma.ANN_MLP_ANNEAL

    从网络摄像头实时捕捉帧,使用深度神经网络检测和分类任何给定帧中存在的20类物体
    1导包

    import  cv2
    import numpy as np
    
    • 1
    • 2

    2、加载caffe模型

    model=cv2.dnn.readNetFromCaffe('objects_data/MobileNetSSD_deploy.prototxt',
                                   "objects_data/MobileNetSSD_deploy.caffemodel")
    
    • 1
    • 2

    3、定义预处理参数
    期望输入的图像300个像素,希望像素值在-1.0~1.0。即相对于通常从0到255范围内,需要减去127.5,再除以127.5

    bold_height=300
    color_scale=1.0/127.5
    average_color=(127.5,127.5,127.5)
    
    • 1
    • 2
    • 3

    4、定义置信度阈值,表示所需要的最小置信度

    confidence_threshold=0.5
    
    • 1

    5、类的标签:

    labels=['airplane','bicycle','bird','boat','bottle','bus','car','cat','chair','cow','dining table',
            'dog','horse','motoebike','person','potted plant','sheep','sofa','train','TV or monitor'
            ]
    
    • 1
    • 2
    • 3

    6、每一帧:计算长宽比,

    cap=cv.VideoCapture(0)
    success,frame=cap.read()
    while success:
        h,w=frame,shape[:2]
        aspect_radio=w/h
        
        bold_width=int(blod__height*aspect_radio)
        bold_size=(bold_width,blod__height)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    7、预处理(调整帧的大小,将像素数据转换到-1.0~1.0

    blod=cv2.dnn.blodFromImage(frame,scalefactor=color_scale,size=blod_size,mean=average_color)
    
    • 1

    8、将生成的二进制大对象(blod)送入深度神经网络,并获得模型的输出

    model.setInput(blod)
    results=model.forward()
    
    • 1
    • 2

    9、访问标签,使用id查找之前定义的列表中的标签

    for object in results[0,0]:
        confidence=object[2]
        if confidence>confidence_threshold:
            x0,y0,x1,y1=(object[3:7]*[w,h,w,h]).astype(int)
            id=int(object[1])
            label=labels[id-1]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    10、访问检测到的物体时:绘制检测矩形以及分类标签和置信度

    cv2.rectangle(frame,(x0,y0),(x1,y1),(255,0,0),2)
    text='%s(%.1f%%)'%(label,confidence*100.0)
    cv2.putText(frame,text,(x0,y0-20),cv2.FONT_HERSHEY_SIMPLEX,1,(255,0,0),2)
    
    • 1
    • 2
    • 3

    11、显示
    按下ESc:退出
    否则:采集另一帧,继续循环下一次迭代

    cv.imshow('Objects',frame)
    
    k=cv2.waitKey(1)
    if k==27:#Escape
        break
    success,frame=cap.read()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    基于第三方深度神经网络的人脸检测和分类

  • 相关阅读:
    springcloudalibaba架构(11):Sentinel规则持久化至Nacos
    【GraphQL】使用Hot Chocolate和.NET 6构建GraphQL应用
    12.Gateway新一代网关
    JS逆向实战19——通杀webpack逆向
    java基础讲义03
    更改Kali Linux系统语言以及安装zenmap
    技巧分享:简单的流程图怎么作?
    Linux 查看是否安装memcached
    机器学习基本知识(2)
    如何让Redis和mysql数据保持数据一致?
  • 原文地址:https://blog.csdn.net/zengdanli/article/details/126202983