日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

OpenCV积分图函数:integral ()详解

發(fā)布時(shí)間:2023/12/18 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 OpenCV积分图函数:integral ()详解 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

?

/**************************************************************************************************/
// 函數(shù)名稱:OnMenu020503()
// 函數(shù)功能:“對(duì)角積分圖”菜單。
// 函數(shù)參數(shù):
// ? ? 輸入?yún)?shù): 無(wú)
// ? ? 輸出參數(shù): 無(wú)
// 返 回 值:void
// 創(chuàng)建作者:(QQ:370711753)
// 修改日期:2017/11/08 16:25:58
/**************************************************************************************************/
void COpenCVDlg::OnMenu020503()
{
?? ?try?? ?// 錯(cuò)誤處理
?? ?{
?? ??? ?Mat lv_MatImageIntegralSum = Mat();
?? ??? ?Mat lv_MatImageIntegralSqSum = Mat();
?? ??? ?Mat lv_MatImageIntegralTilted = Mat();
?? ??? ?Mat lv_MatImageIntegralNorm = Mat(); ?
?? ??? ?// 計(jì)算積分圖像
?? ??? ?cv::integral(m_MatImageRead, lv_MatImageIntegralSum,
?? ??? ??? ?lv_MatImageIntegralSqSum, lv_MatImageIntegralTilted, CV_64F, CV_64F);
?? ??? ?// 圖像數(shù)據(jù)歸一化
?? ??? ?cv::normalize(lv_MatImageIntegralTilted, lv_MatImageIntegralTilted, 0, 255, CV_MINMAX);
?? ??? ?convertScaleAbs(lv_MatImageIntegralTilted,lv_MatImageIntegralNorm);?? ??? ?// 精度轉(zhuǎn)換為8位INT整型?
?? ??? ?// 顯示結(jié)果
?? ??? ?HV_ImageShow(lv_MatImageIntegralNorm, m_strNameWindow);
?? ?}
?? ?catch (Exception& lv_Exception)?? ??? ?// 拋出異常
?? ?{
?? ??? ?CString lv_strException = _T("");
?? ??? ?lv_strException.Format(_T(":%s!"), lv_Exception.what());
?? ??? ?MessageBox(lv_strException, _T("錯(cuò)誤!"), MB_ICONERROR); ??
?? ??? ?return;
?? ?}
?? ?return;
}

//************************************************

Opencv中的積分圖算法

?

積分圖算法由Crow在1984年首次提出,是為了在多尺度透視投影中提高渲染速度。積分圖算法是一種快速計(jì)算圖像區(qū)域和以及圖像區(qū)域平方和的算法。它的核心思想就是對(duì)每一個(gè)圖像建立起自己的積分圖查找表,在圖像處理的階段就可以根據(jù)預(yù)先建立積分圖查找表直接查找從而實(shí)現(xiàn)對(duì)均值卷積的線性時(shí)間計(jì)算。做到了卷積執(zhí)行的時(shí)間與窗口大小無(wú)關(guān)。這種算法被應(yīng)用到基于NCC的快速匹配、對(duì)象檢測(cè)和SURF變換、邊緣檢測(cè)、基于統(tǒng)計(jì)學(xué)的快速濾波器等方面。

積分圖算法的缺點(diǎn):1、需要較大的內(nèi)存來存儲(chǔ)積分圖。2、如果圖片較大,會(huì)導(dǎo)致數(shù)據(jù)溢出。

  • 積分圖的建立

積分圖由原圖像計(jì)算而來,假設(shè)原圖大小為W*H,則積分圖大小為(W+1)*(H+1)。在積分圖(integral image)上任意坐標(biāo)(x,y)處的值,表示原圖中坐標(biāo)為(x,y)的點(diǎn)的左上角所有像素點(diǎn)像素值的和(平方和表中的就是平方和)。和表和平方和表建立公式如下:

和表:

平方和表:

如下圖所示,假設(shè)輸入圖像大小為2x2,則積分圖大小為3x3

  • 積分圖的查找

如上圖所示,如果想求輸入圖像中藍(lán)色區(qū)域內(nèi)的像素值之和(3+2+5+4=14),只要根據(jù)和表積分圖進(jìn)行兩次減法和一次減法即可:46+10-22-20=14。也就是右下角+左上角-右上角-左下角。

  • Opencv實(shí)例

opencv中計(jì)算積分圖的API介紹:

  • //API一

  • void integral( InputArray src, //輸入圖像

  • OutputArray sum, //和表

  • int sdepth = -1,); //和表深度

  • ?
  • //API二

  • void integral( InputArray src, //輸入圖像

  • OutputArray sum, //和表

  • OutputArray sqsum, //平方和表

  • int sdepth = -1, //和表深度,一般為CV_32S

  • int sqdepth = -1 ); //平方和表深度,一般為CV_32F

  • 計(jì)算積分圖并顯示:

    ? ? ? ? ? ? ? ? ? ? ? ??? ? ???

  • //

  • //opencv4.1.0

  • //

  • ?
  • #include <opencv2/opencv.hpp>

  • ?
  • using namespace std;

  • using namespace cv;

  • ?
  • int main() {

  • Mat src, sum, sqrsum;

  • src = imread("1.png", 0);

  • ?
  • integral(src, sum, sqrsum, CV_32S, CV_32F);

  • ?
  • normalize(sum, sum, 0, 255, NORM_MINMAX, CV_8UC1, Mat());

  • normalize(sqrsum, sqrsum, 0, 255, NORM_MINMAX, CV_8UC1, Mat());

  • ?
  • imshow("原圖", src);

  • imshow("和表積分圖", sum);

  • imshow("平方和表積分圖", sqrsum);

  • ?
  • waitKey(0);

  • return 0;

  • }

    • 獲取指定區(qū)域內(nèi)像素值之和

  • ?
  • //

  • //opencv4.1.0

  • //

  • ?
  • #include <opencv2/opencv.hpp>

  • ?
  • using namespace std;

  • using namespace cv;

  • ?
  • int get_block_sum(Mat &sum, int x1, int y1, int x2, int y2);

  • ?
  • int main() {

  • Mat src, sum, sqrsum;

  • src = imread("1.png", 0);

  • ?
  • //獲取ROI,便于觀察(使用ImageWatch插件)

  • int LR = 4;

  • int LC = 4;

  • int width = 6;

  • int height = 6;

  • Mat roi = src(Rect(LR, LC, width, height)).clone();

  • ?
  • //計(jì)算積分圖

  • integral(src, sum, sqrsum, CV_32S, CV_32F);

  • ?
  • //利用積分圖計(jì)算ROI內(nèi)的像素值總和

  • int value = get_block_sum(sum, LR, LC, LR + height, LC + width);

  • cout << value << endl;

  • ?
  • imshow("原圖", src);

  • waitKey(0);

  • return 0;

  • }

  • ?
  • int get_block_sum(Mat &sum, int x1, int y1, int x2, int y2) {

  • int BottomRight = sum.at<int>(x2, y2);

  • int TopLeft = sum.at<int>(x1, y1);

  • int TopRight = sum.at<int>(x1, x2);

  • int BottomLeft = sum.at<int>(x2, y1);

  • int sum_value = (BottomRight + TopLeft - TopRight - BottomLeft);

  • return sum_value;

  • }

  • ?

    //********************************************

    Paul Viola和Michael Jones在2001年首次將積分圖應(yīng)用在圖像特征提取上,在他們的論文“Rapid Object Detection using a Boosted Cascade of Simple Features”中,積分圖被當(dāng)作一種新的圖像特征表征方式,可以把檢測(cè)的Haar特征非常高效的計(jì)算出來,用于實(shí)時(shí)人臉檢測(cè)系統(tǒng)。

    積分圖是一種能夠描述全局信息的矩陣表示方法,其構(gòu)造方式是積分圖像上位置(i,j)處的值ii(i,j)是原圖像(i,j)左上角方向所有像素的和。

    利用積分圖可以可以快速的計(jì)算圖像上某一區(qū)域內(nèi)的像素和,如下圖:

    要計(jì)算區(qū)域D內(nèi)的像素和,只需要獲取到積分圖上1、2、3/4點(diǎn)各自的像素值,分別表述為ii(1)、ii(2)、ii(3)、ii(4),則區(qū)域D的像素和=ii(4)+ii(1)-ii(2)-ii(3)。

    ?

    傳統(tǒng)的計(jì)算像素和的方式需要遍歷區(qū)域D內(nèi)所有的像素,再執(zhí)行累加,計(jì)算量隨著區(qū)域D面積的增大而增大,而對(duì)積分圖方式來說,只需要在計(jì)算積分圖之后,通過簡(jiǎn)單幾次加減運(yùn)算就可以得到某一區(qū)域內(nèi)“像素和”這一特征,計(jì)算速度非常快,并且這種速度的提升效果隨著區(qū)域面積的增大和計(jì)算次數(shù)的增多表現(xiàn)的更為明顯。

    ?

    Opencv中使用integral函數(shù)計(jì)算積分圖。

    ?

    ?

    void integral( InputArray src, OutputArray sum, int sdepth=-1 );


    第一個(gè)參數(shù)src,可以使灰度圖或RGB彩色圖,單通道和三通道均可作為輸入,但每個(gè)通道的精度必須是8位int或32位、64位浮點(diǎn)型;

    ?

    第二個(gè)參數(shù)sum,積分圖,若輸入src是灰度圖,則積分圖也是灰度圖,若輸入src是RGB三通道圖,則積分圖sum也是RGB三通道彩色。sum的圖像深度是32位整型或32位、64位浮點(diǎn)型,這取決于第三個(gè)參數(shù)sdepth的定義;

    第三個(gè)參數(shù)sdepth,定義積分圖的深度(depth),32位整型或者32位、64位浮點(diǎn)型。注意圖像的深度跟圖像的通道數(shù)是無(wú)關(guān)的,相關(guān)概念可以參看這里:Opencv Mat矩陣中data、size、depth、elemSize、step等屬性的理解?;

    所以在使用sum之前,聲明即可,可以不事先定義Mat矩陣的大小和數(shù)據(jù)類型。

    ?

    ?

    #include "highgui/highgui.hpp" #include "imgproc/imgproc.hpp"using namespace cv;int main(int argc,char *argv[]) {Mat image=imread(argv[1]); //cvtColor(image,image,CV_RGB2GRAY); //原圖像是三通道,積分圖也是三通道Mat imageIntegral;integral(image,imageIntegral,CV_32F); //計(jì)算積分圖normalize(imageIntegral,imageIntegral,0,255,CV_MINMAX); //歸一化,方便顯示Mat imageIntegralNorm;convertScaleAbs(imageIntegral,imageIntegralNorm); //精度轉(zhuǎn)換為8位int整型imshow("Source Image",image);imshow("Integral Image",imageIntegralNorm);waitKey(); }


    ?

    ?

    原圖:

    ?

    積分圖:

    ?

    顯示的積分圖是經(jīng)過歸一化后的。可以看到從左上角到右下角,圖像是越來越亮的,也就是說積分圖上像素值是越來越大的。

    ?

    積分圖的圖像通道數(shù)跟原始圖像保存一致,當(dāng)計(jì)算積分圖的原始圖像是彩色圖像時(shí),積分圖也是彩色圖像,這時(shí)候積分圖計(jì)算的不是灰度,而是顏色:

    //************************************

    總結(jié)

    以上是生活随笔為你收集整理的OpenCV积分图函数:integral ()详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。