积分图像(Integral image)

简介: 积分图算法由Crow在1984年首次提出,是为了在多尺度透视投影中提高渲染速度。积分图算法是一种快速计算图像区域和以及图像区域平方和的算法。它的核心思想就是对每一个图像建立起自己的积分图查找表,在图像处理的阶段就可以根据预先建立积分图查找表直接查找从而实现对均值卷积的线性时间计算。做到了卷积执行的时间与窗口大小无关。之前介绍的NL-means算法就可以采用积分图算法进行优化加速。

从直观来说,一张图像就是一个矩形,这个矩形中每个像素点的积分值,就是以图像左上角像素点为左上角顶点,以该像素点为右下角顶点的矩形中包含的所有元素之和。如下图所示,点(x,y)处的积分值为矩形区域中所有像素之和(包括该点)。

65303aa9ff8e4a02b89bcf64d63a1318.jpg

实际计算积分图的时候,为了提高计算效率,通常不会对每一个像素点都重新计算矩形区域包含的所有元素值之和,而是利用相邻点的积分值实现快速计算,如下图所示,点(x,y)的积分值可以使用点(x-1,y)与点(x,y-1)的积分值之和,然后减去重叠区域,也就是减去点(x-1,y-1)的积分值,最后再加上点(x,y)的像素值得到点(x,y)的积分值。

f946faeb710542369f0042807ffdaf68.jpg

上述原理用公式表示为:

I(x,y) = I(x-1,y) + I(x,y-1) - I(x-1,y-1) + pixel(x,y)

此外还需要考虑边界问题,也就是第一行和第一列的计算。

对于第一行:

I(0,0) = pixel(0,0),x=0,y=0

I(x,0) = I(x-1,0) + pixel(x,0),x>0,y=0

对于第一列:

I(0,y) = I(0,y-1) + pixel(0,y),x=0,y>0


根据上述原理,基于OpenCV与C++的实现代码如下:

voidIntegral(Matsrc, Mat&integal_out)
{  
Mattmp(src.size(), CV_64FC1, 0.0);
tmp.ptr<double>(0)[0] = (double)src.ptr<uchar>(0)[0];
for(inti=1; i<src.cols; i++)   //第一行    {
tmp.ptr<double>(0)[i] =tmp.ptr<double>(0)[i-1] +src.ptr<uchar>(0)[i];
    }
for(inti=1; i<src.rows; i++)  //第一列    {
tmp.ptr<double>(i)[0] =tmp.ptr<double>(i-1)[0] +src.ptr<uchar>(i)[0];
    }
for(inti=1; i<src.rows; i++)   //第i行    {
for(intj=1; j<src.cols; j++)   //第j列       {
tmp.ptr<double>(i)[j] =tmp.ptr<double>(i)[j-1] +tmp.ptr<double>(i-1)[j] -tmp.ptr<double>(i-1)[j-1] +src.ptr<uchar>(i)[j];
        }
    }
tmp.copyTo(integal_out);
}

参考OpenCV的官方文档:

C++: voidintegral(InputArrayimage, OutputArraysum, intsdepth=-1Parameters: 
image–SourceimageasWXH  , 8-bitorfloating-point (32for64f).
sum–Integralimageas (W+1) X (H+1) ,
32-bitintegerorfloating-point (32for64f).
sdepth–Desireddepthoftheintegralandthetiltedintegralimages,
CV_32S, CV_32F, orCV_64F.

发现为了能容纳最后一列和最后一行的情况,最终的积分图就应该是 (W + 1) X (H + 1)大小,如下图所示,假设输入图像大小为2x2,则积分图大小为3x3:

80931244fc6546b1be3be4483246bc6a.png

OpenCV官方提供两种积分图函数integral(),可以直接调用:

//API一voidintegral( InputArraysrc,     //输入图像OutputArraysum,    //和表intsdepth=-1,);  //和表深度//API二voidintegral( InputArraysrc,     //输入图像OutputArraysum,    //和表OutputArraysqsum,  //平方和表intsdepth=-1,    //和表深度,一般为CV_32Sintsqdepth=-1 ); //平方和表深度,一般为CV_32F

OpenCV实现过程:

#include <opencv2/opencv.hpp>usingnamespacestd;
usingnamespacecv;
intmain() {
Matsrc, 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);
return0;
}

我们还可以对兴趣区域(ROI)内的像素求和或者平方和:

#include <opencv2/opencv.hpp>usingnamespacestd;
usingnamespacecv;
intget_block_sum(Mat&sum, intx1, inty1, intx2, inty2);
intmain() {
Matsrc, sum, sqrsum;
src=imread("1.png", 0);
//获取ROI,便于观察(使用ImageWatch插件)intLR=4;
intLC=4;
intwidth=6;
intheight=6;
Matroi=src(Rect(LR, LC, width, height)).clone();   
//计算积分图integral(src, sum, sqrsum, CV_32S, CV_32F);
//利用积分图计算ROI内的像素值总和intvalue=get_block_sum(sum, LR, LC, LR+height, LC+width);
cout<<value<<endl;
imshow("原图", src);        
waitKey(0);
return0;
}
intget_block_sum(Mat&sum, intx1, inty1, intx2, inty2) {
intBottomRight=sum.at<int>(x2, y2);
intTopLeft=sum.at<int>(x1, y1);
intTopRight=sum.at<int>(x1, x2);
intBottomLeft=sum.at<int>(x2, y1);
intsum_value= (BottomRight+TopLeft-TopRight-BottomLeft);
returnsum_value;
}
相关文章
|
计算机视觉
Opencv学习笔记(十二):图片腐蚀和膨胀操作
这篇文章介绍了图像腐蚀和膨胀的原理、作用以及使用OpenCV实现这些操作的代码示例,并深入解析了开运算和闭运算的概念及其在图像形态学处理中的应用。
1376 1
Opencv学习笔记(十二):图片腐蚀和膨胀操作
|
8月前
|
人工智能 监控 安全
OpenClaw阿里云/本地部署效率倍增实战:多智能体协作+自定义技能+定时任务全流程优化指南
在完成OpenClaw(Clawdbot)的基础部署、模型对接与通道接入后,多数用户仅停留在消息回复、简单问答、基础查询等浅层功能,并未真正发挥这款执行型AI智能体的核心价值。OpenClaw与传统对话类模型的本质区别,在于其具备自主执行、流程编排、多角色协同、定时触发、系统控制与扩展集成的能力。通过多智能体架构、自定义技能、定时任务、浏览器控制、记忆优化、第三方集成、安全与成本管控七个方向的深度配置,可让整体使用效率提升十倍以上。本文基于2026年最新稳定版本,完整呈现从阿里云与本地平台部署、免费大模型对接,到高阶效率优化的全流程方案,所有配置与代码均可直接复制使用。
1287 1
|
前端开发
Promise.all()方法的作用是什么?
Promise.all()方法的作用是什么?
892 121
|
数据安全/隐私保护 开发者
p文件 破解与防破解技术
p文件 解密机主要功能包括pcode解密、p文件解码、p文件还原m文件、p转m文件、exe文件解密,exe文件还原为m文件
p文件 破解与防破解技术
|
机器学习/深度学习 监控 并行计算
【图像增强】局部对比度增强的CLAHE算法直方图增强研究(Matlab代码实现)
【图像增强】局部对比度增强的CLAHE算法直方图增强研究(Matlab代码实现)
1527 0
|
人工智能 算法 数据管理
制作像素风《饥荒》类游戏的整体蓝图和流程
制作一个像素风《饥荒》类游戏的整体蓝图和流程
|
机器学习/深度学习 人工智能 Ubuntu
|
存储 C++
【C++】Visual Studio C++ 配置并使用gtest(不好用你捶我)
【C++】Visual Studio C++ 配置并使用gtest(不好用你捶我)
|
算法 Java 计算机视觉
图像处理之积分图算法
图像处理之积分图算法
659 2
|
机器学习/深度学习 存储 并行计算
深入解析多目标优化技术:理论、实践与优化
深入解析多目标优化技术:理论、实践与优化
4284 1