当前位置: 首页 > 编程日记 > 正文

【OpenCV】OpenCV中积分图函数与应用

OpenCV中积分图函数与应用

参考资料

opencv 查找integral,目前网上大部分的资料来自于opencv

  • https://docs.opencv.org/master/d7/d1b/group__imgproc__misc.html#gadeaf38d7701d7ad371278d663c50c77d
  • https://blog.csdn.net/jia20003/article/details/52710751
  • https://cloud.tencent.com/developer/article/1084469

一:图像积分图概念

积分图像是Crow在1984年首次提出,是为了在多尺度透视投影中提高渲染速度。随后这种技术被应用到基于NCC的快速匹配、对象检测和SURF变换中、基于统计学的快速滤波器等方面。积分图像是一种在图像中快速计算矩形区域和的方法,这种算法主要优点是一旦积分图像首先被计算出来我们可以计算图像中任意大小矩形区域的和而且是在常量时间内。这样在图像模糊、边缘提取、对象检测的时候极大降低计算量、提高计算速度。第一个应用积分图像技术的应用是在Viola-Jones的对象检测框架中出现。

在这里插入图片描述

在这里插入图片描述

上图左侧四个点的矩形区域像素求和,只要根据每个点左上方所有像素和表值,进行两次减法与一次加法即可=》46 – 22 – 20 + 10 = 14

二:OpenCV中积分图函数

OpenCV中通过integral()函数可以很容易的计算图像的积分图,该函数支持和表积分图、平方和表积分图、瓦块和表积分图计算。integral函数与参数解释如下:

void cv::integral(InputArray  src, // 输入图像OutputArray  sum, // 和表OutputArray  sqsum, // 平方和表OutputArray  tilted, // 瓦块和表int sdepth = -1, // 和表数据深度常见CV_32Sint sqdepth = -1 // 平方和表数据深度 常见 CV_32F
)

三:使用积分图函数

通过代码演示计算积分图实现任意窗口大小的盒子模糊与垂直边缘提取,完整的代码实现如下:

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;void blur_demo(Mat &image, Mat &sum);
void edge_demo(Mat &image, Mat &sum);
int getblockSum(Mat &sum, int x1, int y1, int x2, int y2, int i);
int main(int argc, char** argv) {Mat src = imread("D:/vcprojects/images/yuan_test.png");if (src.empty()) {printf("could not load image...\n");return -1;}namedWindow("input", CV_WINDOW_AUTOSIZE);imshow("input", src);namedWindow("output", CV_WINDOW_AUTOSIZE);// 计算积分图Mat sum, sqrsum;integral(src, sum, sqrsum, CV_32S, CV_32F);// 积分图应用int type = 0;while (true) {char c = waitKey(100);if (c > 0) {type = (int)c;printf("c : %d\n", type);}if (c == 27) {break; // ESC}if (type == 49) { // 数字键 1blur_demo(src, sum);}else if (type == 50) { // 数字键 2edge_demo(src, sum);}else {blur_demo(src, sum);}}waitKey(0);return 0;
}void blur_demo(Mat &image, Mat &sum) {int w = image.cols;int h = image.rows;Mat result = Mat::zeros(image.size(), image.type());int x2 = 0, y2 = 0;int x1 = 0, y1 = 0;int ksize = 5;int radius = ksize / 2;int ch = image.channels();int cx = 0, cy = 0;for (int row = 0; row < h + radius; row++) {y2 = (row + 1)>h ? h : (row + 1);y1 = (row - ksize) < 0 ? 0 : (row - ksize);for (int col = 0; col < w + radius; col++) {x2 = (col + 1)>w ? w : (col + 1);x1 = (col - ksize) < 0 ? 0 : (col - ksize);cx = (col - radius) < 0 ? 0 : col - radius;cy = (row - radius) < 0 ? 0 : row - radius;int num = (x2 - x1)*(y2 - y1);for (int i = 0; i < ch; i++) {// 积分图查找和表,计算卷积int s = getblockSum(sum, x1, y1, x2, y2, i);result.at<Vec3b>(cy, cx)[i] = saturate_cast<uchar>(s / num);}}}imshow("output", result);imwrite("D:/result.png", result);
}/*** 3x3 sobel 垂直边缘检测演示*/void edge_demo(Mat &image, Mat &sum) {int w = image.cols;int h = image.rows;Mat result = Mat::zeros(image.size(), CV_32SC3);int x2 = 0, y2 = 0;int x1 = 0, y1 = 0;int ksize = 3; // 算子大小,可以修改,越大边缘效应越明显int radius = ksize / 2;int ch = image.channels();int cx = 0, cy = 0;for (int row = 0; row < h + radius; row++) {y2 = (row + 1)>h ? h : (row + 1);y1 = (row - ksize) < 0 ? 0 : (row - ksize);for (int col = 0; col < w + radius; col++) {x2 = (col + 1)>w ? w : (col + 1);x1 = (col - ksize) < 0 ? 0 : (col - ksize);cx = (col - radius) < 0 ? 0 : col - radius;cy = (row - radius) < 0 ? 0 : row - radius;int num = (x2 - x1)*(y2 - y1);for (int i = 0; i < ch; i++) {// 积分图查找和表,计算卷积int s1 = getblockSum(sum, x1, y1, cx, y2, i);int s2 = getblockSum(sum, cx, y1, x2, y2, i);result.at<Vec3i>(cy, cx)[i] = saturate_cast<int>(s2 - s1);}}}Mat dst, gray;convertScaleAbs(result, dst);normalize(dst, dst, 0, 255, NORM_MINMAX);cvtColor(dst, gray, COLOR_BGR2GRAY);imshow("output", gray);imwrite("D:/edge_result.png", gray);
}int getblockSum(Mat &sum, int x1, int y1, int x2, int y2, int i) {int tl = sum.at<Vec3i>(y1, x1)[i];int tr = sum.at<Vec3i>(y2, x1)[i];int bl = sum.at<Vec3i>(y1, x2)[i];int br = sum.at<Vec3i>(y2, x2)[i];int s = (br - bl - tr + tl);return s;
}

这里最重要的是要注意到上面的图示,积分图对象的Mat(1,1)对应实际图像Mat(0,0),如果不加处理的话会导致结果有明显的中心迁移。edge_demo实现了积分图查找提取图像边缘、blur_demo函数实现积分图查找图像均值模糊,getblockSum函数实现和表查找功能,运行显示:

相关文章:

django学习笔记【003】创建第一个带有model的app

【1】python应用程序要连接mysql有多个驱动程序可供选择&#xff1a; 1、MySQLdb 这个只支持python2.x 所以在这里就不说了&#xff1b; 2、mysqlclient 下载地址   https://pypi.python.org/pypi/mysqlclient/1.3.9 3、MySQL Connector/python 这个是mysql官方主推的mysql驱…

图像非极大值抑制 Sobel 边缘实现

bool SobelVerEdge(cv::Mat srcImage, cv::Mat& resultImage) {CV_Assert(srcImage.channels() 1);srcImage.convertTo(srcImage, CV_32FC1);// 水平方向的 Sobel 算子cv::Mat sobelx (cv::Mat_<float>(3,3) << -0.125, 0, 0.125,-0.25, 0, 0.25,-0.125, 0, …

第四次作业 (日期和jieba库的运用)

设计题1&#xff1a; 设计一个本月份日历&#xff0c;输出格式如下&#xff1a; 要求&#xff1a; 1.初始化start_day&#xff0c;end_day两个日期 from datetime import datetime start_daydatetime(2019,4,1) end_daydatetime(2019,4,30) 其它时间数据生成要用datetime或date…

【C++】LINK类型错误分析记录

LINK类型错误 情况1&#xff1a; 根据生成路径&#xff0c;查找是否成功生成静态库/动态库&#xff0c;一般在./bin文件中。 情况2&#xff1a; 是否在CMakeLists中target_link_libraries中添加链接静态库操作 情况3&#xff1a; 是都存在类模板&#xff0c;需要实例化&a…

eBay宣布发布全新的购买和销售APIs

eBay最近宣布发布两款全新的购买和销售APIs。这些APIs旨在促进eBay产品在第三方应用程序中的更好集成。eBay于10月19日在他们的博客上发表了几篇文章&#xff0c;不仅详细介绍了这些全新的购买和销售APIs提供的功能&#xff0c;而且还详细地总结了他们公司从SOAP&#xff08;简…

Sobel 边缘实现

#include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include "opencv2/imgproc/imgproc.hpp" #include <iostream> using namespace cv; // 非极大值抑制实现sobel竖直细化边缘 bool SobelVerEdge(cv::Mat srcImage, cv::…

vue下实现textarea类似密码框的功能之探索input输入框keyup,keydown,input事件的触发顺序...

项目中引入element的input框组件&#xff0c;触发事件必须要加上.native <el-input placeholder"请输入" type"textarea" v-model"valueText" keyup.native"keyUp(valueText,$event)" keydown.native"keyDown($event)" …

【C++】动态内存管理/move/以及移动构造与移动赋值运算符

文章目录1 .对象移动与右值引用 实际应用过程中遇到的问题及其解决方案c中临时变量不能作为非const的引用参数2. 动态内存管理类3. 对象移动与右值引用4. 移动构造与移动复制运算符1 .对象移动与右值引用 实际应用过程中遇到的问题及其解决方案 问题描述&#xff1a; bool Cr…

图像直接卷积 Sobel 边缘实现

bool sobelEdge(const cv::Mat& srcImage, cv::Mat& resultImage,uchar threshold) {CV_Assert(srcImage.channels() 1);// 初始化水平核因子Mat sobelx (Mat_<double>(3, 3) << 1, 0,-1, 2, 0, -2, 1, 0, -1);// 初始化垂直核因子Mat sobely (Mat_&…

JSON.parse解析特殊字符报错解决方案

2019独角兽企业重金招聘Python工程师标准>>> 具体案例&#xff1a; 页面点击”下一任务” 会去请求后台&#xff0c;这里出现的问题是有虚拟任务的时候。然后会返回一个map&#xff0c;也就是如下图中回调函数中的data。 当该map里存有以下字符的时候&#xff1a; \…

MySQL数据库字符集和整理

MySQL数据库字符集和整理(2009-11-20 22:23:37)mysql数据库 it 其实这个表在MySQL数据库中通过phpMyAdmin就能看到&#xff0c;icech只是把表格整理了一下方便大家使用&#xff0c;如果要更换数据库的字符集&#xff0c;心里有数。其中有三种utf8_general_ci、utf8_unicode_ci…

【SLAM后端】—— ceres优化相机位姿求解

求解结果如下&#xff1a; mat 初始化&#xff0c;eigenvalue初始化 Mat K ( Mat_<double> ( 3,3 ) << 520.9, 0, 325.1, 0, 521.0, 249.7, 0, 0, 1 );Eigen::Matrix<float,3,1> vd_3d;v_3d << 3, 2, 1;求解目标函数结构体构造与实例 struct CurveFi…

SPOJ 1811 LCS [后缀自动机]

题意&#xff1a; 求两个串的最大连续子串 一个串建SAM&#xff0c;另一个串在上面跑 注意如果走了Suffix Link&#xff0c;sum需要更新为t[u].val1 Suffix Link有点像失配吧&#xff0c;当前状态s走不了了就到Suffix Link指向的状态fa上去&#xff0c;fa是s的后缀所以是可行的…

图像卷积下非极大值抑制 Sobel 的实现

bool sobelOptaEdge(const cv::Mat& srcImage, cv::Mat& resultImage, int flag) {CV_Assert(srcImage.channels() 1);// 初始化sobel水平核因子cv::Mat sobelX (cv::Mat_<double>(3, 3) << 1, 0, -1,2, 0, -2, 1, 0, -1);// 初始化sebel垂直核因子cv::…

was unable to refresh its cache! status = Cannot execute request on any known server

出现这种错误是因为: Eureka服务注册中心也会将自己作为客户端来尝试注册它自己&#xff0c;所以我们需要禁用它的客户端注册行为。 在 yml中设置 eureka.client.register-with-eurekafalse eureka.client.fetch-registryfalse 但在服务端是要这是为false的&#xff0c;在客…

【C++】浅析析构函数(基类中)为什么要写成虚基类?

为什么有了虚析构函数&#xff0c;就能先调用子类的析构函数&#xff1f; class A {virtual ~A(){} };class B : A {virtual ~B(){} };A *p new B(); delete p; 唯一差别是&#xff0c;每个析构函数结束时会自动&#xff08;隐含地&#xff09;调上父类的析构函数&#xff0…

Roberts 边缘检测

#include <opencv2/opencv.hpp> // roberts算子实现 cv::Mat roberts(cv::Mat srcImage) {cv::Mat dstImage srcImage.clone();int nRows dstImage.rows;int nCols dstImage.cols;for (int i 0; i < nRows - 1; i){for (int j 0; j < nCols - 1; j){// 根据公…

vector、map删除当前记录

map<string, string> sMap; map<string, string>::iterator iter; for(iter sMap.begin();iter ! sMap.end();/* iter */) {sMap.erase(iter); }注意下列错误表达&#xff1a;1. for(iter sMap.begin();iter ! sMap.end(); iter ) {sMap.erase(iter); } 错误原因…

1-2 postman工具简介

postman提供了一个多窗口和多选项卡页面用于发送和接受请求&#xff0c;postman努力保持整洁和灵活&#xff0c;提供更多的空间&#xff0c;满足用户的需要。他很简单&#xff0c;能满足大部分接口的测试&#xff0c;性价比特别高。如图所示&#xff1a; 1.侧边栏 postman的侧边…

【C++】重载运算符(一)

1.1 重载运算符特点 重载运算符本质上是一次函数调用 除了operator() 运算符调用外&#xff0c;其他重载运算符不能含有默认参数。 当重载的运算符是成员函数时&#xff0c;this绑定到左侧运算对象。成员运算符函数&#xff08;显式&#xff09;的参数数量比运算对象少一个。…

javaScript的调试(二)

2019独角兽企业重金招聘Python工程师标准>>> 一、Firebug Firebug是Firefox浏览器的调试工具&#xff0c;只要我们在Firefox中安装了Firebug应用&#xff0c;就可以按F12或右击鼠标开启调试 那么我们就先来看一下如何在Firefox中安装了Firebug应用&#xff0c;一图剩…

Prewitt 边缘检测

#include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include "opencv2/imgproc/imgproc.hpp" #include <iostream> // prewitt算子实现 cv::Mat prewitts(cv::Mat img, bool verFlag false) {img.convertTo(img, CV_32FC…

[swift 进阶]读书笔记-第十一章:互用性 C11P1 实践:封装 CommonMark

第十一章&#xff1a;互用性 Interoperability 前言&#xff1a; swift 的最大优点就是与C 或者 OC 混编的时候稳的一匹 本章主要讲了swift和C之间的一些知识点。 11.1 实践:封装 CommonMark Hands-On: Wrapping CommonMark 这一小节更像是一个教程。教你如何封装C语言中的Comm…

【Cmake】Cmake学习记录

Cmake学习记录 1.1 常例 add_library(gen_reference_infogen_reference_info/gen_reference_info.hgen_reference_info/gen_reference_info.cc ) target_link_libraries(gen_reference_infoparamsimage_preprocessorcenter_extractorremapperdescriptor_generator${OpenCV_LI…

MySQL(三)用正则表达式搜索

正则表达式是用来匹配文本的特殊的串&#xff08;字符集合&#xff09;&#xff0c;将一个模式&#xff08;正则表达式&#xff09;与一个文本串进行比较&#xff1b; 所有种类的程序设计语言、文本编辑器、操作系统等都支持正则表达式&#xff0c;正则表达式用正则表达式语言来…

计算梯度幅值与方向

Mat magX Mat(src.rows, src.cols, CV_32F); Mat magY Mat(src.rows, src.cols, CV_32F); Sobel(image, magX, CV_32F, 1, 0, 3); Sobel(image, magY, CV_32F, 0, 1, 3); // 计算斜率 Mat slopes Mat(image.rows, image.cols, CV_32F); divide(magY, magX, slopes); // 计…

好程序员web前端技术分享媒体查询

为什么80%的码农都做不了架构师&#xff1f;>>> 好程序员web前端技术分享媒体查询 什么是媒体查询 媒体查询可以让我们根据设备显示器的特性&#xff08;如视口宽度、屏幕比例、设备方向&#xff1a;横向或纵向&#xff09;为其设定CSS样式&#xff0c;媒体查询由媒…

【C++】重载运算符(二)

1.4 下标运算符p501 下标运算符必须是成员函数&#xff0c;表示容器的类通常可以通过容器中的位置访问元素&#xff0c;定义下标运算符operator[]一个包含下标运算符的类&#xff0c;通常&#xff0c;定义2个版本&#xff1a;一个返回普通引用&#xff0c;另一个是类的常量成员…

手动建库11.2.0.4

环境&#xff1a; oracle11.2.0.4 redhat6.2 在上篇文章中&#xff0c;我们只安装了oracle&#xff0c;还没有建立实例&#xff0c;本篇文章就来介绍如果手动建立实例。 1.创建密码文件&#xff08;password file&#xff09;----非必要 cd $ORACLE_HOME/dbs/ 查看是否有init.o…

滞后阈值边缘连接

// 边缘连接 void followEdges(int x, int y, Mat &magnitude, int tUpper,int tLower, Mat &edges) { edges.at<float>(y, x) 255; for (int i -1; i < 2; i) {for (int j -1; j < 2; j) {// 边界限制if((i ! 0) && (j ! 0) && (…