zoukankan      html  css  js  c++  java
  • opencv计算机视觉学习笔记八

    第九章 基于opencv的神经网络简介

    1 人工神精网络ann

    2 人工神精网络的结构

    输入层

    网络的输入数目

    如动物有体重,长度,牙齿三个属性,网络则需要三个输入节点

    中间层

    输出层

    与定义的类别数相同,如定义了猪,狗,猫,鸡,则输出层的数目为4

    创建ANN常见规则

    神经元数 位于输入/输出层之间, 接近输出层

    较小的输入,神经元数=(输入+输出)/3*2

    学习算法:

    监督学习

    非监督学习

    强化学习

    3 opencv中的ann

    示例代码如下:

    
    import cv2
    import numpy as np
    
    # 创建ann,MLP 是multilayer perceptron 感知器
    ann = cv2.ml.ANN_MLP_create()
    # 设置拓扑结构,通过数组来定义各层大小,分别对应输入/隐藏/输出
    ann.setLayerSizes(np.array([9, 5, 9], dtype=np.uint8))
    # 采用反向传播方式,还有一种方式ANN_MLP_RPROP,只有在有监督学习中才可以设置
    ann.setTrainMethod(cv2.ml.ANN_MLP_BACKPROP)
    
    # 有点类似于向量机svm的 train函数
    ann.train(np.array([[1.2, 1.3, 1.9, 2.2, 2.3, 2.9, 3.0, 3.2, 3.3]], dtype=np.float32)# 对应9个输入数据
              cv2.ml.ROW_SAMPLE# 如果提供以下几个参数就是有监督学习
              np.array([[0, 0, 0, 0, 0, 1, 0, 0, 0]], dtype=np.float32))  # 输出层大小为9
    print(ann.predict(np.array([[1.4, 1.5, 1.2, 2., 2.5, 2.8, 3., 3.1, 3.8]], dtype=np.float32)))
    
    # 输出结果为:
    # (5.0, #类标签
    #  array([[-0.06419383, -0.13360272, -0.1681568 , -0.18708915,  0.0970564 ,  #输入数据属于每个类的概率
    #        0.89237726,  0.05093023,  0.17537238,  0.13388439]], dtype=float32))

    基于ann的动物分类

    示例代码如下:

    
    import cv2
    import numpy as np
    from random import randint
    
    # 创建ann
    animals_net = cv2.ml.ANN_MLP_create()
    # 设定train函数为弹性反向传播
    animals_net.setTrainMethod(cv2.ml.ANN_MLP_RPROP | cv2.ml.ANN_MLP_UPDATE_WEIGHTS)
    animals_net.setActivationFunction(cv2.ml.ANN_MLP_SIGMOID_SYM)
    # 设置拓扑结构,通过数组来定义各层大小,分别对应输入/隐藏/输出
    animals_net.setLayerSizes(np.array([3, 8, 4]))
    # 指定ann的终止条件
    animals_net.setTermCriteria((cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1))
    
    """
    输入数组
    weight, length, teeth
    """
    """
    输出数组 狗 膺 海豚 龙
    dog,eagle,dolphin and dragon
    """
    
    
    def dog_sample():
        return [randint(5, 20), 1, randint(38, 42)]
    
    
    def dog_class():
        return [1, 0, 0, 0]
    
    
    def eagle_sample():
        return [randint(3, 13), 3, 0]
    
    
    def eagle_class():
        return [0, 1, 0, 0]
    
    
    def dolphin_sample():
        return [randint(30, 190), randint(5, 15), randint(80, 100)]
    
    
    def dolphin_class():
        return [0, 0, 1, 0]
    
    
    def dragon_sample():
        return [randint(1200, 1800), randint(15, 40), randint(160, 180)]
    
    
    def dragon_class():
        return [0, 0, 0, 1]
    
    
    
    
    
    """
    # 创建四类动物数据,每类5000个样本
    SAMPLE = 5000
    for x in range(0, SAMPLE):
        print("samples %d/%d" % (x, SAMPLE))
        animals_net.train(np.array([dog_sample()], dtype=np.float32),
                          cv2.ml.ROW_SAMPLE,
                          np.array([dog_class()], dtype=np.float32))
    
        animals_net.train(np.array([eagle_sample()], dtype=np.float32),
                          cv2.ml.ROW_SAMPLE,
                          np.array([eagle_class()], dtype=np.float32))
    
        animals_net.train(np.array([dolphin_sample()], dtype=np.float32),
                          cv2.ml.ROW_SAMPLE,
                          np.array([dolphin_class()], dtype=np.float32))
    
        animals_net.train(np.array([dragon_sample()], dtype=np.float32),
                          cv2.ml.ROW_SAMPLE,
                          np.array([dragon_class()], dtype=np.float32))
    
    print(animals_net.predict(np.array([dog_sample()], dtype=np.float32)))
    print(animals_net.predict(np.array([eagle_sample()], dtype=np.float32)))
    print(animals_net.predict(np.array([dolphin_sample()], dtype=np.float32)))
    print(animals_net.predict(np.array([dragon_sample()], dtype=np.float32)))
    # 输出结果
    # (1.0, array([[ 1.49817729,  1.60551953, -1.56444871, -0.04313202]], dtype=float32))
    # (1.0, array([[ 1.49817729,  1.60551953, -1.56444871, -0.04313202]], dtype=float32))
    # (1.0, array([[ 1.49817729,  1.60551953, -1.56444871, -0.04313202]], dtype=float32))
    # (1.0, array([[ 1.42620921,  1.5461663 , -1.4097836 ,  0.07277301]], dtype=float32))
    """
    
    # 训练周期
    def record(sample, classification):
        return (np.array([sample], dtype=np.float32), np.array([classification], dtype=np.float32))
    
    records = []
    RECORDS = 5000
    for x in range(0, RECORDS):
        records.append(record(dog_sample(), dog_class()))
        records.append(record(eagle_sample(), eagle_class()))
        records.append(record(dolphin_sample(), dolphin_class()))
        records.append(record(dragon_sample(), dragon_class()))
    
    EPOCHS = 2
    for e in range(0, EPOCHS):
        print("Epoch %d:" % e)
        for t, c in records:
            animals_net.train(t, cv2.ml.ROW_SAMPLE, c)
    
    TESTS = 100
    dog_results = 0
    for x in range(0, TESTS):
        clas = int(animals_net.predict(np.array([dog_sample()], dtype=np.float32))[0])
        print("class: %d" % clas)
        if (clas) == 0:
            dog_results += 1
    eagle_results = 0
    for x in range(0, TESTS):
        clas = int(animals_net.predict(np.array([eagle_sample()], dtype=np.float32))[0])
        print("class: %d" % clas)
        if (clas) == 1:
            eagle_results += 1
    
    dolphin_results = 0
    for x in range(0, TESTS):
        clas = int(animals_net.predict(np.array([dolphin_sample()], dtype=np.float32))[0])
        print("class: %d" % clas)
        if (clas) == 2:
            dolphin_results += 1
    
    dragon_results = 0
    for x in range(0, TESTS):
        clas = int(animals_net.predict(np.array([dragon_sample()], dtype=np.float32))[0])
        print("class: %d" % clas)
        if (clas) == 3:
            dragon_results += 1
    
    print("Dog accuracy: %f%%" % (dog_results))
    print("condor accuracy: %f%%" % (eagle_results))
    print("dolphin accuracy: %f%%" % (dolphin_results))
    print("dragon accuracy: %f%%" % (dragon_results))
    
    # 输出结果如下:
    # Dog accuracy: 0.000000%
    # condor accuracy: 0.000000%
    # dolphin accuracy: 0.000000%
    # dragon accuracy: 50.000000%

    4 用人工神精网络进行手写数字识别

    手写数字数据库,下载地址

    http://yann.lecun.com/exdb/mnist

    迷你库

    #!/usr/bin/env python

    # -*- coding: utf-8 -*-

    # @Time   : 2016/12/17 10:44

    # @Author : Retacn

    # @Site   : opencv ann 手写数字识别

    # @File   : digits_ann.py

    # @Software: PyCharm

    __author__ = "retacn"

    __copyright__ = "property ofmankind."

    __license__ = "CN"

    __version__ = "0.0.1"

    __maintainer__ = "retacn"

    __email__ = "zhenhuayue@sina.com"

    __status__ = "Development"

    import cv2

    import pickle

    import numpy as np

    import gzip

    def load_data():

       mnist = gzip.open('./data/mnist.pkl.gz', 'rb')

       training_data, classification_data, test_data = pickle.load(mnist,encoding='latin1')

       mnist.close()

       return (training_data, classification_data, test_data)

    def wrap_data():

       tr_d, va_d, te_d = load_data()

       training_inputs = [np.reshape(x, (784, 1)) for x in tr_d[0]]

       training_results = [vectorized_result(y) for y in tr_d[1]]

       training_data = zip(training_inputs, training_results)

       validation_inputs = [np.reshape(x, (784, 1)) for x in va_d[0]]

        validation_data = zip(validation_inputs,va_d[1])

       test_inputs = [np.reshape(x, (784, 1)) for x in te_d[0]]

       test_data = zip(test_inputs, te_d[1])

       return (training_data, validation_data, test_data)

    # 给出类标签,创建10个元素的0数组

    # 参数j表示要置1的位置

    def vectorized_result(j):

        e= np.zeros((10, 1))

       e[j] = 1.0

       return e

    # 创建ann

    def create_ANN(hidden=20):

       ann = cv2.ml.ANN_MLP_create()

        #设置各层大小

       ann.setLayerSizes(np.array([784, hidden, 10]))

        #采用反向传播方式

       ann.setTrainMethod(cv2.ml.ANN_MLP_RPROP)

       ann.setActivationFunction(cv2.ml.ANN_MLP_SIGMOID_SYM)

        #指定ann的终止条件

       ann.setTermCriteria((cv2.TERM_CRITERIA_EPS | cv2.TermCriteria_COUNT, 20,1))

       return ann

    # 训练函数

    def train(ann, samples=10000, epochs=1):

       tr, val, test = wrap_data()

       for x in range(epochs):

           counter = 0

           for img in tr:

               if (counter > samples):

                    break

               if (counter % 1000 == 0):

                    print("Epoch %d: Trained%d/%d " % (x, counter, samples))

               counter += 1

               data, digit = img

               # ravel()将多维数组拉平为一维

               ann.train(np.array([data.ravel()], dtype=np.float32),

                          cv2.ml.ROW_SAMPLE,

                          np.array([digit.ravel()],dtype=np.float32))

           print('Epoch %d complete' % x)

       return ann, test

    # 检查神精网络工作

    def test(ann, test_data):

       sample = np.array(test_data[0][0].ravel(), dtype=np.float32).reshape(28,28)

       cv2.imshow("sample", sample)

       cv2.waitKey()

       print(ann.predict(np.array([test_data[0][0].ravel()],dtype=np.float32)))

    def predict(ann, sample):

       resized = sample.copy()

       rows, cols = resized.shape

       if (rows != 28 or cols != 28) and rows * cols > 0:

           resized = cv2.resize(resized, (28, 28), interpolation=cv2.INTER_CUBIC)

       return ann.predict(np.array([resized.ravel()], dtype=np.float32))

    if __name__ == "__main__":

       pass

    # print(vectorized_result(2))

     

    #!/usr/bin/env python

    # -*- coding: utf-8 -*-

    # @Time   : 2016/12/17 11:35

    # @Author : Retacn

    # @Site   : 识别手写数字图像

    # @File   : digits_image.py

    # @Software: PyCharm

    __author__ = "retacn"

    __copyright__ = "property ofmankind."

    __license__ = "CN"

    __version__ = "0.0.1"

    __maintainer__ = "retacn"

    __email__ = "zhenhuayue@sina.com"

    __status__ = "Development"

    import cv2

    import numpy as np

    import Nine.digits_ann as ANN

    # 确定矩形是否完全包含在另一个中

    def inside(r1, r2):

       x1, y1, w1, h1 = r1

       x2, y2, w2, h2 = r2

       if (x1 > x2) and (y1 > y2) and (x1 + w1 < x2 + w2) and (y1 + h1< y2 + h2):

           return True

       else:

           return False

    # 取得数字周围矩形,将其转换为正方形

    def wrap_digit(rect):

       x, y, w, h = rect

       padding = 5

       hcenter = x + w / 2

       vcenter = y + h / 2

       if (h > w):

           w = h

           x = hcenter - (w / 2)

       else:

           h = w

           y = vcenter - (h / 2)

       return (int(x - padding), int(y - padding), int(w + padding), int(h +padding))

    # 创建神经网络,中间层为58,训练50000个样本

    ann, test_data =ANN.train(ANN.create_ANN(100), 50000,30)

    font = cv2.FONT_HERSHEY_SIMPLEX

    # 读入图像

    PATH = './image/numbers.jpg'

    # PATH = './image/MNISTsamples.png'

    img = cv2.imread(PATH,cv2.IMREAD_UNCHANGED)

    # 更换颜色空间

    bw = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # 高斯模糊

    bw = cv2.GaussianBlur(bw, (7, 7), 0)

    # 设置阈值

    ret, thbw = cv2.threshold(bw, 127, 255,cv2.THRESH_BINARY_INV)

    # 腐蚀

    thbw = cv2.erode(thbw, np.ones((2, 2),np.uint8), iterations=2)

    # 查找轮廓

    image, cntrs, hier =cv2.findContours(thbw.copy(),  # 源图像

                                         cv2.RETR_TREE,  # 模式为查询所有

                                         cv2.CHAIN_APPROX_SIMPLE)  # 查询方法

    rectangles = []

    for c in cntrs:

        r= x, y, w, h = cv2.boundingRect(c)

        a= cv2.contourArea(c)

        b= (img.shape[0] - 3) * (img.shape[1] - 3)

       is_inside = False

       for q in rectangles:

           if inside(r, q):

               is_inside = True

               break

       if not is_inside:

           if not a == b:

               rectangles.append(r)

    # 向预测函数伟递正方形区域

    for r in rectangles:

       x, y, w, h = wrap_digit(r)

        #绘制矩形

        cv2.rectangle(img, (x, y), (x + w, y + h), (0,255, 0), 2)

        #取得部分图像

       roi = thbw[y:y + h, x:x + w]

       try:

           digit_class = int(ANN.predict(ann, roi.copy())[0])

       except:

           continue

       cv2.putText(img, '%d' % digit_class, (x, y - 1), font, 1, (0, 255, 0))

    cv2.imshow("thbw", thbw)

    cv2.imshow("contours", img)

    cv2.imwrite('./image/sample.jpg', img)

    cv2.waitKey()

  • 相关阅读:
    Java 模板权重随机
    Linux java 启动脚本
    Resin Thread Dump
    Spring Cloud微服务实战 打造企业级优惠券系统 7-17 模板微服务网关路由配置定义
    Spring Cloud微服务实战 打造企业级优惠券系统 6-6 阶段总结 【优惠券系统业务思想与架构总结】
    Spring Cloud微服务实战 打造企业级优惠券系统 6-5 架构设计
    Spring Cloud微服务实战 打造企业级优惠券系统 5-5 阶段练习题
    Spring Cloud微服务实战 打造企业级优惠券系统 5-4 阶段说明[微服务通用模块说明]
    Spring Cloud微服务实战 打造企业级优惠券系统 5-3 统一异常代码编写
    Spring Cloud微服务实战 打造企业级优惠券系统 5-2 统一响应代码编写
  • 原文地址:https://www.cnblogs.com/retacn-yue/p/6194150.html
Copyright © 2011-2022 走看看