1. 问题描述
在机器人运动控制中需要实现室内引导,采用的方案为机器视觉,通过摄像头采集道路信息,识别红色的引导线。实现导航。
2. 开发环境
opencv2.4.9.0 + VS2013 + matlab2014a
3. 设计流程
3.1. 采集图片并保存为jpg图片
3.2. 将图片裁剪为合适的尺寸,本项目中选用的为320*5(RGB888)
3.3. 对图片进行标记。标记出裁剪的图片中的红色引导线的位置。本项目将所有的jpg图片用opencv读出像素值(opencv读出的数据的排列方式为BGR排列,matlab的排列方式为RGB)以后存储为一个文件test_data.yuv,将标记的红色引导线的位置存储为另外一个文件test_data_res.txt。为了简化操作,采用鼠标点击红色线条中心,同时单击右键为删除当前图片,并且将所有的标记图片垂直镜像,让训练数据加倍。最后使用约半个小时标记了1802组数据。
3.4. 使用matlab 的nnstart神经网络工具箱对神经网络进行训练,获取神经元的相关参数。
3.5. 使用matlab 中训练得到的神经网络参数编写神经网络(c语言)。
3.6. 测试识别效果。
以上为设计流程,其中的工作分解涉及到诸多软件工具的编写包括:采集图像程序、图像裁剪程序、标记工具、神经网络等程序。
本博客主要介绍神经网络仿真,导出相关参数,以及编写神经网络函数。
在matlab命令行输入
load('rpic.mat') %加载训练输入数据
load('res.mat') %加载训练目标数据
nnstart %打开神经网络工具箱
进入matlab神经网络工具箱选择Fitting App 选择训练使用的数据
经过测试隐含层选择15个神经元时拟合系数R^2 较接近1 效果较好。
同时平均误差为15个像素
最终导出训练完毕的神经网络函数
打开得到的神经网络函数,将神经网络函数的参数写入头文件。
%创建annparm.h 文件 将神经网络参数写入头文件 方便C程序调用
%将上述得到的神经网络参数拷贝到此处
fid = fopen('annparm.h','w');
fprintf(fid,'#ifndef _ANNPARM_ 1\r\n');
fprintf(fid,'#define _ANNPARM_ 1\r\n');
fwrite(fid,'const float x1_step1_gain[] = {');
fprintf(fid,'%f,',x1_step1_gain);
fprintf(fid,'};\r\n');
fwrite(fid,'const float x1_step1_xoffset[] = {');
fprintf(fid,'%f,',x1_step1_xoffset);
fprintf(fid,'};\r\n');
fwrite(fid,'const float x1_step1_ymin = ');
fprintf(fid,'%f',x1_step1_ymin);
fprintf(fid,';\r\n');
fwrite(fid,'const float b1[] = {');
fprintf(fid,'%f,',b1);
fprintf(fid,'};\r\n');
fwrite(fid,'const float IW1_1[15][4800] = {');
%打印数据为先列后行所以要先把数据转化转置
TIW1_1 = IW1_1';
fprintf(fid,'%f,',TIW1_1);
fprintf(fid,'};\r\n');
fwrite(fid,'const float b2 = ');
fprintf(fid,'%f',b2);
fprintf(fid,';\r\n');
fwrite(fid,'const float LW2_1[] = {');
fprintf(fid,'%f,',LW2_1);
fprintf(fid,'};\r\n');
fwrite(fid,'const float y1_step1_ymin = ');
fprintf(fid,'%f',y1_step1_ymin);
fprintf(fid,';\r\n');
fwrite(fid,'const float y1_step1_gain = ');
fprintf(fid,'%f',y1_step1_gain);
fprintf(fid,';\r\n');
fwrite(fid,'const float y1_step1_xoffset = ');
fprintf(fid,'%f',y1_step1_xoffset);
fprintf(fid,';\r\n');
fprintf(fid,'#endif\r\n');
fclose(fid);
得到了C程序调用的头文件。
根据网络结构写出神经网络函数
/*图像处理神经网络*/
float pb_ann(unsigned char x[INP_LEN])
{
int i,j;
double x1[INP_LEN] = {0};
double a[HID_LEN] = {0};
double a2 = 0;
double temp;
/*输入层*/
for (i = 0; i < INP_LEN; i++)
{
x1[i] = x[i] - x1_step1_xoffset[i];
}
for (i = 0; i < INP_LEN; i++)
{
x1[i] = x1[i] * x1_step1_gain[i] + x1_step1_ymin;
}
/*layer 1*/
for (i = 0; i < HID_LEN; i++)
{
temp = 0;
for (j = 0; j < INP_LEN; j++)
{
temp = temp + x1[j] * IW1_1[i][j] ;
}
a[i] = temp + b1[i];
/*传输函数*/
a[i] = 2.0 / (1.0 + exp(-2.0 * a[i])) - 1.0;
}
/*输出层*/
for (i = 0; i < HID_LEN; i++)
{
a2 = a[i] * LW2_1[i] + a2;
}
a2 = a2 + b2;
a2 = a2 - y1_step1_ymin;
a2 = a2 / y1_step1_gain;
a2 = a2 + y1_step1_xoffset;
return a2;
}
至此神经网络识别完成,相关源代码见链接
测试结果视频链接:http://v.youku.com/v_show/id_XMzQ0ODU3OTYzMg==.html?spm=a2h3j.8428770.3416059.1
程序源码链接:https://download.csdn.net/download/u014070258/10276308
程序源码包括
本人E-mail: deamonyang@foxmail.com