物体检测的方法有很多,现在主流的方法有光流法、背景查分法、帧间差分法,它们各有各的优缺点;为了计算方便和同时能够检测
到多个物体,这里使用的是背景差分法;
物体检测的步骤大致可分为下面几个部分:高斯滤波器->差值->二值化->边缘检测->逼近矩阵->显示;
要在android系统上实现这些方法可以自己写,但是用到的for循环或其他循环都会浪费很多的时间,从而不利于实时检测;所以这里是
使用了opencv3.0提供的库函数来实现的。
1、高斯滤波器
Imgproc.GaussianBlur(background,background,new Size(5.0,5.0),1.5);
它的作用是用来使得输入的图像变得更加平滑些,有利于减少检测时引入的误差;
2、差值
Core.absdiff(background,mGray,ss);
它的作用是将当前帧和背景帧矩阵相减然后取绝对值并存储在ss矩阵中;
3、二值化
Imgproc.threshold(ss,ss, 40, 255, Imgproc.THRESH_BINARY);
4、边缘检测
Imgproc.findContours(ss, contours, new Mat(), Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_NONE);
5、逼近矩阵
最近一直有人问我,怎么将检测的无边边缘逼近成一个方形或其它形状,其实这个问题很容易,你只要在物体的边缘上得到
你要绘制的形状的必要点即可,这里以方形为例:如果要自己写的话,你可能要遍历物体边缘找到物体的左上角、左下角、右
上角、右下角,然后在进行一定的优化,使得绘制出的方形不会将物体覆盖,这样想想就知道会产生多大的复杂度;这里我们可
以用opencv提供的类Imgproc来解决这一问题,具体代码可以参考如下:
Rect r = Imgproc.boundingRect(border);
其中,border是检测到的物体的边缘,这样就会将得到的四个点放在方形类Rect中;接着,通过opencv的绘图函数在图片中将
图形绘制出来:
Imgproc.rectangle(rGba,r.tl(),r.br(),new Scalar(20.0,255.0),2);
其中,rGba是要绘制的图像,r.tl()为左上角坐标,r.br()为右下角坐标,2为边框线的粗细。
综上,你就能够通过手机或其它带有摄像头的设备轻松检测到并追踪运动物体了。
作者原著,如需转载请注明出处,谢谢。