opencv計算機視覺學習筆記八

轉載自https://blog.csdn.net/retacn_yue/article/details/53726481
第九章 基於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 = “[email protected]

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 = “[email protected]

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()

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章