盒式滤波器Box Filter

其主要功能是:在给定的滑动窗口大小下,对每个窗口内的像素值进行快速相加求和

在模式识别领域,Haar特征是大家非常熟悉的一种图像特征了,它可以应用于许多目标检测的算法中。与Haar相似,图像的局部矩形内像素的和、平方和、均值、方差等特征也可以用类似Haar特征的计算方法来计算。这些特征有时会频繁的在某些算法中使用,因此对它的优化势在必行。Boxfilter就是这样一种优化方法,它可以使复杂度为O(MN)的求和,求方差等运算降低到O(1)或近似于O(1)的复杂度,它的缺点是不支持多尺度。

第一个提出Haar特征快速计算方法的是CVPR2001上的那篇经典论文Rapid Object Detection using a Boosted Cascade of Simple Features ,它提出了integral image的概念,这个方法使得图像的局部矩形求和运算的复杂度从O(MN)下降到了O(4)。它的原理很简单:首先建立一个数组A,宽高与原图像相等,然后对这个数组赋值,每个元素的值A[i]赋为该点与图像原点所构成的矩形中所有像素的和。初始化之后,想要计算某个矩形像素和的时候可以采用如下方法:如图D矩形的像素和就等于A[4] – A[2] – A[3] + A[1],共4次运算,即O(4)。Integral Image极大的提高了Haar特征的计算速度,它的优点在于能够快速计算任意大小的矩形求和运算。

  Boxfilter的原理有点类似Integral Image,而且比它还要快,但是实现步骤比较复杂。在计算矩形特征之前,Boxfilter与Integral Image都需要对图像进行初始化(即对数组A赋值),不同于Integral Image, Boxfilter的数组A中的每个元素的值是该像素邻域内的像素和(或像素平方和),在需要求某个矩形内像素和的时候,直接访问数组中对应的位置就可以了。因此可以看出它的复杂度是O(1)。

Boxfilter的初始化过程如下:

1、给定一张图像,宽高为(M,N),确定待求矩形模板的宽高(m,n),如图紫色矩形。图中每个黑色方块代表一个像素,红色方块是假想像素。

2、开辟一段大小为M的数组,记为buff, 用来存储计算过程的中间变量,用红色方块表示

3、将矩形模板(紫色)从左上角(0,0)开始,逐像素向右滑动,到达行末时,矩形移动到下一行的开头(0,1),如此反复,每移动到一个新位置时,计算矩形内的像素和,保存在数组A中。以(0,0)位置为例进行说明:首先将绿色矩形内的每一列像素求和,结果放在buff内(红色方块),再对蓝色矩形内的像素求和,结果即为紫色特征矩形内的像素和,把它存放到数组A中,如此便完成了第一次求和运算。

4、每次紫色矩形向右移动时,实际上就是求对应的蓝色矩形的像素和,此时只要把上一次的求和结果减去蓝色矩形内的第一个红色块,再加上它右面的一个红色块,就是当前位置的和了,用公式表示 sum[i] = sum[i-1] - buff[x-1] + buff[x+m-1]

5、当紫色矩形移动到行末时,需要对buff进行更新。因为整个绿色矩形下移了一个像素,所以对于每个buff[i], 需要加上一个新进来的像素,再减去一个出去的像素,然后便开始新的一行的计算了。

  Boxfilter的初始化过程非常快速,每个矩形的计算基本上只需要一加一减两次运算。从初始化的计算速度上来说,Boxfilter比Integral Image要快一些,大约25%。在具体求某个矩形特征时,Boxfilter比Integral Image快4倍,所谓的4倍其实就是从4次加减运算降低到1次,虽然这个优化非常渺小,但是把它放到几层大循环里面,还是能节省一些时间的。对于那些实时跟踪检测算法,一帧的处理时间要严格在40ms以下,正是这些细小的优化决定了程序的效率,积少成多,聚沙成塔。

下面的程序是Boxfilter的示例代码,谨供参考(C语言)

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <math.h>
 4 #include <opencv2\opencv.hpp>
 5
 6 void displayImageNewWindow(char *title,CvArr* img){
 7     cvNamedWindow(title,1);
 8     cvShowImage(title,img);
 9 }
10 void box_filter(IplImage* img,IplImage* result){
11     //init part
12     CvScalar s;
13     int width = img->width, height = img->height;
14     int m_w = 5,m_h = 5;//window_size
15     int boxwidth = width - m_w, boxheight = height - m_h;
16     int *sum = (int*)malloc(boxwidth *boxheight*sizeof(double));
17     int *buff= (int*)malloc(width*sizeof(double));
18     memset(sum,0,boxwidth *boxheight*sizeof(int));
19     memset(buff,0,width*sizeof(int));
20
21     //set buff:from 0 to 4 rows,per col
22     int x,y,j;
23     for(y=0; y<m_h; y++){
24         for(x=0; x<width; x++){
25             uchar pixel = CV_IMAGE_ELEM(img,uchar,y,x);
26             buff[x] += pixel;
27             //printf("%d:%d\n",x,buff[x]);
28         }
29     }
30
31     for(y=0; y<height - m_h;y++){
32         int Xsum = 0;
33
34         for(j=0; j<m_w; j++){
35             Xsum += buff[j];//sum of pixel from (0,0) to (m_h,m_w) (also x = 0)
36         }
37
38         for(x=0; x<boxwidth; x++){
39             if(x!=0){
40                 Xsum = Xsum-buff[x-1]+buff[m_w-1+x];//Xsum:sum of cols range from x to x+m_w ,rows range from 0 to 4
41             }
42             sum[y*boxwidth + x] = (float) Xsum;
43         }
44
45         for(x=0; x<width; x++){
46             uchar pixel = CV_IMAGE_ELEM(img,uchar,y,x);//img[y *width + x];
47             uchar pixel2= CV_IMAGE_ELEM(img,uchar,y+m_h,x);//img[(y+mheight) *width + x];
48             buff[x] = buff[x] - pixel + pixel2;
49         }
50     }
51     //遍历,得到每个点的和,传给矩阵result
52     for( y=0; y<height-5; y++){
53         for( x=0; x<width; x++){
54             if(y>m_h/2 && y<height - m_h/2 && x>m_w/2 && x<width - m_w/2){
55                 s.val[0] =  sum[(y - m_h/2) *boxwidth + (x - m_h/2)]/(m_h*m_w);
56                 cvSet2D(result,y,x,s);
57             }else{
58                 s.val[0] = -1;
59                 cvSet2D(result,y,x,s);
60             }//end else
61         }//end the first for
62     }//end the second for
63 }
64 int main(int argc,char** argv){
65     IplImage* left = cvLoadImage(argv[1]);
66     IplImage* dst = cvCreateImage(cvGetSize(left),8,1);
67     IplImage* mat =  cvCreateImage(cvGetSize(left),8,1);
68     cvZero(mat);
69     cvCvtColor(left,dst,CV_RGB2GRAY);
70     box_filter(dst,mat);
71     displayImageNewWindow("mat",mat);
72     cvWaitKey();
73     return 0;
74 }
时间: 2024-10-15 16:09:27

盒式滤波器Box Filter的相关文章

解析opencv的 Box Filter的实现并提出进一步加速的方案。

说明:本文所有算法的涉及到的优化均指在PC上进行的,对于其他构架是否合适未知,请自行试验. Box Filter,最经典的一种领域操作,在无数的场合中都有着广泛的应用,作为一个很基础的函数,其性能的好坏也直接影响着其他相关函数的性能,最典型莫如现在很好的EPF滤波器:GuideFilter.因此其优化的档次和程度是非常重要的,网络上有很多相关的代码和博客对该算法进行讲解和优化,提出了不少O(1)算法,但所谓的0(1)算法也有优劣之分,0(1)只是表示执行时间和某个参数无关,但本身的耗时还是有区别

解析opencv中Box Filter的实现并提出进一步加速的方案(源码共享)。

说明:本文所有算法的涉及到的优化均指在PC上进行的,对于其他构架是否合适未知,请自行试验. Box Filter,最经典的一种领域操作,在无数的场合中都有着广泛的应用,作为一个很基础的函数,其性能的好坏也直接影响着其他相关函数的性能,最典型莫如现在很好的EPF滤波器:GuideFilter.因此其优化的档次和程度是非常重要的,网络上有很多相关的代码和博客对该算法进行讲解和优化,提出了不少O(1)算法,但所谓的0(1)算法也有优劣之分,0(1)只是表示执行时间和某个参数无关,但本身的耗时还是有区别

测试卡尔曼滤波器(Kalman Filter)

真实的温度测试数据,通过加热棒加热一盆水测得的真实数据,X轴是时间秒,Y轴是温度: 1)滤波前 2)滤波后(p=10, q=0.0001, r=0.05, kGain=0;) 2)滤波后(p=10, q=0.00001, r=1, kGain=0;),Y轴放大10倍并取整 .   相关C语言代码: #define LINE 1024 static float prevData=0; static float p=10, q=0.0001, r=0.05, kGain=0; float kalma

卡尔曼滤波器 Kalman Filter (转载)

在学习卡尔曼滤波器之前,首先看看为什么叫“卡尔曼”.跟其他著名的理论(例如傅立叶变换,泰勒级数等等)一样,卡尔曼也是一个人的名字,而跟他们不同的是,他是个现代人! 卡 尔曼全名Rudolf Emil Kalman,匈牙利数学家,1930年出生于匈牙利首都布达佩斯.1953,1954年于麻省理工学院分别获得电机工程学士及硕士学位.1957年于哥 伦比亚大学获得博士学位.我们现在要学习的卡尔曼滤波器,正是源于他的博士论文和1960年发表的论文<A New Approach to Linear Fil

第一章、数字图像的描述

“虚拟的图像,一个点或一组点,如果在一面镜子或透镜的一边看到,那么在另一边必定存在一个真实的发出光的实体” ——Clerk Maxwell 矢量图像 描述图像的一种方式是使用数字来申明图像的内容,位置,大小,几何形状——图形:线,曲线,矩形,圆等:这种图像称为矢量图. 坐标系 对于矢量图,我们需要定义一个坐标系来描述它.这种用来表述图形各个元素的位置关系的坐标系称为用户空间(user space),在这个坐标系下,用户定义各个元素的位置关系. 图1-1坐标系 本文中所有示例的坐标系都如上图所示以

[Matlab] 滤波器filter函数造轮子及使用代码生成进行速度优化

之前做脑机接口上位机的时候需要对数据进行实时滤波,也就是需要对数据进行分段滤波,保存滤波器前一次的历史状态.翻了翻MATLAB官方文档的filter函数发现有这个功能,不过他们的函数说明是用相位及延迟进行设置,看了半天没理解什么意思,为了保险起见我自己造了个轮子实现简单的IIR滤波器.filter函数的官方文档:https://ww2.mathworks.cn/help/matlab/ref/filter.html?s_tid=doc_ta 在官方文档中IIR滤波器的详细原理都已经讲的很明白了不

opencv图像处理之常见滤波器

图像平滑 Smoothing, also called blurring, is a simple and frequently used image processing operation. 平滑,也叫模糊. 本质就是把某点的像素值转换为其及其周围像素值的不同权重的叠加.h(k,l)即为卷积核,或者叫滤波器filter. 有几种常见的filter Normalized Box Filter Gaussian Filter Median Filter Bilateral Filter 均值滤波

滤波器概述

滤波器 滤波器(filter)是一种用来消除干扰杂讯的器件,将输入或输出经过过滤而得到纯净的交流电. 滤波器概述 对特定频率的频点或该频点以外的频率进行有效滤除的电路,就是滤波器. 其功能就是得到一个特定频率或消除一个特定频率, 利用这个特性可以将通过滤波器的一个方波群或复合噪波,而得到一个特定频率的正弦波. 滤波器类型 巴特沃斯响应(最平坦响应) 巴特沃斯响应能够最大化滤波器的通带平坦度.该响应非常平坦,接近DC信号,然后慢慢衰减至截止频率点为-3dB,最终逼近-20ndB/decade的衰减

[数字图像处理]图像去噪初步(2)--非线性滤波器

1.非线性处理与线性处理的区别 上一篇博文的内容,是关于均值滤波器的.比如说像算术均值滤波器,几何均值滤波器.这以类型的滤波器的常常被用于剔除某些不需要的频率成分,或者选择需要的频率成分,从而达到去噪的目的.这样的滤波器,被称为线性滤波器. 然而,还有一些特殊滤波器,他们被称为非线性滤波器.其代表为中央值滤波器.所谓中央值滤波器,就是将一定范围内的数据(对于图像而言,是像素的灰度值)进行排序,选择中央值作为滤波器的输出. 中央值滤波器的目的并不是频率成分的选择,而是求root信号.关于root信