图像容器Mat:访问图像像素

2025-11-27 07:15:40

1、关于Mat:

基本上讲,Mat是一个类,由两部分组成:矩阵头;

............................................ 一个指向像素值矩阵的指针。

使用Mat进行图像操作时,使每个Mat对象创建自己的矩阵头,但共享同一个矩阵。这通过使用矩阵指针指向同一地址实现。

例如:在拷贝图像时,只拷贝矩阵头和矩阵指针,而不拷贝矩阵。

Mat A, C;                                 // 只创建信息头部分

A = imread(argv[1], CV_LOAD_IMAGE_COLOR); // 这里为矩阵开辟内存

Mat B(A);                                 // 使用拷贝构造函数

C = A;                                    // 赋值运算符

图像容器Mat:访问图像像素

2、Mat公共属性:

Mat的成员函数含义以下几个公共属性;

Mat信息头:

cv::Mat::Mat(

int rows,

int cols,

int type 

)

cv::Mat::Mat(

int ndims,

const int *sizes,

int type 

)

cv::Mat::Mat(

const std::vector< int > & sizes,

int type 

)

cv::Mat::Mat(

Size size,

int type,

void * data,

size_t step = AUTO_STEP 

)

图像容器Mat:访问图像像素

3、常见成员函数:

// make a 7x7 complex matrix filled with 1+3j.

Mat M(7,7,CV_32FC2,Scalar(1,3));

// and now turn M to a 100x60 15-channel 8-bit matrix.

// The old content will be deallocated

M.create(100,60,CV_8UC(15));

IplImage*转Mat

IplImage* img = cvLoadImage("greatwave.png", 1);Mat mtx(img); // convert IplImage* -> Mat

具体成员函数如下图所示:

图像容器Mat:访问图像像素

图像容器Mat:访问图像像素

图像容器Mat:访问图像像素

图像容器Mat:访问图像像素

4、Mat类型存储格式:

存储像素值需要指定颜色空间和数据类型。

对灰度图像,一般存放<uchar>数据类型;

对RGB彩色图像,一般存放<Vec3b>数据类型;

单通道灰度图数据存放格式:如图所示

多通道彩色图像数据存放格式:如图所示

通常,图像的数据都是连续存放在内存中的。

使用isContinuous()函数来判断图像十足是否为连续的。

图像容器Mat:访问图像像素

图像容器Mat:访问图像像素

5、访问图像像素:

方法一:“NaNr<>”和内存访问操作符“[]”

Mat最直接访问方法是通过NaNr<>函数得到一行的指针,并使用[]操作符访问某一列的像素值。

//访问图像像素

//在每行定义一个指针,然后在内存上直接连续访问;

Mat& mImageReduce_C(Mat &mImg, int mGreyThresh)

{

         //只接受字符类型的图像

         CV_Assert(mImg.depth()!=sizeof(uchar));

         int mChannels=mImg.channels();

         int mRows=mImg.rows;

         int mCols=mImg.cols*mChannels;//根据图像存储结构

         if (mImg.isContinuous())//一般情况下isContinuous()为true;

         {

                   mCols *= mRows;

                   mRows =1;//图像内存存储形式

         }

         uchar *mData;

         for (int i=0;i<mRows;++i)

         {

                   mData = mImgNaNr<uchar>(i);

                   for (int j=0;j<mCols;j++)

                   {

                            if (mData[j]<mGreyThresh)

                            {

                                     mData[j]=0;

                            }

                            else

                                     continue;

                   }

         }

         return mImg;

}

图像容器Mat:访问图像像素

图像容器Mat:访问图像像素

6、方法二:迭代器,较安全方法;

OpenCV中,迭代器会访问每一列然后自动跳到下一行,不管内存是否isContinous。

【注】:三通道图像定义<Vec3b>格式的迭代器。

这种方式虽然安全,速度较慢。

Mat& mImageReduce_Interator(Mat &mImg, int mGreyThresh)

{

         CV_Assert(mImg.depth()!=sizeof(uchar));

         const int mChannels = mImg.channels();

         switch(mChannels)

         {

         case 1:

                   {

                            MatIterator_<uchar> it,end;

                            for (it=mImg.begin<uchar>(),end=mImg.end<uchar>();it!=end; it++)

                            {

                                     if ((*it)<mGreyThresh)

                                     {

                                               (*it)=0;

                                     }

                                     else

                                               continue;

                            }

                            break;

                   }

         case 3:

                   {

                            MatIterator_<Vec3b> it,end;

                            for (it=mImg.begin<Vec3b>(),end=mImg.end<Vec3b>();it!=end;++it)

                            {

                                     for (int i=0;i<3;i++)

                                     {

                                               if ((*it)[i]<mGreyThresh)

                                               {

                                                        (*it)[i]=0;

                                               }

                                               else

                                                        continue;

                                     }

                            }

                   }

         }

         return mImg;

}

图像容器Mat:访问图像像素

图像容器Mat:访问图像像素

图像容器Mat:访问图像像素

7、方法三:动态地址访问

功能:访问任意的某一行某一列;更适用于随机访问,在连续扫描点时不推荐。

Mat& mImageReduce_Random(Mat &mImg, int mGrayThresh)

{

         CV_Assert(mImg.depth() != sizeof(uchar));

         const int mChannels = mImg.channels();

         switch(mChannels)

         {

         case 1:

                   {

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

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

                                               if (mImg.at<uchar>(i,j)<mGrayThresh)

                                                        mImg.at<uchar>(i,j)=0;

                   }

                   break;

         case 3:

                   {

                            Mat_<Vec3b> _mImg =mImg;

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

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

                                               for (int k=0;k<3;k++)

                                               {

                                                        if (_mImg(i,j)[k]<mGrayThresh)

                                                                 _mImg(i,j)[k]=0;

                                               }

                                     mImg=_mImg;

                                     break;

                   }

         }

         return mImg;

}

图像容器Mat:访问图像像素

图像容器Mat:访问图像像素

图像容器Mat:访问图像像素

声明:本网站引用、摘录或转载内容仅供网站访问者交流或参考,不代表本站立场,如存在版权或非法内容,请联系站长删除,联系邮箱:site.kefu@qq.com。
猜你喜欢