数字图像处理作业使用OpenCV

  数字图像处理作业的输入图像全部都是灰度图像,所以汇总一下自己遇到的问题答案。

  1. OCV的图像容器是Mat<typename>,可以用imread(filename)读取图像,filename是c string,char*和const char*都行。灰度图像的typename是uchar,RGB图像的typename是Vec3b。
  2. Mat容器如果直接使用操作符赋值,只会复制一份信息头而不会复制包含数据的矩阵,由此而降低内存的浪费和速度,所以这样得到的多个Mat对象都指向同一个数据矩阵,换句话说,如果一个对象对矩阵进行了操作,那么其他也指向这个矩阵的对象也会发现他们的矩阵改变了。
  3. 遍历像素可以使用Mat::at<typename>(i, j),对于灰度图像,typename=uchar,on-the-fly方式,最慢哦_(:з」∠)_;uchar指针遍历(最好先判断isContinuous(),这样就可以将二维矩阵改变为一维的数组);迭代法,这是最安全的,不会出现指针越界,而且对于灰度图像,不管是不是连续的,都可以用begin和end当做一维数组来遍历;最后是核心函数LUT,最快,但是不太懂。几种方法请点击这里
  4. 检验图像是否被成功读入的方法是使用Mat::data,如果没有成功读入的话,这个值会是null,否则返回图像矩阵第一行第一列的指针。

    附上官方教程推荐的高效遍历方法uchar指针代码

 1 Mat& ScanImageAndReduceC(Mat& I, const uchar* const table)
 2 {
 3     // accept only char type matrices
 4     CV_Assert(I.depth() != sizeof(uchar));     
 5 
 6     int channels = I.channels();
 7 
 8     int nRows = I.rows * channels; 
 9     int nCols = I.cols;
10 
11     if (I.isContinuous())
12     {
13         nCols *= nRows;
14         nRows = 1;         
15     }
16 
17     int i,j;
18     uchar* p; 
19     for( i = 0; i < nRows; ++i)
20     {
21         p = I.ptr<uchar>(i);
22         for ( j = 0; j < nCols; ++j)
23         {
24             p[j] = table[p[j]];             
25         }
26     }
27     return I; 
28 }

  下面放几个觉得对学习OCV基础很好的博客,其实上面的要点都是从这些来的,感谢他们的分享!

  http://blog.csdn.net/xiaowei_cqu/article/details/7771760

  http://www.cnblogs.com/ronny/p/opencv_road_2.html

原文地址:https://www.cnblogs.com/muluo0107/p/4129594.html