像素值的读写

很多时候, 我们需要读取某个像素值, 或者设置某个像素值; 在更多的时候,我们需要对整个图像里的所有像素进行遍历。OpenCV 提供了多种方法来实现图像的遍历。

1、at()函数

函数 at()来实现读取矩阵中的某个像素,或者对某个像素进行赋值操作。下面两行代码演示了 at()函数的使用方法。

如果要对图像进行遍历,可以参考下面的例程。这个例程创建了两个图像,分别是单通道的 grayim 以及 3 个通道的 colorim,然后对两个图像的所有像素值进行赋值,最后现实结果。

#include<iostream>

#include"opencv2/opencv.hpp"

using namespace std;

using namespace cv;

int main(int argc, char* argv[])

{  

Mat grayim(600,800,CV_8UC1);  

Mat colorim(600,800,CV_8UC3);

 //遍历所有像素,并设置像素值

 for (int i = 0; i < grayim.rows; ++i)  

 for (int j = 0; j < grayim.cols; ++j)   

 grayim.at<uchar>(i, j) = (i + j) % 255;  

//遍历所有像素,并设置像素值  

for (int i = 0; i < colorim.rows; ++i)   

for (int j = 0; j < colorim.cols; ++j)   

{   

Vec3b pixel;  

 pixel[0] = i % 255;

//Blue

  pixel[1] = j % 255;

//Green  

 pixel[2] = 0;

//Red  

 colorim.at<Vec3b>(i, j) = pixel;  

 }

 //显示结果

 imshow("grayim",grayim);

 imshow("colorim",colorim);

 waitKey(0);

 return 0;

}

 

通过数据指针来读写像素

使用 IplImage 结构的时候,我们会经常使用数据指针来直接操作像素。通过指针操作来访问像素是非常高效的,但是你务必十分地小心。C/C++中的指针操作是不进行类型以及越界检查的,如果指针访问出错,程序运行时有时候可能看上去一切正常,有时候却突然弹出“段错误” (segment fault) 。

当程序规模较大,且逻辑复杂时,查找指针错误十分困难。对于不熟悉指针的编程者来说,指针就如同噩梦。如果你对指针使用没有自信,则不建议直接通过指针操作来访问像素。虽然 at()函数和迭代器也不能保证对像素访问进行充分的检查,但是总是比指针操作要可靠一些。 如果你非常注重程序的运行速度,那么遍历像素时,建议使用指针。下面的
例程演示如何使用指针来遍历图像中的所有像素。此例程实现的操作跟第 3.5.1节中的例程完全相同。例程代码如下:

#include<iostream>

#include"opencv2/opencv.hpp"

using namespace std;

using namespace cv;

int main(int argc, char* argv[])

{

 Mat grayim(600,800,CV_8UC1);

 Mat colorim(600,800,CV_8UC3);

 //遍历所有像素,并设置像素值

 for (int i = 0; i < colorim.rows; ++i)  

{   

//获取第i行首像素指针  

 Vec3b *p = colorim.ptr<Vec3b>(i);  

 //对第i行的每个像素(byte一个字节)进行操作

  for (int j = 0; j < colorim.cols; ++j)  

 {   

 p[j][0] = i % 255;//Blue   

 p[j][1] = j % 255;//Green   

 p[j][2] = 0;//Red  

 }    

 }  

//遍历所有像素,并设置像素值  

for (int i = 0; i < grayim.rows; ++i)  

{  

 //获取第i行首像素指针  

 uchar *p = grayim.ptr<uchar>(i);  

 //对第i行的每个像素(byte一个字节)进行操作   

for (int j = 0; j < grayim.cols; ++j)   

 p[j] = (i + j) % 255;  

}

 imshow("grayim", grayim);

 imshow("colorim", colorim);

  waitKey(0);

 return 0;

}

 

转载于:https://www.cnblogs.com/gary-guo/p/6551504.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值