0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

OpenCV中积分图函数与应用

OpenCV学堂 来源:OpenCV学堂 作者:OpenCV学堂 2022-06-29 10:26 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

OpenCV中积分图函数与应用

一:图像积分图概念

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

35f9e682-f6f5-11ec-ba43-dac502259ad0.jpg

36181fe4-f6f5-11ec-ba43-dac502259ad0.png

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

二:OpenCV中积分图函数

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


	
  1. void cv::integral(

  2. InputArray src, // 输入图像

  3. OutputArray sum, // 和表

  4. OutputArray sqsum, // 平方和表

  5. OutputArray tilted, // 瓦块和表

  6. int sdepth = -1, // 和表数据深度常见CV_32S

  7. int sqdepth = -1 // 平方和表数据深度 常见 CV_32F

  8. )

三:使用积分图函数

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


	
  1. #include

  2. #include

  3. using namespace cv;

  4. using namespace std;

  5. void blur_demo(Mat &image, Mat &sum);

  6. void edge_demo(Mat &image, Mat &sum);

  7. int getblockSum(Mat &sum, int x1, int y1, int x2, int y2, int i);

  8. int main(int argc, char** argv) {

  9. Mat src = imread("D:/vcprojects/images/yuan_test.png");

  10. if (src.empty()) {

  11. printf("could not load image... ");

  12. return -1;

  13. }

  14. namedWindow("input", CV_WINDOW_AUTOSIZE);

  15. imshow("input", src);

  16. namedWindow("output", CV_WINDOW_AUTOSIZE);

  17. // 计算积分图

  18. Mat sum, sqrsum;

  19. integral(src, sum, sqrsum, CV_32S, CV_32F);

  20. // 积分图应用

  21. int type = 0;

  22. while (true) {

  23. char c = waitKey(100);

  24. if (c > 0) {

  25. type = (int)c;

  26. printf("c : %d ", type);

  27. }

  28. if (c == 27) {

  29. break; // ESC

  30. }

  31. if (type == 49) { // 数字键 1

  32. blur_demo(src, sum);

  33. }

  34. else if (type == 50) { // 数字键 2

  35. edge_demo(src, sum);

  36. }

  37. else {

  38. blur_demo(src, sum);

  39. }

  40. }

  41. waitKey(0);

  42. return 0;

  43. }

  44. void blur_demo(Mat &image, Mat &sum) {

  45. int w = image.cols;

  46. int h = image.rows;

  47. Mat result = Mat::zeros(image.size(), image.type());

  48. int x2 = 0, y2 = 0;

  49. int x1 = 0, y1 = 0;

  50. int ksize = 5;

  51. int radius = ksize / 2;

  52. int ch = image.channels();

  53. int cx = 0, cy = 0;

  54. for (int row = 0; row < h + radius; row++) {

  55. y2 = (row + 1)>h ? h : (row + 1);

  56. y1 = (row - ksize) < 0 ? 0 : (row - ksize);

  57. for (int col = 0; col < w + radius; col++) {

  58. x2 = (col + 1)>w ? w : (col + 1);

  59. x1 = (col - ksize) < 0 ? 0 : (col - ksize);

  60. cx = (col - radius) < 0 ? 0 : col - radius;

  61. cy = (row - radius) < 0 ? 0 : row - radius;

  62. int num = (x2 - x1)*(y2 - y1);

  63. for (int i = 0; i < ch; i++) {

  64. // 积分图查找和表,计算卷积

  65. int s = getblockSum(sum, x1, y1, x2, y2, i);

  66. result.at<Vec3b>(cy, cx)[i] = saturate_cast(s / num);

  67. }

  68. }

  69. }

  70. imshow("output", result);

  71. imwrite("D:/result.png", result);

  72. }

  73. /**

  74. * 3x3 sobel 垂直边缘检测演示

  75. */

  76. void edge_demo(Mat &image, Mat &sum) {

  77. int w = image.cols;

  78. int h = image.rows;

  79. Mat result = Mat::zeros(image.size(), CV_32SC3);

  80. int x2 = 0, y2 = 0;

  81. int x1 = 0, y1 = 0;

  82. int ksize = 3; // 算子大小,可以修改,越大边缘效应越明显

  83. int radius = ksize / 2;

  84. int ch = image.channels();

  85. int cx = 0, cy = 0;

  86. for (int row = 0; row < h + radius; row++) {

  87. y2 = (row + 1)>h ? h : (row + 1);

  88. y1 = (row - ksize) < 0 ? 0 : (row - ksize);

  89. for (int col = 0; col < w + radius; col++) {

  90. x2 = (col + 1)>w ? w : (col + 1);

  91. x1 = (col - ksize) < 0 ? 0 : (col - ksize);

  92. cx = (col - radius) < 0 ? 0 : col - radius;

  93. cy = (row - radius) < 0 ? 0 : row - radius;

  94. int num = (x2 - x1)*(y2 - y1);

  95. for (int i = 0; i < ch; i++) {

  96. // 积分图查找和表,计算卷积

  97. int s1 = getblockSum(sum, x1, y1, cx, y2, i);

  98. int s2 = getblockSum(sum, cx, y1, x2, y2, i);

  99. result.at<Vec3i>(cy, cx)[i] = saturate_cast(s2 - s1);

  100. }

  101. }

  102. }

  103. Mat dst, gray;

  104. convertScaleAbs(result, dst);

  105. normalize(dst, dst, 0, 255, NORM_MINMAX);

  106. cvtColor(dst, gray, COLOR_BGR2GRAY);

  107. imshow("output", gray);

  108. imwrite("D:/edge_result.png", gray);

  109. }

  110. int getblockSum(Mat &sum, int x1, int y1, int x2, int y2, int i) {

  111. int tl = sum.at<Vec3i>(y1, x1)[i];

  112. int tr = sum.at<Vec3i>(y2, x1)[i];

  113. int bl = sum.at<Vec3i>(y1, x2)[i];

  114. int br = sum.at<Vec3i>(y2, x2)[i];

  115. int s = (br - bl - tr + tl);

  116. return s;

  117. }

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

原图:

模糊效果

36546d64-f6f5-11ec-ba43-dac502259ad0.jpg

边缘效果

36721c38-f6f5-11ec-ba43-dac502259ad0.jpg

审核编辑 :李倩


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 图像
    +关注

    关注

    2

    文章

    1095

    浏览量

    42157
  • 函数
    +关注

    关注

    3

    文章

    4406

    浏览量

    66838
  • OpenCV
    +关注

    关注

    33

    文章

    651

    浏览量

    44420

原文标题:OpenCV中积分图介绍与应用

文章出处:【微信号:CVSCHOOL,微信公众号:OpenCV学堂】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    零成本钢铁侠手套!树莓派+OpenCV 秒变手势遥控器!

    大家好,这是一个树莓派和OpenCV的连载专题。使用树莓派与OpenCV实现姿态估计和面部特征点追踪使用树莓派与OpenCV实现面部和运动追踪的云台系统使用树莓派和OpenCV实现手部
    的头像 发表于 08-16 16:16 883次阅读
    零成本钢铁侠手套!树莓派+<b class='flag-5'>OpenCV</b> 秒变手势遥控器!

    如何使用树莓派与OpenCV实现面部和运动追踪的云台系统?

    大家好,这是一个树莓派和OpenCV的连载专题。使用树莓派与OpenCV实现姿态估计和面部特征点追踪使用树莓派与OpenCV实现面部和运动追踪的云台系统使用树莓派和OpenCV实现手部
    的头像 发表于 08-14 17:45 957次阅读
    如何使用树莓派与<b class='flag-5'>OpenCV</b>实现面部和运动追踪的云台系统?

    如何使用树莓派+OpenCV实现姿态估计和面部特征点追踪?

    大家好,这是一个树莓派和OpenCV的连载专题。使用树莓派与OpenCV实现姿态估计和面部特征点追踪使用树莓派与OpenCV实现面部和运动追踪的云台系统使用树莓派和OpenCV实现手部
    的头像 发表于 08-13 17:44 977次阅读
    如何使用树莓派+<b class='flag-5'>OpenCV</b>实现姿态估计和面部特征点追踪?

    如何板端编译OpenCV并搭建应用--基于瑞芯微米尔RK3576开发板

    .. make-j8 可以首先测试下opencv环境是否正常 输入 ./example_opencv即可打开如上命令,证明系统的cv环境没有问题 性能测试 在hog测试dnn加速平均帧率10fps左右 8cpu已经接近
    发表于 08-08 17:14

    ElfBoard技术贴|如何在【RK3588】ELF 2开发板安装openCV4以及第三方库contrib

    应用,不同项目对功能、性能等方面常有特定需求,开发者可能需要使用其他版本的OpenCV,此时便需替换Buildroot的默认配置。同时,为满足更复杂场景需求并扩展功能,添加OpenCV的contrib
    的头像 发表于 08-05 11:03 4308次阅读
    ElfBoard技术贴|如何在【RK3588】ELF 2开发板<b class='flag-5'>中</b>安装<b class='flag-5'>openCV</b>4以及第三方库contrib

    【Milk-V Duo S 开发板免费体验】SDK编译、人脸检测、OpenCV测试

    【Milk-V Duo S 开发板免费体验】SDK编译、人脸检测、OpenCV测试 本文介绍了 Milk-V Duo S 开发板实现 Buildroot SDK 镜像编译、基于 TDL 模型的人
    发表于 07-11 13:48

    itop-3568开发板机器视觉opencv开发手册-图像绘制-画线

    demo11_line.py 然后向该文件添加以下内容: 第 1 行和第 2 行分别导入了 opencv 和 numpy 库; 第 3 行使用 zeros()函数创建一个 512x512 的黑色图片; 第 4 行使
    发表于 06-04 10:38

    在matlab如何计算含有第一类修正的贝塞尔函数积分算不出的问题?

    问题摘要: 在matlab中计算含有第一类修正的贝塞尔函数积分时,出现了在部分值能计算出结果,部分值无法计算出结果的问题。 一、变量定义: syms x y=1.0+1i*x; %积分
    发表于 05-19 16:53

    快速部署!米尔全志T527开发板的OpenCV行人检测方案指南

    本文将介绍基于米尔电子MYD-LT527开发板(米尔基于全志T527开发板)的OpenCV行人检测方案测试。摘自优秀创作者-小火苗 一、软件环境安装1.在全志T527开发板安装OpenCV
    发表于 04-11 18:14

    为LSDK构建opencv时遇到的问题求解

    我正在尝试使用 flex-builder 来运行 bld -c opencv -r ubuntu:桌面 我想要最新版本的 OpenCV。在我的 sdk.yml 文件,我将 opencv
    发表于 03-26 08:26

    详解RTOS的Hook函数

    Hook函数是RTOS的一个关键特性,通过该函数,用户可以增强对任务管理的控制,定义系统行为。
    的头像 发表于 03-24 16:14 838次阅读

    运算放大器积分电路分析

    的。 当输入信号是阶跃直流电压么时,电容将以近似恒流的方式进行充电,输出电压与时间成线性关系。即 例:在1的积分器的输入端加入2给定输入波形,画出在此输入波形作用下
    发表于 03-11 14:36

    使用OpenVINO™模型的OpenCV进行人脸检测,检测到多张人脸时,伺服电机和步入器电机都发生移动是为什么?

    使用OpenVINO™模型的 OpenCV* 进行人脸检测。 使用 cv2.矩形 函数,能够获取检测到的面部的坐标。 检测到多张人脸时,多个坐标被捕获到,伺服电机和步入器电机都发生移动。
    发表于 03-07 06:35

    运放反相放大电路与积分电路反馈电阻和电容的作用

    详细探讨了运放反相放大电路与积分电路反馈电阻和电容的作用。在反相放大电路,电容主要用于稳定电路,减少高频干扰,而电阻是主要的放大元件。在积分电路
    的头像 发表于 03-01 14:55 5545次阅读
    运放反相放大电路与<b class='flag-5'>积分</b>电路<b class='flag-5'>中</b>反馈电阻和电容的作用

    【AI实战项目】基于OpenCV的“颜色识别项目”完整操作过程

    OpenCV是一个广受欢迎且极为流行的计算机视觉库,它因其强大的功能、灵活性和开源特性而在开发者和研究者备受青睐。学习OpenCV主要就是学习里面的计算机视觉算法。要学习这些算法的原理,知道它们
    的头像 发表于 12-09 16:42 1894次阅读
    【AI实战项目】基于<b class='flag-5'>OpenCV</b>的“颜色识别项目”完整操作过程