引言:
Paul Viola和Michael Jones在2001年首次将积分图应用在图像特征提取上,在他们的论文“Rapid Object Detection using a Boosted Cascade of Simple Features”中,积分图被当作一种新的图像特征表征方式,可以把检测的Haar特征非常高效的计算出来,用于实时人脸检测系统。
积分图是一种能够描述全局信息的矩阵表示方法,其构造方式是积分图像上位置(i,j)处的值ii(i,j)是原图像(i,j)左上角方向所有像素的和。
利用积分图可以可以快速的计算图像上某一区域内的像素和,如下图。此时A区域的像素和为:
L4-L3-L2+L1
传统的计算像素和的方式需要遍历区域A内所有的像素,再执行累加,计算量随着区域A面积的增大而增大,而对积分图方式来说,只需要在计算积分图之后,通过简单几次加减运算就可以得到某一区域内“像素和”这一特征,计算速度非常快,并且这种速度的提升效果随着区域面积的增大和计算次数的增多表现的更为明显。
API:
代码演示:
#include "pch.h"
#include <iostream>
#include "opencv2/opencv.hpp"
#include <opencv2/xfeatures2d.hpp>
using namespace std;
using namespace cv;
using namespace cv::xfeatures2d;
int main()
{
Mat src = imread("F:\\visual studio\\Image\\hand4.jpg");
if (src.empty())
{
cout << "Can't load the image" << endl;
return -1;
}
resize(src, src, Size(), 0.5, 0.5);
Mat graysrc;
cvtColor(src, graysrc, CV_RGB2GRAY);
imshow("src", src);
Mat sum = Mat::zeros(src.rows + 1, src.cols + 1, CV_32FC1);
Mat sqsum = Mat::zeros(src.rows + 1, src.cols + 1, CV_64FC1);
integral(graysrc, sum, sqsum, CV_32FC1, CV_64FC1);
//归一化显示
Mat result;
normalize(sum, result, 0, 255, NORM_MINMAX, CV_8UC1);
imshow("result", result);
//验证
Mat roi = graysrc(Rect(100, 100, 200, 200));
float total1 = 0;
for (int i = 0; i < roi.rows; i++)
{
uchar* data = roi.ptr<uchar>(i);
for (int j = 0; j < roi.cols; j++)
{
total1 += data[j];
}
}
cout << "total1 = " << total1 << endl;
float total2 = sum.at<float>(300, 300) - sum.at<float>(100, 300) - sum.at<float>(300, 100) + sum.at<float>(100, 100);
cout << "total2 = " << total2 << endl;
waitKey(0);
return 0;
}