像素值的读写

很多时候, 我们需要读取某个像素值, 或者设置某个像素值; 在更多的时候,我们需要对整个图像里的所有像素进行遍历。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;

}

 

posted on   gary_123  阅读(327)  评论(0编辑  收藏  举报

编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示