0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

OpenCV中積分圖函數(shù)與應(yīng)用

OpenCV學(xué)堂 ? 來源:OpenCV學(xué)堂 ? 作者:OpenCV學(xué)堂 ? 2022-06-29 10:26 ? 次閱讀

OpenCV中積分圖函數(shù)與應(yīng)用

一:圖像積分圖概念

積分圖像是Crow在1984年首次提出,是為了在多尺度透視投影中提高渲染速度。隨后這種技術(shù)被應(yīng)用到基于NCC的快速匹配、對(duì)象檢測(cè)和SURF變換中、基于統(tǒng)計(jì)學(xué)的快速濾波器等方面。積分圖像是一種在圖像中快速計(jì)算矩形區(qū)域和的方法,這種算法主要優(yōu)點(diǎn)是一旦積分圖像首先被計(jì)算出來我們可以計(jì)算圖像中任意大小矩形區(qū)域的和而且是在常量時(shí)間內(nèi)。這樣在圖像模糊、邊緣提取、對(duì)象檢測(cè)的時(shí)候極大降低計(jì)算量、提高計(jì)算速度。第一個(gè)應(yīng)用積分圖像技術(shù)的應(yīng)用是在Viola-Jones的對(duì)象檢測(cè)框架中出現(xiàn)。

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

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

上圖左側(cè)四個(gè)點(diǎn)的矩形區(qū)域像素求和,只要根據(jù)每個(gè)點(diǎn)左上方所有像素和表值,進(jìn)行兩次減法與一次加法即可=》46 – 22 – 20 + 10 = 14

二:OpenCV中積分圖函數(shù)

OpenCV中通過integral()函數(shù)可以很容易的計(jì)算圖像的積分圖,該函數(shù)支持和表積分圖、平方和表積分圖、瓦塊和表積分圖計(jì)算。integral函數(shù)與參數(shù)解釋如下:


	
  1. void cv::integral(

  2. InputArray src, // 輸入圖像

  3. OutputArray sum, // 和表

  4. OutputArray sqsum, // 平方和表

  5. OutputArray tilted, // 瓦塊和表

  6. int sdepth = -1, // 和表數(shù)據(jù)深度常見CV_32S

  7. int sqdepth = -1 // 平方和表數(shù)據(jù)深度 常見 CV_32F

  8. )

三:使用積分圖函數(shù)

通過代碼演示計(jì)算積分圖實(shí)現(xiàn)任意窗口大小的盒子模糊與垂直邊緣提取,完整的代碼實(shí)現(xiàn)如下:


	
  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. // 計(jì)算積分圖

  18. Mat sum, sqrsum;

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

  20. // 積分圖應(yīng)用

  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) { // 數(shù)字鍵 1

  32. blur_demo(src, sum);

  33. }

  34. else if (type == 50) { // 數(shù)字鍵 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. // 積分圖查找和表,計(jì)算卷積

  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 垂直邊緣檢測(cè)演示

  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; // 算子大小,可以修改,越大邊緣效應(yīng)越明顯

  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. // 積分圖查找和表,計(jì)算卷積

  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. }

這里最重要的是要注意到上面的圖示,積分圖對(duì)象的Mat(1,1)對(duì)應(yīng)實(shí)際圖像Mat(0,0),如果不加處理的話會(huì)導(dǎo)致結(jié)果有明顯的中心遷移。edge_demo實(shí)現(xiàn)了積分圖查找提取圖像邊緣、blur_demo函數(shù)實(shí)現(xiàn)積分圖查找圖像均值模糊,getblockSum函數(shù)實(shí)現(xiàn)和表查找功能,運(yùn)行顯示:

原圖:

模糊效果

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

邊緣效果

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

審核編輯 :李倩


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 圖像
    +關(guān)注

    關(guān)注

    2

    文章

    1079

    瀏覽量

    40375
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4284

    瀏覽量

    62328
  • OpenCV
    +關(guān)注

    關(guān)注

    29

    文章

    625

    瀏覽量

    41215

原文標(biāo)題:OpenCV中積分圖介紹與應(yīng)用

文章出處:【微信號(hào):CVSCHOOL,微信公眾號(hào):OpenCV學(xué)堂】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    RTOS鉤子函數(shù)的用途及用法

    在很多操作系統(tǒng),都存在這樣一類API函數(shù)接口:HOOK函數(shù)(也叫鉤子函數(shù))。
    的頭像 發(fā)表于 10-23 16:25 ?151次閱讀
    RTOS<b class='flag-5'>中</b>鉤子<b class='flag-5'>函數(shù)</b>的用途及用法

    【龍芯2K0300蜂鳥板試用】5 搭建opencv開發(fā)環(huán)境

    在官方提供的buildroot根文件系統(tǒng),不支持opencv庫,故需要自己增加,另外,在本地編譯的時(shí)候,需要在本地(ubuntu)上安裝對(duì)應(yīng)opencv庫,這樣才能將編譯好的鏡像放到板子上跑起來
    發(fā)表于 08-27 15:08

    OpenCV圖像識(shí)別C++代碼

    安裝OpenCV庫 首先,您需要在您的計(jì)算機(jī)上安裝OpenCV庫。您可以從OpenCV官網(wǎng)下載預(yù)編譯的庫或從源代碼編譯。安裝完成后,確保將OpenCV的頭文件和庫文件添加到您的項(xiàng)目中。
    的頭像 發(fā)表于 07-16 10:42 ?1664次閱讀

    opencv-python和opencv一樣嗎

    不一樣。OpenCV(Open Source Computer Vision Library)是一個(gè)開源的計(jì)算機(jī)視覺和機(jī)器學(xué)習(xí)軟件庫,它提供了大量的圖像和視頻處理功能。OpenCV
    的頭像 發(fā)表于 07-16 10:38 ?882次閱讀

    opencv的主要功能有哪些

    OpenCV(Open Source Computer Vision Library)是一個(gè)開源的計(jì)算機(jī)視覺庫,提供了大量的計(jì)算機(jī)視覺算法和工具。以下是OpenCV的主要功能: 圖像處理
    的頭像 發(fā)表于 07-16 10:35 ?1243次閱讀

    OpenCV攜奧比光3D相機(jī)亮相CVPR 2024

    6月17日-21日,奧比光合作伙伴OpenCV攜Orbbec 3D相機(jī)參展在美國西雅圖舉辦的CVPR 2024(即IEEE國際計(jì)算機(jī)視覺與模式識(shí)別會(huì)議),讓開發(fā)者親身體驗(yàn)Orbbec 3D相機(jī)
    的頭像 發(fā)表于 06-21 09:38 ?476次閱讀

    I.MX6ULL-飛凌 ElfBoard ELF1板卡 - 如何在Ubuntu編譯OpenCV庫(X86架構(gòu))

    在之前發(fā)布的文章探討了交叉編譯OpenCV并部署至嵌入式系統(tǒng)的方法。然而,在調(diào)試階段,我們發(fā)現(xiàn)在 Ubuntu 環(huán)境下將 OpenCV 編譯為 X86 架構(gòu)可能更加方便和高效。 通過在主機(jī)上編譯并
    發(fā)表于 06-07 09:32

    嵌入式學(xué)習(xí)-飛凌ElfBoard ELF 1板卡 - 如何在Ubuntu編譯OpenCV

    在之前發(fā)布的文章探討了交叉編譯OpenCV并部署至嵌入式系統(tǒng)的方法。然而,在調(diào)試階段,我們發(fā)現(xiàn)在 Ubuntu 環(huán)境下將 OpenCV 編譯為 X86 架構(gòu)可能更加方便和高效。 通過在主機(jī)上編譯并
    發(fā)表于 06-07 09:21

    ELF 1技術(shù)貼|如何在Ubuntu編譯OpenCV

    在之前發(fā)布的文章探討了交叉編譯OpenCV并部署至嵌入式系統(tǒng)的方法。然而,在調(diào)試階段,我們發(fā)現(xiàn)在Ubuntu環(huán)境下將OpenCV編譯為X86架構(gòu)可能更加方便和高效。通過在主機(jī)上編譯并使用X86架構(gòu)
    的頭像 發(fā)表于 05-31 16:41 ?1116次閱讀
    ELF 1技術(shù)貼|如何在Ubuntu<b class='flag-5'>中</b>編譯<b class='flag-5'>OpenCV</b>庫

    labview的積分函數(shù)用哪個(gè)?

    對(duì)標(biāo)準(zhǔn)正弦加速度數(shù)據(jù)求速度,使用了積分函數(shù),但是得到的積分結(jié)果不是標(biāo)準(zhǔn)的余弦,請(qǐng)問是為什么
    發(fā)表于 05-30 15:13

    請(qǐng)問STM32_ImageProcessingLibrary中有類似于opencv的findContours函數(shù)嗎?

    STM32_ImageProcessingLibrary中有類似于opencv的findContours函數(shù)嗎?
    發(fā)表于 03-07 07:17

    verilog函數(shù)和任務(wù)對(duì)比

    在verilog,函數(shù)和任務(wù)均用來描述共同的代碼段,并且在模式內(nèi)任意位置被調(diào)用,提高代碼效率,讓代碼更加的直觀,提高代碼可讀性。但是在實(shí)際使用的過程,函數(shù)和任務(wù)也存在諸多的不同,下
    的頭像 發(fā)表于 02-12 18:43 ?836次閱讀

    ELF 1技術(shù)貼|如何移植OpenCV

    ,OpenCV擁有了豐富的常用圖像處理函數(shù)庫,采用C/C++語言編寫,可以運(yùn)行在Linux、Windows、Mac等操作系統(tǒng)上流暢運(yùn)行,并能夠快速實(shí)現(xiàn)一系列圖像處理和識(shí)別任
    的頭像 發(fā)表于 01-09 13:55 ?342次閱讀
    ELF 1技術(shù)貼|如何移植<b class='flag-5'>OpenCV</b>

    excelxlookup函數(shù)怎么使用

    XLOOKUP函數(shù)是Excel的一種查找函數(shù),用于在指定的數(shù)據(jù)區(qū)域中查找并返回與給定條件匹配的值。它是Excel 365新增的函數(shù),通常
    的頭像 發(fā)表于 12-03 10:16 ?2111次閱讀

    深入了解Excel的SUMIF函數(shù)

    Excel是一款廣泛應(yīng)用于辦公和數(shù)據(jù)分析的軟件,在眾多的內(nèi)置函數(shù),SUMIF函數(shù)是一個(gè)非常重要且常用的函數(shù)之一。本文將詳盡地介紹SUMIF函數(shù)
    的頭像 發(fā)表于 11-30 16:41 ?2071次閱讀