本站使用了 Pjax 等基于 JavaScript 的开发技术,但您的浏览器已禁用 JavaScript,请开启 JavaScript 以保证网站正常显示!

积分图像

本篇主要介绍了以下内容

  • 何为积分图像
  • 如何计算积分图像
  • 基于opencv实现积分图像的构建

积分图像

积分图像(integral image),是一个快速且有效地计算图像网格区域的数据结构和算法,得到的结果是一个可以描述图像的全局信息的矩阵。其原理是对某个区域网格内像素点之和,所以又称总和面积表(英语:summed area table,简称SAT)。其数学的描述为如下公式:

$$ii(i,j) = \sum_{k \leq i, l\leq j} f(k,l)$$

其中,$f$为原图像,即位置$(i,j)$处的积分图像值$ ii(i,j)$为该点的左上角的像素点之和。

computeRectangleWithAlpha.png

实际上这是一种预计算的技术,以空间换时间,类似灰度值变换之时常常用到的查找表(look up table)。在得到积分图之后,理论上可以$O(1)$的时间得到图像任意一个矩形区域的总像素之和,如上图所示,如要计算阴影的区域的像素总和,设$A(x1,y1),B(x2,y2),C(x3,y3),D(x4,y4)$,则计算非常简单,只需要用C的积分图减去其余三个积分图:

$$S = ii(x3,x3) - ii(x1,y1) - ii(x2,y2) - ii(x3,y3)$$

计算积分图像

算法步骤如下

  • (1)用$s(i,j)$表示行方向的累加和,初始化$s(i,-1) =0 $.
  • (2)用$ii(i,j)$表示一个积分图像,初始化$ii(-1,j)=0$.
  • (3)逐行扫描图像,递归使用下面的公式计算每个像素$(i,j)$的累加和s(i,j)和积分图像$ii(i,j)$的值

$$s(i,j) = s(i,j-1) + f(i,j)$$
$$ii(i,j) = ii(i-1, j) + s(i,j)$$

  • (4)扫描图像一遍,积分图像$ii$就构造好了。

代码实现

// integral-image.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include "pch.h"
#include <iostream>
#include<vector>

#include <opencv2/opencv.hpp>


int main()
{
    // load gray image
    cv::Mat image = cv::imread("lena.jpg", 0);
    if (image.empty())
    {
        return -1;
    }
    int row = image.rows;
    int col = image.cols;
    //---------- calculate the integral image---------

    // step1: initialize s(i, -1) =0;
    std::vector<std::vector<int> > s(row, std::vector<int>(col,0));

    // step2: initialize ii(-1, j) = 0;
    std::vector<std::vector<int> > ii(row, std::vector<int>(col, 0));


    // step3: calculate s(i,j) and ii(i,j)
    for (auto i = 0; i < row; i++)
    {
        for (auto j = 0; j < col; j++)
        {
            // s(i,j) = s(i,j -1) + f(i,j)
            if (j < 1)
            {
                s[i][j] = 0 + image.at<uchar>(i, j);//s(i, -1) =0;
            }
            else
            {
                s[i][j] = s[i][j - 1] + image.at<uchar>(i, j);
            }
            
            // ii(i,j) = ii(i-1, j) + s(i,j)
            if (i < 1)
            {
                ii[i][j] = 0 + s[i][j];//ii(-1, j) = 0;
            }
            else
            {
                ii[i][j] = ii[i - 1][j] + s[i][j];
            }
        }
    }


    // normalize and show the integral image
    double max = ii[row - 1][col - 1];
    cv::Mat integral_image = cv::Mat(cv::Size(col, row), CV_8UC1);
    for (auto i = 0; i < row; i++)
    {
        for (auto j = 0; j < col; j++)
        {
            ii[i][j] = int(double(ii[i][j] / max) * 255);
            integral_image.at<uchar>(i,j) = ii[i][j];
        }
    }

    cv::imshow("integral-image", integral_image);
    cv::waitKey(0);

    return 0;
}

计算lena的图像
lena.jpg

得到的积分图归一化后显示为
结果.png

references

【1】积分图-维基百科
【2】图像处理、分析与机器视觉
【3】积分图像-xiaoluo91-csdn


本文由芒果浩明发布,转载请注明来源。
本文链接:https://mangoroom.cn/opencv/integral-image.html


 继续浏览关于 opencv图像处理计算机视觉图像处理算法积分图像 的文章

 本文最后更新于:2020/01/17 11:12:16,可能因经年累月而与现状有所差异

 引用转载请注明:芒果的博客 > opencv,算法,计算机视觉 > 积分图像