opencv学习笔记三十二:Haar特征与积分图像

一、 Haar特征定义

        Haar特征是基于“块”的特征,也被称为矩形特征。Haar特征(模板)分为三类:边缘特征、线性特征、中心特征和对角线特征。特征模板内有白色和黑色两种矩形,并定义该模板的特征值为白色矩形像素和减去黑色矩形像素和。Haar特征值反映了图像的灰度变化情况。例如:脸部的一些特征能由矩形特征简单的描述,如:眼睛要比脸颊颜色要深,鼻梁两侧比鼻梁颜色要深,嘴巴比周围颜色要深等。但矩形特征只对一些简单的图形结构,如边缘、线段较敏感,所以只能描述特定走向(水平、垂直、对角)的结构。

                                              opencv学习笔记三十二:Haar特征与积分图像_第1张图片                                              

对于图中的1.a这类特征,特征数值计算公式为:v=Sum白-Sum黑,而对于2.c这类来说,计算公式如下:v=Sum白-2*Sum黑;之所以将黑色区域像素和乘以2,是为了使两种矩形区域中像素数目一致。

Haar特征数量:
通过改变特征模板的大小和位置,可在图像子窗口中穷举出大量的特征。上图的特征模板称为“特征原型”;特征原型在图像子窗口中扩展(平移伸缩)得到的特征称为“矩形特征”;矩形特征的值称为“特征值”。
矩形特征可位于图像任意位置,大小也可以任意改变,所以矩形特征值是矩形模版类别、矩形位置和矩形大小这三个因素的函数。故类别、大小和位置的变化,使得很小的检测窗口含有非常多的矩形特征。对于一个给定的24X24的窗口,根据不同的位置,以及不同的缩放,可以产生超过160,000个特征,因此计算一幅图像的所有Haar特征是一件工作量很大的事。

                    

二、Haar特征的快速计算-积分图

opencv学习笔记三十二:Haar特征与积分图像_第2张图片 
图2 计算某个方块内的像素和

图中的大框是积分图,为了讲解如何计算任意矩形内的像素值,我们画出四个区域A、B、C、D,并且图中有四个位置分别为1、2、3、4。我们要计算D区域内部的像素和该怎么计算?

我们记位置4的左上的所有像素为rectsum(4),那么 
D位置的像素之和就是rectsum(4)−rectsum(2)−rectsum(3)+rectsum(1)。 

 

 matlab实现积分图像:

src = imread('2.jpg');
imshow(src);
src = rgb2gray(src);
src = double(src);
[m,n]=size(src);
I=zeros(m,n);
for i=1:m
    for j=1:n
        if i==1 && j==1             %积分图像左上角
            I(i,j)=src(i,j);
        elseif i==1 && j~=1         %积分图像第一行
            I(i,j)=I(i,j-1)+src(i,j);
        elseif i~=1 && j==1         %积分图像第一列
            I(i,j)=I(i-1,j)+src(i,j);
        else                        %积分图像其它像素
            I(i,j)=src(i,j)+I(i-1,j)+I(i,j-1)-I(i-1,j-1);  
        end
    end
end

figure,imshow(I,[]);

 

opencv学习笔记三十二:Haar特征与积分图像_第3张图片

c++实现积分图像:

#include

using namespace cv;
using namespace std;

int main(int arc, char** argv) { 
	Mat src = imread("2.jpg",IMREAD_GRAYSCALE);
	namedWindow("input");
	imshow("input", src);
	Mat result = Mat::zeros(src.size(), CV_32FC1);
	for (int row = 0; row < src.rows; row++) {
		for (int col = 0; col < src.cols; col++) {
			if ((row == 0) && (col == 0)) {
				result.at(row, col) = src.at(row, col);
			}
			else if (row == 0 && col != 0) {
				result.at(row, col) = src.at(row, col) + result.at(row, col - 1);
			}
			else if (row != 0 && col == 0) {
				result.at(row, col) = src.at(row, col) + result.at(row - 1, col);
			}
			else {
					result.at(row, col) = src.at(row, col) + result.at(row - 1, col)
					+ result.at(row, col - 1) - result.at(row - 1, col - 1);
			}		
		}
	}
	normalize(result, result, 0, 255, NORM_MINMAX,CV_8UC1);
	imshow("output", result);
	waitKey(0);
	return 0;
}

 

opencv学习笔记三十二:Haar特征与积分图像_第4张图片

opencv实现积分图像:

#include
using namespace cv;
using namespace std;

int main(int arc, char** argv) { 
	Mat src;
	src = imread("2.jpg",IMREAD_GRAYSCALE);
	namedWindow("input", CV_WINDOW_AUTOSIZE);
	imshow("input", src);
    
    //opencv生成的积分图尺寸比原图尺寸行列各要大一个像素,用opencv的API遵循它的规则即可,不然也可自己写
	Mat sum_img = Mat::zeros(src.rows + 1, src.cols + 1, CV_32FC1);

	integral(src, sum_img, CV_32FC1);
	normalize(sum_img, sum_img, 0, 255, NORM_MINMAX,CV_8UC1);
	imshow("integral_img", sum_img);
        waitKey(0);
	return 0;

}

 

opencv学习笔记三十二:Haar特征与积分图像_第5张图片

参考文献:https://blog.csdn.net/shuzfan/article/details/44676735

                    https://blog.csdn.net/xizero00/article/details/46929261

你可能感兴趣的:(opencv)