图像处理基础知识

来源:互联网 发布:科大讯飞 阿里云 编辑:程序博客网 时间:2024/05/16 00:50

     @DavidHan,
    http://blog.csdn.net/David_Han008/article/details/78883641

前言
最近这段时间,导师这边有个人脸识别做跟随移动的机器人,想利用这个机会总结一些关于图像处理的基础知识
实践部分
这部分,主要写利用ROS在phil333的代码基础上,添加了跟随功能,以及解决,多级控制的的方法,来实现安卓控制和人脸跟随的两个级别的控制。
原作者的github:点击这里
用法:打开摄像头之后,直接roslaunch face_detection face_tracking.launch 就可以了。 在使用的时候,会遇到face_tracking的包的话题,没办法映射,因此应该在cfg当中修改。如下图所示:
这里写图片描述
原作者代码解析:
1、 在发布图像方面:
phil333默认的初值是0也就是不发布图像,但是我们需要发布图像,因此这个地方应该设置成3
这里写图片描述
在发布的msg当中,作者已经通过 std_msgs::Int32MultiArray 这个数据,将所有的数据存储下来,数据第0位:帧率。第1位:图片当中脸的个数。第2位:图像列数,第3位:图像的行数,第4位,脸的ID 第5位,框住同一张脸的数量。第6位,框的左上角x,第7位,框右上角y,第8位,框的宽度,第9位,框的高度。这个设计真的很贴心,而且最后在发布topic的时候,也可以产生compress压缩图像的topic ,这样我就可以通过手机来订阅这个图像。从而在安卓手机上显示,最后我吧我修改后的代码上传到github上面。
2、opencv测试版本
还需要注意的一点是,安装的opencv版本是2.4.13的版本,上是通过的,如果cv_bridge没有找到opencv的安装的位置的话,就将整个/usr/local/include/openc和/usr/local/include/opencv2 复制到/usr/include/opencv /usr/include/opencv2,使用的命令是cp -r
添加人脸跟随左转右转
添加的原理:
这里写图片描述
原作者的msg已经提供我们需要使用的量。我们使用的,就是x,框的width,以及图像的cols(列数),我们可以通过x+width/2来求出图像中心的位置,通过质心的位置,判断质心是否超过我们设置的阈值,然后来来发布速度。这里发布速度的频率是是根据帧率来确定的。也就是你没是被一张图片,发现他是一张人脸,然后在这张上面画一个框,,提取出框的坐标,来发布左转或者右转的命令。
最后为了防止,当图像中没有脸的时候,我们利用上面的msg进行判断,如果没有脸的时候,发布速度是0.
解决遥控和人脸识别控制的优先级问题
问题简述:

这里写图片描述
解决问题的总体的思路:
如何判断,是否有安卓手机发布的速度值
尝试过的解决方案:
1、通过nodename来判断
刚开始的时候,也尝试过利用Mux来进行优先级,进行设置。也尝试股哟,来判断订阅一个node的名字,判断时候有这个节点的名字,但是这种方案,有个不好的时候,就是当你的安卓app退出之后,这个节点的名字仍然存在,在使用getsubscriberNumber,也查阅了相关API,但是反馈的数值一直不是很准确,姑此方案舍弃
2、通过mux来判断
mux,感觉挺复杂的,看了wiki的介绍,感觉理解需要一些时间,我尝试过,采用两个topic,最后映射成一个topic,感觉意义不大,姑此方案舍弃
3、通过订阅这个话题,然后来判断是否需要数据替换。
这种方案测试成功:
大体的思路:
这里写图片描述
代码逻辑框图:
这里写图片描述
核心代码:

//这里的image.cols*image*row是640*480//printf("faces[0].x:%d",faces[1].x); /*如果没有框的时候,也就是data=0的时候,发布速度是0如果有框的data的时候,发布速度是+如果data*/double j_people_num,j_b_x,j_b_width,j_p_width,OFFSET;j_people_num=myMsg.data[1];//人的个数j_b_x=myMsg.data[6];//xj_b_width=myMsg.data[8]/2;//B一半宽j_p_width=myMsg.data[2]/2;//P一半宽OFFSET=50;//范围//std::cout<<"j_b_x+j_b_width:"<<j_b_x+j_b_width<<"j_p_width+OFFSET"<<j_p_width+OFFSET<<std::endl;//std::cout<<"twi.angular.z="<<twi.angular.z<<std::endl;//如果这两组数据都不存在,那么进行下面的步骤twi.linear.x=joy_twi.linear.x;twi.angular.z=joy_twi.angular.z;if((joy_twi.angular.z==0)&&(joy_twi.linear.x==0))//如果说,是joy=0{//进行图像判断if (j_people_num==0){ twi.angular.z=0;}if (j_people_num>0){  if((j_b_x+j_b_width)<=(j_p_width+OFFSET)&&(j_b_x+j_b_width)>=(j_p_width-OFFSET))   {    twi.angular.z =0;   }   if((j_b_x+j_b_width)<(j_p_width-OFFSET))   {   twi.angular.z=0.6;   }   if((j_b_x+j_b_width)>(j_p_width+OFFSET))   {   twi.angular.z=-0.6;   }}//joy_twi.angular.z=twi.angular.z;//进行数据替换//joy_twi.linear.x=twi.linear.x;}veb_pub_.publish(twi);//发twi

具体的代码,详见github。