opencv操作像素

来源:互联网 发布:部落冲突更新软件 编辑:程序博客网 时间:2024/06/02 03:11

1、访问元素
使用Mat的at(int x int y)可以访问指定位置的元素。
如:

image.at<uchar>(j,i)=255;//将j行i列的像素点的值设为255

2、用指针扫描图像
使用指针访问图像的每个像素,将其值设为原来的1/8

void colorReduce(cv::Mat image,int div=64){   int rows=image.rows;   int num_per_rows=image.cols*image.channels();//每行元素的数量   for(int j=0;j<rows;i++)    {      uchar* data=image.ptr<uchar>(j);//uchar指向第j行的地址      for(int i=0;i<num_per_row;i++)          data[i]=data[i]/div*div+div/2;//处理每个像素     }}

3、使用迭代器扫描图像
要得到cv::Mat实例的迭代器,先要创建一个cv::MatIterator_的对象;
如:

cv::MatIterator_<cv::Vec3b> it;

或者是:

cv::Mat_<cv::Vec3b>::iterator it;

比如获取一个图像的开始和结尾的迭代器:

cv::Mat_<cv::Vec3b>::iterator begin=image.begin<cv::Vec3b>();//开始位置cv::Mat_<cv::Vec3b>::iterator end=image.end<cv::Vec3b>();//结尾位置for(;begin!=end;begin++){    (*begin)[0]=(*begin)[0]+10;    (*begin)[1]=(*begin)[1]+15;    (*begin)[2]=(*begin)[2]+20;}

常量迭代器定义:

cv::MatConstIterator_<cv::Vec3b> it;//或者cv::Mat_<cv::Vec3b>::const_iterator it;

4、扫描并访问相邻像素
在图像处理中计算像素值时,经常需要用它的相邻像素值。如果相邻像素在上一行火下一行,就需要同事扫描图像的多行。
以图像锐化为例子;在图像处理领域,如果从图像中减去拉普拉斯算子部分,图像的边缘就会放大,因而图像会变得尖锐;
锐化方法:
sharpened_pixel=5*current-left-right-up-down;
但是第一行,最后一行,第一列,最后一列的像素值是无法计算的。

void sharpen(const cv::Mat& iamge,cv::Mat& result){   result.create(image.size(),image.type());//分配图像空间   int nchannels=image.channels();//读取通道数   for(int j=1;j<image.rows-1;j++)//处理除了第一行和最后一行的所有行   {      const uchar* previous=image.ptr<const uchar>(j-i);//上一行      const uchar* current=image.ptr<const uchar>(j);//当前行      const uchar* next=image.ptr<const uchar>(j+i);//下一行      uchar* output=result.ptr<uchar>(j);//输出行      for(int i=nchannels;i<(image.cols-1)*nchannels;i++)       {           *output++=cv::saturate_cast<uchar>(5*current[i]-current[i-nchannels]-current[i+nchannels]-previous[i]-next[i]);        }   }//未处理的像素设置为0   result.row(0).setTo(cv::Scalar(0));   result.row(result.rows-1).setTo(cv::Scalar(0));   result.col(0).setTo(cv::Scalar(0));   result.col(result.rows-1).setTo(cv::Scalar(0)); }

cv::saturate_cast函数将结果调整到8位无符号整数范围内,就是将大于255的设为255,小于0的设为0;
setTo方法可以对矩阵中的所有元素赋值。

在对像素领域进行计算时,通常用一个核心矩阵来表示,这个矩阵展示了为得到预期的结果,如何将计算相关的像素组合起来。
cv::filter2D函数只需要一个内核,调用函数并传入图像和内核,即可返回滤波后的图像;

void sharpen2D(const cv::Mat& image,cv::Mat& result){    //构造内核    cv::Mat kernel(3,3,CV_32F,cv::Scalar(0));    //对内核赋值    kernel.at<float>(1,1)=5.0;    kernel.at<float>(0,1)=-1.0;    kernel.at<float>(2,1)=-1.0;    kernel.at<float>(1,0)=-1.0;    kernel.at<float>(1,2)=-1.0;   //对图像滤波   cv::filter2D(image,result,image.depth(),kernel);}

5、图像运算

//c[i]=a[i]+b[i];cv::add(imageA,imageB,resultC);//c[i]=a[i]+k;cv::add(imageA,cv::Scalar(k),resultC);//c[i]=k1*a[i]+k2*b[i]+k3;cv::addWeighted(imageA,k1,image2,k2,k3,resultC);

6、图像重映射
图像重映射的过程不会修改图像的值,而是把每个像素的位置重新映射到新的位置。

void wave(const cv::Mat& iamge,cv::Mat& result){   cv::Mat srcX(image.rows,image.cols,CV_32F);   cv::Mat srcY(image.rows,image.cols,CV_32F);   for(int i=0;i<image.rows;i++)     for(int j=0;j<image.clos;j++)      {         srcX.at<float>(i,j)=j;         srcY.at<float>(i,j)=i+5*sin(j/10.0);      }}
原创粉丝点击