单片机程序移植到上位机来实现之算法插件的开发

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
同样的道理,在上位机算法插件当中,我们开始执行算法处理这个二维数组之前,我们必须对这个数组进行赋值操作(即把图像数据存放到这个数组当中),然后在执行我们的算法程序即可。
好了,接下来我们就要对这个全局数组变量赋值了,那如何赋值呢?数据从何处来呢?
我们先看一下上位机使用算法插件进行处理的流程:
上位机打开一幅图像
由于pData是一个void类型的指针,我们不能对它直接进行加法或者减法操作。因为我们知道
char型的指针加1的时候,指针其实移动了一个字节。
short型的指针加1的时候,指针其实移动了两个字节。
int型的指针加1的时候,指针其实移动了4个字节。
一个自定义结构体的指针加1的时候,指针其实移动了这个结构体大小的总的字节数。
{
int i=0,j=0;
//该段代码一般不用做任何修改,作用为从上位机取数据填充到ImageData,就如同下位//机的采集程序一样的效果.
for (i= 0;i< IMG_ROWS;i++)
{
for (j = 0;j < IMG_COLS;j++)
{
ImageData[i][j] = *((UCHAR*)pData+i* IMG_COLS +j);
单片机程序移植到上位机来实现
--------之算法插件的开发
第一步:
用VC6.0打开二值化算法插件工程模板目录下的AlgorithmDLL.dsw文件。
(说明:请勿自己建立工程,否则将出现各种错误,切记!)
第二步:
点击菜单栏的----组建----清除。(说明:如果不清除的话,编译连接的时候有可能出现找不到一些文件的奇怪错误。)
-----点击算法插件按钮经过算法插件处理
-----上位机再显示处理后的数据
所以算法插件扮演的是一个中间层,处理上位机提供的图像,然后又送到上位机进行显示。
再看看我们提供的函数参数的意思就可以把上位机显示的图像数据赋值到我们定义的全局二维数组当中了。
具体代码如下:
// w图像宽
// h图像高
// pData指向上位机显示的图像数据的指针
现在我们要指向第i行第j列,我们只要在pData做强制类型转换后再加i* IMG_COLS +j即可。最后在前面加个*就可以读到第i行第j列的数据了。
B:算法移植并把处理后的数据送到上位机显示:
在这里我们举一个最经典的二值化算法样例:
添加算法后的代码如下:
void _stdcall HandleImg(void *pData,ULONG w,ULONG h)
第三步:
点击下图的第2个按钮即可。(说明:第1个按钮为编译,第2个按钮为连接,第三个按钮为执行。在这里我们点击第二个就可以了,因为生成的DLL文件不能单独执行所以不要点击第3个按钮。)
点击第二个按钮后:
在最下面的调试信息中出现AlgorithmDLL.dll - 0 error(s), 0 warning(s)字样,表明已经成功生成DLL算法插件文件了,该文件的位置在工程模板目录下的Debug目录下。(说明:该文件生成的位置可以由我们自己设定,设定生成位置的方法为:点击--工程--设置---连接---分类选择常规--然后在输出文件名那里指定你要生成的目录即可。比如你填上:“D:\算法库\AlgorithmDLL.dll”该路径填写的时候不包括引号部分,那么你点击上图中的第二个按钮连接时就会在D盘下的算法库插件生成AlgorithmDLL.dll文件了。)
}
}
//以下位置为添加算法的地方
unsigned char *p;
for (p = &ImageData[0][0];p < &ImageData[IMG_ROWS-1][IMG_ROWS];p++)
{
if (*p > 120){*p = 255;}
else{*p = 0;}
}
//该段代码一般不用做任何修改,作用为把执行算法处理后把处理后的图像数据送到上位//机显示
下篇教程将讲述:
1.如何动态跟踪算法插件在执行过程当中的变量信息。
2.如何把提取到的中心线或者其他有用的信息保存起来以便查看和分析。
3.如何把提取到的中心线明显的显示到上位机界面上来。
4.如何进行快速调试。
把这三条语句从单片机的程序拷贝到算法插件工程,放到任何函数外面(即花括号外面)也作为全局变量即可。
2.刚才我们已经把图像数组的定义拷贝过来了,现在我们要拷贝的是函数的内容了,法之前呢,我们需要做一些初始化操作,因为我们明白我们的这个算法程序是对ImageData这个图像数组数据进行操作的,在单片机程序(即下位机)当中,这个ImageData数组存放的是我们采集回来的图像数据,并且我们在进行处理之前,这个数组已经存放好图像数据了的。
移植案例:
一、首先给你的算法起个名字:
在下面的函数里面修改算法名称,该名称就是加载到上位机软件后插件按钮显示的名称。
void _stdcall AlgorithmName(char *pName)
{
char *p = "提取";
strcpy(pName,p);
}
比如做了以上的修改,当算法插件加载到上位机软件的时候,插件按钮的名称就会显示“提取”字样。当打开图像,然后点击该按钮时就会执行里面的算法程序,执行完后被处理的效果图将显示在下面的一个框框中了。
而我们的void型的指针加1的时候,编译器就傻了,到底该移动多少字节呢,编译器就无法确定了,这时候你如果还强行编译,那编译器只好跟你说不好意思了,就会报错了。
这时侯必须由我们告诉编译器,对什么类型的指针进行加1或者加n操作,这样才能让编译器不犯傻。
所以在这里我们进行了一个强制类型转化为UCHAR型的指针,因为我们的图像数组数据是UCHAR型的,加1的时候,指针恰好指向下个数据了。
for (i = 0;i < IMG_ROWS;i++)
{
for (j = 0;j < IMG_COLS;j++)
{
*((UCHAR*)pData+i* IMG_COLS +j) = ImageData[i][j];
}
}
}
好了移植一个算法就算是完成了,详情请看模板工程中的代码。
更多调试技巧,请待下篇教程。
第四步:
经过以上步骤我们已经成功生成了算法插件文件了,现在要解决的问题是怎么加载到上位机的问题了。现在我们打开上位机软件,点击左上角的添加算法库,类型可由你自己自定义填写,路径选择到刚才生成算法插件的那个目录选择AlgorithmDLL.dll这个文件即可,或者你也可以直接把AlgorithmDLL.dll这个文件拖入到路径那个地方然后确定即可。(说明:添加成功后,实际上算法插件dll文件被拷贝到了上位机exe文件所在目录下的plugins文件夹下的对应子文件夹下了)。
void _stdcall HandleImg(void *pData,ULONG w,ULONG h)
{
for (inti= 0;i< IMG_ROWS;i++)
{
for (int j = 0;j < IMG_COLS;j++)
{
ImageData[i][j] = *((UCHAR*)pData+i*IMG_COLS+j);
}
}
}
上面的代码已经可以把我们上位机显示的图像数据传到了ImageData这个数组当中了。
在这里我需要解释其中的一行代码:
ImageData[i][j] = *((UCHAR*)pData+i*IMG_COLS+j);
这一行代码的作用是把上位机显示的图像数据的第i行第j列的像素值赋值给ImageData[i][j]
二、开始移植我们的单片机的算法程序到上位机并查看效果:
1.首先需要你拷贝一些全局变量到算法插件工程里面
最经典的就是拷贝一个存放图像数据的二维数组全局变量,还有定义图像行和列的宏定义等。
比如:
#define IMG_ROWS 50
#define IMG_COLS 100
unsigned char ImageData[IMG_ROWS][IMG_COLS];
相关文档
最新文档