OpenCV —图像像素操作(C++结构)

来源:互联网 发布:数控铣床编程实例有图 编辑:程序博客网 时间:2024/06/03 18:35

http://blog.csdn.net/armily/article/details/8934470

转自:http://blog.csdn.net/a390641326/article/details/8686501

//因为本人接触OpenCV时已经出2.4.3版本了(写这笔记时已经更新到2.4.4),所以直接学习2版本的方法,既然更新使用C++,添加类,必然是为了使用更方便//而且C++类结构,不必过多担心分配的内存,类析构时会释放相应内存空间//因此关于1.0之前C接口的方式就不关注了,1.0版本的中文资料比较多,请自行搜索

1. at方法

使用at模板函数能访问某行某列的像素

例如:

img1.at<cv::Vec3b>(j,i)

访问其各个通道:

img1.at<cv::Vec3b>(j,i)[0]   b通道

img1.at<cv::Vec3b>(j,i)[1]   g通道

img1.at<cv::Vec3b>(j,i)[2]    r通道

2.ptr方法

使用ptr模板可以得到行数据的头指针

uchar * data=img1.ptr<uchar>(j);//得到j行指针(储存行数据的地址)

访问第i个像素各个通道:

本质是根据指针移步实现,根据图像结构来移步

data[i*img1.nchanles+0]

data[i*img1.nchanles+1]

data[i*img1.nchanles+2]

3.iterator方法(迭代器)

迭代器方法,类似一维数组的模式,利用迭代器操作,方便操作像素

cv::Mat_<cv::Vec3b>::iterator it=img1.begin<cv::Vec3b>();cv::Mat_<cv::Vec3b>::iterator it_end=img1.end<cv::Vec3b>();

访问像素:

(*it)[0] b通道

(*it)[1] g通道

(*it)[2] r通道

it++

下面用代码来演示以上3中方法对读取图像所有数据,更利于理解,

为显示数据少,特自己制作了一个9×8的图像

图像和代码打包发到资源,有兴趣可以下载来看(1分),点击打开链接

[html] view plaincopy
  1. Mat img1=imread("d:\\demo1.bmp");//9*8  
  2.     namedWindow("demo");  
  3.     imshow("demo",img1);  
  4.     int i,j;  
  5.     //方法1:at方法  
  6.     cout<<"方法1:at方法"<<endl;  
  7.     cout<<"-----------------------------------------------"<<endl;  
  8.     for(j=0;j<img1.rows;j++)//按照图像布局打印数值  
  9.     {  
  10.         for(i=0;i<img1.cols;i++) //注意J和I的参数顺序,表示第I行J列  
  11.         {  
  12.             cout<<(int)img1.at<cv::Vec3b>(j,i)[0];//b通道  
  13.             //cout<<" ";  
  14.             cout<<(int)img1.at<cv::Vec3b>(j,i)[1];//g通道  
  15.             //cout<<" ";  
  16.             cout<<(int)img1.at<cv::Vec3b>(j,i)[2];//r通道  
  17.             //cout<<" ";  
  18.             cout<<"\t";  
  19.   
  20.         }  
  21.         cout<<endl;  
  22.     }  
  23.     ////////////////////////////////////////////////////////  
  24.     cout<<"-----------------------------------------------"<<endl;  
  25.     //方法2:ptr方法  
  26.     cout<<"方法2:ptr方法"<<endl;  
  27.     cout<<"-----------------------------------------------"<<endl;  
  28.     for(j=0;j<img1.rows;j++)  
  29.     {  
  30.         uchar * data=img1.ptr<uchar>(j);//得到行指针(储存行数据的地址)  
  31.         for (i=0;i<img1.cols*img1.channels();i++)//行数据的长度为 列数*通道数  
  32.         {  
  33.             //仿照方式格式打印出来  
  34.             cout<<(int)data[i];////b通道  
  35.             i++;  
  36.             cout<<(int)data[i];//g通道  
  37.             i++;  
  38.             cout<<(int)data[i];//r通道  
  39.             cout<<"\t";  
  40.   
  41.   
  42.         }  
  43.         cout<<endl;  
  44.     }  
  45.     cout<<"-----------------------------------------------"<<endl;  
  46.     cout<<"方法3:iterator方法"<<endl;//  
  47.     cout<<"-----------------------------------------------"<<endl;  
  48.     cv::Mat_<cv::Vec3b>::iterator it=img1.begin<cv::Vec3b>();  
  49.     cv::Mat_<cv::Vec3b>::iterator it_end=img1.end<cv::Vec3b>();  
  50.     for (i=0;it!=it_end;it++)//类似一维数组了  
  51.     {  
  52.         cout<<(int)(*it)[0];//b  
  53.         cout<<(int)(*it)[1];//g  
  54.         cout<<(int)(*it)[2];//r  
  55.         cout<<"\t";  
  56.         i++;  
  57.         if (i>0&&i%img1.cols==0)  
  58.         {  
  59.             cout<<endl;//  
  60.         }  
  61.   
  62.     }  
  63.   
  64.     cout<<"-----------------------------------------------"<<endl;  
  65.     waitKey(0);  
  66.     return 0;  

原创粉丝点击