1、隐藏节点:60
训练样本:50000
阶段:10
import gzip
import pickle
import cv2
import numpy as np
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)
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)
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)
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
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
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))
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、导包
import cv2
import numpy as np
import digits_ann
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)
选择每个数字最外层的边框
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)
4、在四周添加5个像素
padding=5
x-=padding
y-=padding
w+=2*padding
h+=2*padding
此时,修改的矩形可能会延申到图像外部
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
6、返回修改后的矩形代码
return x,y,w,h
7、主程序:创建人工神经网络,在MNIST数据集上对其训练
nn,test_data=digits_ann.train(digits_ann.create_ann(60),50000,10)
60隐藏节点,50000训练样本,10阶段
8、加载测试图像
img_path="./digit_images/digits_0.jpg"
img=cv2.imread(img_path,cv2.IMREAD_COLOR)
9、把图像转换为灰度图像并进行模糊,以去噪声,使墨水的颜色均匀一点
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
cv2.GaussianBlur(gray,(7,7),0,gray)
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)
cv2.THRESH_BINARY_INV:逆二值阈值
数据集是黑底白字
11、形态学运算过后,分别检测图片中的每个数字,首先找到轮廓
contours,hier=cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
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)
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])
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)
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、激活函数
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
2、加载caffe模型
model=cv2.dnn.readNetFromCaffe('objects_data/MobileNetSSD_deploy.prototxt',
"objects_data/MobileNetSSD_deploy.caffemodel")
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)
4、定义置信度阈值,表示所需要的最小置信度
confidence_threshold=0.5
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'
]
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)
7、预处理(调整帧的大小,将像素数据转换到-1.0~1.0
blod=cv2.dnn.blodFromImage(frame,scalefactor=color_scale,size=blod_size,mean=average_color)
8、将生成的二进制大对象(blod)送入深度神经网络,并获得模型的输出
model.setInput(blod)
results=model.forward()
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]
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)
11、显示
按下ESc:退出
否则:采集另一帧,继续循环下一次迭代
cv.imshow('Objects',frame)
k=cv2.waitKey(1)
if k==27:#Escape
break
success,frame=cap.read()
基于第三方深度神经网络的人脸检测和分类