integral函数Opencv源码理解-leetcode动态规划的使用场景

news2024/11/26 0:46:12

前言

            Opencv有一个integral()函数,也就是积分图算法。有三种积分图类型,求和(sum),求平方和(sqsum),求旋转45°和(titled)。根据名字可知道,前两个是统计输出每个坐标的左上方像素和、左上方像素平方和,旋转45°的积分图则是统计每个像素点左上方45°到右上方45°区域的像素和。

        作为一名合格的算法工程师,肯定都有leetcode的刷题经验,leetcode上的经典动态规划类型题目,可以完美的在integral函数的代码中体现。

        通过本文,你会知道完全弄清积分图的sum, sqsum, titled的使用和实现细节。看到动态规划中时间复杂度和内存优化的思想是如何被一步步设计的。

integral()函数的介绍

        积分图是数字图像处理中常用的一种方法,通常能够很大程度的加速计算过程。其思想是,当需要统计一张图像中矩形区域的像素和时候,如果我们之前统计过该图像的积分图结果,就可以直接调用积分图数据,做两次加法两次减法就能得到结果了,而不用再遍历这个图像的所有像素点。

        如下图,假设积分图用summ表示, ABCD区域的像素和用S表示,则S=summ[A] + summ[D]-summ[C]-summ[B]。粉色标记区域就是点A的累计像素和区域,分别对应了sum, sqsum积分图和titled积分图。

        另外,使用积分图时候,一般会给一个左上角的点A(x,y, h,w), 其对应的矩形B,C,D的坐标关系,在sum,titled里具有不一样的含义。比如在opencv 文档里的示例,一个正常的矩形 Rect(4,4,3,2) 和一个倾斜45度的矩形Rect(5,1,2,3)。其坐标对应关系如下,请注意stright和titled矩形的P0,P1,P2,P3并非一一对应,只有同一张图里的P0,P1,P2,P3四个点的相对位置是对应的,这里可能会给人造成误解。

 

        integral积分图有三种构建方式,定义如下。前两种sum,sqsum比如可以用在相似度匹配算法NCC, 第三种titled常用在人脸检测算法的Harr特征提取场景。

 integral的代码实现设计

        由定义可知,sum, sqsum两种积分图除了累加定义不同,其实现思路是一样的。为了描述方便,后面代码设计主要以sum,title两种方式为典型进行分析。

sum模式的代码实现设计

        把一张图按照从左到右,从上到下的顺序遍历,sum是以统计每个像素点的之前的像素值累计之和,那么如果没有优化思想,每个输出像素点都要重新从头开始遍历图像并累加和,那么时间复杂度就是O(H *W *(1+2+3+...+H*W)≈O(H*W)^2,实际上完全没有必要。

        根据定义,我们可以发现当前像素点的积分结果与其左边和上边一个是有关系的!利用这个关系,可以重复利用之前统计过的像素值,而不用重新统计新坐标位置之前的像素和了,实现“看一遍”就出结果的效果。

        如下图,假设原图用src表示, sum表示积分图结果。现在要计算p(x,y)的积分结果,可以有两种实现设计,其时间复杂度都是O(H*W), 只是空间复杂度不同。

设计一(左边):

需要一个额外的空间数组Buf,长度和图像宽w相同。 buf[i]表示该列累计到i的像素和。

sum(x,y)=sum(x-1,y) +Buf(x-1)+src(x,y)

设计二(右边):

需要一个额外空间变量Sx,表示该行累计到x坐标之前的像素和。

sum(x,y)=sum(x,y-1)+Sx+src(x,y)

 

titled模式的代码实现设计

        同样,我们也可以观察到titled模式的积分统计也是有规律的,当前像素的结果与其周边的几个点也有关系。最终也有两种实现设计方式。

        我们同样用src指代原图,用titled指代旋转45度的积分图结果。

设计一(左边):

需要一个额外的空间数组Buf,长度和图像宽w相同。 buf[i]表示到第i行,其右斜对角的像素和。

titled(x,y)= titled(x-1,y-1)+Buf(x)+Buf(x+1)+src(x,y)

设计二(右边):

titled(x,y)= titled(x-1,y-1)+ titled(x+1,y-1)- titled(x,y-2)+src(x,y)+src(x,y-1)

        另外对于titled模式,请注意,上面示意的只是中间位置像素点的计算,当第一行,或者第一列,最后一列时候的处理关系如下,上面两种设计对这种边界的处理是相同的。

  • titled(x,y)=src(x,y),   if y=0
  • titled(x,y)=titled(x+1,y-1)+src(x,y)+src(x,y-1),  if x=0
  • titled(x,y)=titled(x-1,y-1)+src(x,y)+src(x,y-1),  if x=w-1

小结

        对于sum, titled,opencv的实现分别采用了设计2,设计1。并且为了使计算代码更简洁,在实现时候,sum,titled的内存分配都会比src多一行和一列。最终的结果在去掉这一行一列。

        至此,将integral积分图的代码实现流程已经分析完毕,sum, sqsum的计算比较容易复现,titled模式下,对维护每行斜对角累计像素和的Buf更新,有点不太容易理解。后面如果大家有需求,欢迎留言,再把我写的python实现代码贴一下,今天就到这里啦。

        整体代码实现的设计思路就是用到了动态规划的思想,想想自己之前刷过的题,感觉好亲切啊,有没有?

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/27719.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

pexpect 自动交互输入

pexpect 为 python 内置库,在 linux 上执行的,win 执行会报错 主要用于执行命令后自动输入,例如要执行 sql 去修改全局变量: mysql -uroot -p -h127.0.0.1 -e"set gloabl max_prepared_stmt_count1000000;" 这时候会…

实时数据平台设计

1 相关概念背景 1.1 从现代数仓架构角度看实时数据平台 现代数仓由传统数仓发展而来,对比传统数仓,现代数仓既有与其相同之处,也有诸多发展点。首先我们看一下传统数仓(图1)和现代数仓(图2)的…

基于springboot和vue的IT内部电脑报修服务系统设计与实现-计算机毕业设计源码+LW文档

it内部设备服务系统设计与实现 摘 要 it内部设备服务系统将传统的网络服务方式与最新的互联网技术相结合,使用方便快捷,有利于设备维修部门规范管理,提高网络维修部门的工作效率,在技术、态度等多方面提高维修部门服务质量。因此…

Oracle表空间、用户详解

目录新建连接三者关系表空间创建表空间修改表空间和数据文件修改数据文件容量新增表空间的数据文件重命名数据文件修改表空间状态修改数据文件状态删除表空间查询用户创建删除查询修改新建连接 工具选择: 我们一般会选择一个工具来连接本地的Oracle,而我…

老男孩k8s笔记

1.docker常用操作,挂载,环境变量,容器内安装应用,提交镜像 2.trefik部署: k8s部署traefik_weixin_30916125的博客-CSDN博客 3.删除节点后重新加入 k8s node节点删除并重新加入_人生匆匆的博客-CSDN博客 4.mariDB配置…

streamlit+ndraw进行可视化训练深度学习模型

简介 如果你喜欢web可视化的方式训练深度学习模型,那么streamlit是一个不可错过的选择! 优点: 提供丰富的web组件支持嵌入python中,简单易用轻松构建一个web页面,按钮控制训练过程 本文使用streamlit进行web可视化…

会议管理系统SSM记录(一)

目录: (1)环境搭建 (2)整合MyBatis (1)环境搭建 添加:package 配置成web的结构: pom先加入springmvc的依赖就可以实现spring和springmvc的整合 pom.xml中加入依赖&am…

接口的定义与实现

声明类的关键字是class,声明接口的关键字是interface 1.介绍 普通类:只有具体实现 抽象类:具体实现和规范(抽象方法)都有 接口:只有规范 |自己无法写方法,专业的约束 接口就是规范,…

MATLAB | 全网唯一 MATLAB双向弦图(有向弦图)绘制

先赞后看,养成习惯~~ 先赞后看,养成习惯~~ 先赞后看,养成习惯~~ 绘制效果 下面这款弦图我已经出了很久了,也陆陆续续增添了新的功能和修了一些bug: 甚至还用它做出了一些复刻,分成两组的弦图有了后就有很多…

【仿真建模】AnyLogic入门基础教程 第一课

文章目录一、AnyLogic介绍二、设置2.1 设置中文三、新建项目四、行人库介绍五、创建新行人六、切换3D视角七、增加墙八、行人密度图一、AnyLogic介绍 二、设置 2.1 设置中文 三、新建项目 四、行人库介绍 点击面板,选择第三个图标,就是行人库 行人库分…

【第五部分 | JS WebAPI】4:八千字详解 “事件·高级篇”

目录 | 概述 | 注册事件的两种方式 | 删除事件的两种方式 | 事件对象【重要】 事件对象简介和声明 e.target 和 this 的区别 [ 事件对象 的常用属性方法 ] | Dom事件流 什么是Dom事件流? 阻止默认行为 阻止事件冒泡 利用事件冒泡进行事件委托 | 常用的鼠…

1、Git相关操作

目录 一、远程库的拉取 二、远程库创建分支 声明:需要有一定的GIt基础,如果不懂可以自行查看个人学习的Git笔记或者可以通过其他途径学习Git 一、远程库的拉取 步骤: 先创建一个空的文件夹在创建的文件夹中使用git init 命令来初始化本地…

频域中的后门攻击论文笔记

文章一:Rethinking the Backdoor Attacks’ Triggers: A Frequency Perspective 文章贡献: 在频域上对现有的 backdoor trigger 进行分析,发现常见 trigger 存在 high-frequency artifacts 的问题。对这些 artifacts 进行了详细的分析展示了…

什么是中间件

一、什么是中间件 中间件(Middleware)是处于操作系统和应用程序之间的软件,也有人认为它应该属于操作系统中的一部分。人们在使用中间件时,往往是一组中间件集成在一起,构成一个平台(包括开发平台和运行平…

企业内训app源码,在线培训小程序,随时随地想学就学

近年来,在线学习逐渐被广泛应用于人才培养领域。公司要想长远发展,内部培训必不可少。公司的发展离不开公司整体员工的进步,而人员管理往往是公司管理中最重要也最难的一个环节。许多公司开始通过企业内训app源码开发来优化公司人员管理方式、…

基于PHP+MySQL学生信息管理系统的设计与实现

我国是一个高等教育逐渐普及的国度,相应的每年也有上百万的大学生入校,如此庞大的学生数量如何进行更加科学的管理是教育工作者一直关心的一个问题,为了能够实现高校对学生信息管理的科学化,信息化,我们开发了本基于PH…

C++ 手动实现双向链表(作业版)

双向链表&#xff0c;并实现增删查改等功能 首先定义节点类&#xff0c;类成员包含当前节点的值&#xff0c; 指向下一个节点的指针和指向上一个节点的指针 //节点定义 template <typename T> class Node { public:Node<T>* prior;T value;Node<T>* next;N…

减少乘法次数的优化算法(Gauss、Strassen、Winograd)

目录 Gauss算法 Strassen算法 Winograd算法 Winograd 1D Winograd 2D 在硬件设计中&#xff0c;乘法无论是在逻辑资源的使用上还是组合逻辑的延时上都要比加法高很多。从硬件方面考虑&#xff0c;我们都更倾向于将乘法转换成移位和加法&#xff0c;譬如乘以8&#xff0c;可…

stm32项目平衡车详解(stm32F407)

stm32项目 stm32项目介绍值平衡车 本文章学习借鉴于创客学院团队&#xff0c;以表感谢。教学视频 文章目录stm32项目前言一、平衡小车平衡小车的功能介绍平衡小车功能开发需求平衡小车整体框架小车环境数据采集进程1. 平衡小车姿态信息介绍2. 平衡小车项目工程框架搭建3. Mpu6…

【面试题】原型和原型链

1. 如何用class实现继承 // 父类 class People{constructor(name){this.name name}eat(){console.log(${this.name} eat something)} }// 子类 class Student extends People{constructor(name, number){super(name)this.number number}sayHi(){console.log(姓名&#xff1a…