Reference article: https://blog.csdn.net/PecoHe/article/details/89927842
https://blog.csdn.net/weixin_41695564/article/details/80056430
-
Foreword
Integral graph algorithm first proposed by Crow in 1984, in order to improve rendering speed in multi-scale perspective projection. FIG integral algorithm is a fast algorithm for computing the image area and image area and the sum of squares. Its core idea is to find a table for each image to establish its own integral image, in the image processing stage you can find in order to achieve a direct calculation of the mean time linear convolution integral image according to pre-established look-up table. Did time convolution performed regardless of the window size . Such an algorithm is applied to the NCC based on fast matching, object detection and SURF conversion, edge detection, based on statistics and so on fast filter.
-
Establish integral image
FIG integral calculated from the original image, the original image is assumed that the size of W * H, the integral image size (W + 1) * (H + 1). In the integral image (integral image) at any point in the upper left corner coordinates (x, y) at a value representing the original coordinates (x, y) of all pixels and the pixel values (square sum is squared tables with). And tables and square tables and establish the following equation:
And tables:
Sum of squares table:
As shown below, assume the input image size is 2x2, 3x3 size of the integral FIG.
-
Find integral image
As shown above, if you want to find pixel values in the input image and a blue area (2 + 3 + 4 + 5 = 14), and in accordance with the table as long as the integration is performed twice FIG subtraction and one subtraction to: 46+ 10-22-20 = 14. That is bottom right corner of the upper left corner + - the top right - bottom left corner.
-
Opencv examples
In calculating the integral of FIG opencv API Introduction:
//API一
void integral( InputArray src, //输入图像
OutputArray sum, //和表
int sdepth = -1,); //和表深度
//API二
void integral( InputArray src, //输入图像
OutputArray sum, //和表
OutputArray sqsum, //平方和表
int sdepth = -1, //和表深度,一般为CV_32S
int sqdepth = -1 ); //平方和表深度,一般为CV_32F
FIG integral calculation and display:
//////////////////////////////////
//opencv4.1.0
//////////////////////////////////
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main() {
Mat src, sum, sqrsum;
src = imread("1.png", 0);
integral(src, sum, sqrsum, CV_32S, CV_32F);
normalize(sum, sum, 0, 255, NORM_MINMAX, CV_8UC1, Mat());
normalize(sqrsum, sqrsum, 0, 255, NORM_MINMAX, CV_8UC1, Mat());
imshow("原图", src);
imshow("和表积分图", sum);
imshow("平方和表积分图", sqrsum);
waitKey(0);
return 0;
}
-
Get the pixel values within the specified area and
//////////////////////////////////
//opencv4.1.0
//////////////////////////////////
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int get_block_sum(Mat &sum, int x1, int y1, int x2, int y2);
int main() {
Mat src, sum, sqrsum;
src = imread("1.png", 0);
//获取ROI,便于观察(使用ImageWatch插件)
int LR = 4;
int LC = 4;
int width = 6;
int height = 6;
Mat roi = src(Rect(LR, LC, width, height)).clone();
//计算积分图
integral(src, sum, sqrsum, CV_32S, CV_32F);
//利用积分图计算ROI内的像素值总和
int value = get_block_sum(sum, LR, LC, LR + height, LC + width);
cout << value << endl;
imshow("原图", src);
waitKey(0);
return 0;
}
int get_block_sum(Mat &sum, int x1, int y1, int x2, int y2) {
int BottomRight = sum.at<int>(x2, y2);
int TopLeft = sum.at<int>(x1, y1);
int TopRight = sum.at<int>(x1, x2);
int BottomLeft = sum.at<int>(x2, y1);
int sum_value = (BottomRight + TopLeft - TopRight - BottomLeft);
return sum_value;
}