OpenCV操作像素的几种方法(单个像素|操作多像素|遍历像素)

操作单个像素:

at()用來訪問像素,可返回左值或右值,所以我們可用at()得到或改變某個像素值,這函式使用模板,所以使用時除了輸入位置,還必須需入影像的像素型態,使用at()函式時,輸入參數順序同樣為先高再寬。。

  • OpenCV改變像素:template T& Mat::at(int i, int j)
  • OpenCV讀取像素:template const T& Mat::at(int i, int j) const
  • 在灰階圖中,OpenCV裡可用uchar代替uncigned char,在彩色圖中,OpenCV裡可用Vec3b代替將3個uchar組成的容器(vector),且可在後面加上[],註明是要操作此像素的哪個通道。

下面操作一個8位元灰階圖,分別改變某個像素的值,以及查看此像素的值:

Mat gray_img(100, 100, CV_8U, Scalar(100));
gray_img.at<uchar>(30,20) =255;            
uchar value1 = gray_img.at<uchar>(30,20);

下面分別改變彩色圖某個像素的第一通道值,以及查看此像素第一通道的值:

Mat color_img(100, 100, CV_8UC3, Scalar(200,100,0));
img.at<Vec3b>(30,20)[0] =255;        
uchar value2 = img.at<Vec3b>(30,20)[0];

操作像素

ptr函式輸入指定列,返回一個指標指向此列的第一個像素,通常為尋訪影像用到,ptr可讀取或改變像素值,同樣使用模板,所以也必須需入影像的像素型態。

  • OpenCV改變像素:template T* Mat::ptr(int i=0)
  • OpenCV讀取像素:template const T* Mat::ptr(int i=0) const

操作多像素(像素巡访)(at、ptr)

   当我们进行图片处理是,可能需要遍历所有像素,比如我们改变一张图的灰度值,让所有的像素增加30,这时候我们就需要遍历整个图片的所有像素,这边介绍OpenCV的三种方法(1, at()   2, ptr()   3, 迭代器)来遍历Mat所有像素.

  •  at() 可用来读取和修改某个像素值,通常对随机位置的像素进行读写,就效率  而言并不适合用来遍历所有像素

示例:  让所有像素加10;

int widthLimit = img.channels()*img.colos;
   for(int height=0; height<img.rows; height++)
  {
     for(int width=0; width<widthLimit; width++)
      {
        img.at<uchar>(height,width) += 10;
       }
   }

ptr()函数返回指针,指向图片指定列的首像素,使用时需要输入像素深度和第几列,对于一个深度8位元的图,我们可以用img.ptr(j)指定第j列的第一个像素,接着逐列遍历,最后访问到所有像素,这种方法运行速度比at()快,在解析度大或是重视效率的地方是比较好的方法,以下是用ptr()来读取img的所有像素,并让所有像素值加10:

int widthLimit = img.channels()* img.colos;
 for(int height=0; height<img.rows; height++){
     uchar* data = img.ptr<uchar>(height);
          for(int width=0; width< widthLimit; width++){
                 data[width] +=10;
                }
       }

迭代器方法

    OpenCV有为Mat提供与STL迭代器兼容的迭代器,使用时需指定数据类型,以下示例是用迭代器来访问img的所有像素,并让所有像素值增加10:

if(img.channels()==1)
{
   Mat_<uchar>::iterator   it    = img.begin<uchar>();
   Mat_<uchar>::iterator   itend = img.end<uchar>();
   for(; it != itend; it++){
      (*it) += 10;
     }
}else if(img.channels()==3)
{
    Mat_<Vec3b>::iterator it = img.begin<Vec3b>();
    Mat_<Vec3b>::iterator itend = img.end<Vector>();
    for(;it != itend; it++){
      (*it)[0] += 10;
      (*it)[1] += 10;
      (*it)[2] += 10;
      }
}
原文地址:https://www.cnblogs.com/zl1991/p/14087382.html