图像识别与处理之Opencv——像素值的读写

来源:互联网 发布:相貌评分软件 编辑:程序博客网 时间:2024/05/29 09:04

像素值的读写
很多时候,我们需要读取某个像素值,或者设置某个像素值;在更多的时候,我们需要对整个图像里的所有像素进行遍历。 OpenCV 提供了多种方法来实现图像的遍历。
1 at()函数
函数 at()来实现读去矩阵中的某个像素,或者对某个像素进行赋值操作。 下面两行代码演示了 at()函数的使用方法。

uchar value = grayim.at<uchar>(i,j);//读出第 i 行第 j 列像素值grayim.at<uchar>(i,j)=128; //将第 i 行第 j 列像素值设置为 128

如果要对图像进行遍历,可以参考下面的例程。这个例程创建了两个图像,分别是单通道的 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; //Bluepixel[1] = j%255; //Greenpixel[2] = 0; //Redcolorim.at<Vec3b>(i,j) = pixel;}//显示结果namedWindow("grayim", 1);imshow("grayim", grayim);imshow("colorim", colorim);waitKey(0);return 0;}

这里写图片描述

这里写图片描述

2 使用迭代器
如果你熟悉 C++的 STL 库,那一定了解迭代器(iterator)的使用。迭代器可
以方便地遍历所有元素。 Mat 也增加了迭代器的支持,以便于矩阵元素的遍历。
下面的例程功能跟上一节的例程类似,但是由于使用了迭代器,而不是使用行数
和列数来遍历,所以这儿没有了 i 和 j 变量,图像的像素值设置为一个随机数。

#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);//遍历所有像素,并设置像素值MatIterator_<uchar> grayit, grayend;for( grayit = grayim.begin<uchar>(), grayend =grayim.end<uchar>(); grayit != grayend; ++grayit)*grayit = rand()%255;//遍历所有像素,并设置像素值MatIterator_<Vec3b> colorit, colorend;for( colorit = colorim.begin<Vec3b>(), colorend =colorim.end<Vec3b>(); colorit != colorend; ++colorit){(*colorit)[0] = rand()%255; //Blue(*colorit)[1] = rand()%255; //Green(*colorit)[2] = rand()%255; //Red}//显示结果imshow("grayim", grayim);imshow("colorim", colorim);waitKey(0);return 0;}

这里写图片描述

3.通过数据指针
使用 IplImage 结构的时候,我们会经常使用数据指针来直接操作像素。通过指针操作来访问像素是非常高效的,但是你务必十分地小心。 C/C++中的指针操作是不进行类型以及越界检查的,如果指针访问出错,程序运行时有时候可能看31上去一切正常,有时候却突然弹出“段错误”(segment fault)。当程序规模较大,且逻辑复杂时,查找指针错误十分困难。 对于不熟悉指针的编程者来说,指针就如同噩梦。 如果你对指针使用没有自信,则不建议直接通过指针操作来访问像素。虽然 at()函数和迭代器也不能保证对像素访问进行充分的检查,但是总是比指针操作要可靠一些。
如果你非常注重程序的运行速度,那么遍历像素时,建议使用指。 下面的例程演示如何使用指针来遍历图像中的所有像素。例程代码如下:

#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){//获取第 i 行首像素指针uchar * p = grayim.ptr<uchar>(i);//对第 i 行的每个像素(byte)操作for( int j = 0; j < grayim.cols; ++j )p[j] = (i+j)%255;}//遍历所有像素,并设置像素值for( int i = 0; i < colorim.rows; ++i){//获取第 i 行首像素指针Vec3b * p = colorim.ptr<Vec3b>(i);for( int j = 0; j < colorim.cols; ++j ){p[j][0] = i%255; //Bluep[j][1] = j%255; //Greenp[j][2] = 0; //Red}}//显示结果imshow("grayim", grayim);imshow("colorim", colorim);waitKey(0);return 0;}
阅读全文
0 0
原创粉丝点击