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

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

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

编程问答

Opencv中三种操作像素的方法

發(fā)布時(shí)間:2024/9/21 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Opencv中三种操作像素的方法 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

測(cè)試環(huán)境:opencv3.1.0 + Visual Studio 2015 + win7 64位

?

opencv中有3中方法可以訪(fǎng)問(wèn)/修改圖像的像素值,分別為:

1.??????指針訪(fǎng)問(wèn)

2.??????迭代器iterator

3.??????動(dòng)態(tài)地址計(jì)算

?

測(cè)試程序如下:

  • #include "opencv2/opencv.hpp"
  • #include "iostream"
  • using namespace std;
  • using namespace cv;
  • int main()
  • {
  • //原始圖像初始化
  • Mat image(240, 320, CV_8UC3, Scalar(0, 0, 0));
  • imshow("原始圖像", image);
  • //------------------指針操作-------------------------
  • double start = static_cast<double>(getTickCount());
  • int rowNumber = image.rows;//行數(shù)
  • int colNumber = image.cols * image.channels();//每一行元素個(gè)數(shù) = 列數(shù) x 通道數(shù)
  • for (int i = 0; i < rowNumber; i++)//行循環(huán)
  • {
  • uchar* data = image.ptr<uchar>(i);//獲取第i行的首地址
  • for (int j = 0; j < colNumber; j++)//列循環(huán)
  • {
  • //開(kāi)始處理
  • data[j] = 255;
  • }
  • }
  • double end = static_cast<double>(getTickCount());
  • double time = (end - start) / getTickFrequency();
  • cout << "指針操作運(yùn)行時(shí)間為:" << time << "秒" << endl;
  • imshow("指針操作", image);
  • //---------------------------------------------------
  • //-----------------迭代器操作------------------------
  • start = static_cast<double>(getTickCount());
  • Mat_<Vec3b>::iterator it = image.begin<Vec3b>();//初始位置的迭代器
  • Mat_<Vec3b>::iterator itend = image.end<Vec3b>();//終止位置的迭代器
  • for (; it != itend; it++)
  • {
  • //處理BGR三個(gè)通道
  • (*it)[0] = 255;//B
  • (*it)[1] = 255;//G
  • (*it)[2] = 0;//R
  • }
  • end = static_cast<double>(getTickCount());
  • time = (end - start) / getTickFrequency();//計(jì)算時(shí)間
  • cout << "迭代器操作運(yùn)行時(shí)間為:" << time << "秒" << endl;
  • imshow("迭代器操作", image);
  • //---------------------------------------------------
  • //----------------動(dòng)態(tài)地址計(jì)算-----------------------
  • start = static_cast<double>(getTickCount());
  • rowNumber = image.rows;
  • colNumber = image.cols;
  • for (int i = 0; i < rowNumber; i++)
  • for (int j = 0; j < colNumber; j++)
  • {
  • //處理BGR三個(gè)通道
  • image.at<Vec3b>(i, j)[0] = 0;//B
  • image.at<Vec3b>(i, j)[1] = 255;//G
  • image.at<Vec3b>(i, j)[2] = 0;//R
  • }
  • end = static_cast<double>(getTickCount());
  • time = (end - start) / getTickFrequency();//計(jì)算時(shí)間
  • cout << "動(dòng)態(tài)地址操作運(yùn)行時(shí)間為:" << time << "秒" << endl;
  • imshow("動(dòng)態(tài)地址操作", image);
  • //---------------------------------------------------
  • cvWaitKey(0);
  • return 1;
  • }

  • 運(yùn)行結(jié)果如下:



    Debug模式下運(yùn)行時(shí)間如下:


    Release模式下運(yùn)行時(shí)間如下:



    可以看到指針操作在Debug模式和Release模式下均是最快的,動(dòng)態(tài)地址和迭代器操作稍微慢點(diǎn)。

    ?

    一些說(shuō)明:

    1.??????RGB顏色模型的矩陣如下(opencv中通道順序?yàn)锽GR):


    因此,指針操作的時(shí)候,每行的元素個(gè)數(shù)為:列數(shù)x通道數(shù)。

    Mat類(lèi)提供了ptr函數(shù)可以得到圖像任意行的首地址。

    ?

    2.??????在迭代法中,我們所需要做的僅僅是獲得圖像矩陣的begin和end,然后迭代從begin到end。將*操作符添加在迭代指針前,即可以訪(fǎng)問(wèn)當(dāng)前指向的內(nèi)容。相比于指針直接訪(fǎng)問(wèn)可能出現(xiàn)越界問(wèn)題,迭代器絕對(duì)是非常安全的方法。

    3.??????成員函數(shù)at(int y, int x)可以用來(lái)存取圖像元素,但是必須在編譯期知道圖像的數(shù)據(jù)類(lèi)型。對(duì)于彩色圖像,每個(gè)像素由三個(gè)部分構(gòu)成:藍(lán)色通道、綠色通道和紅色通道(BGR)。因此,對(duì)于一個(gè)包含彩色圖像的Mat,會(huì)返回一個(gè)由三個(gè)8位數(shù)組成的向量。Opencv將此類(lèi)型的向量定義為Vec3b,即由三個(gè)unsigned char組成的向量。這也解釋了為什么存取彩色圖像像素的代碼可以寫(xiě)出如下形式

    image.at<Vec3b>(j, i)[channel] = value;


    另外:

    而對(duì)于單通道的灰度圖像就簡(jiǎn)單很多了:

    image.at<uchar>(i,j);?

    這里要注意at中(i,j)的順序表示的是第i行第j列,跟Point(i,j)和Rect(i,j)中表示第j行第i列是相反的,如果把這個(gè)搞混了,很容易導(dǎo)致內(nèi)存異常,還不容易發(fā)現(xiàn)錯(cuò)誤。

    ?

    補(bǔ)充說(shuō)明一下:OpenCV中坐標(biāo)體系中的零點(diǎn)坐標(biāo)定義為圖片的左上角,X軸為圖像矩形的上面那條水平線(xiàn),從左往右;Y軸為圖像矩形左邊的那條垂直線(xiàn),從上往下。在Point(x,y)和Rect(x,y)中,第一個(gè)參數(shù)x代表的是元素所在圖像的列數(shù),第二個(gè)參數(shù)y代表的是元素所在圖像的行數(shù),而在at(x,y)中是相反的。






    參考文獻(xiàn)

    OpenCV3編程入門(mén)

    OpenCV坐標(biāo)系與操作像素的四種方法

    總結(jié)

    以上是生活随笔為你收集整理的Opencv中三种操作像素的方法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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