opencv访问图像中每个像素的值——方法总结

    1.任何图像处理算法,都是基于对每个像素的操作。

    2.任何opencv提供的图像处理库函数,只要了解算法原理,都可以写出具有相同功能的程序。

访问图像中每个像素的值:

方法一:用指针访问像素

void colorReduce(Mat& inputImage, Mat& outputImage, int div)
{
 //参数准备
 outputImage = inputImage.clone();//复制实参到临时变量
 int rowNumber = outputImage.rows;//行数
 int colNumber = outputImage.cols*outputImage.channels();//列数*通道数=图像每行元素的个数
 
//双重循环,遍历所有像素值
for (int i = 0; i < rowNumber; i++) {
  uchar* data = outputImage.ptr<uchar>(i);//ptr函数可以获取图像第i行的首地址
  for (int j = 0; j < colNumber; j++)//列循环
  {
   //开始处理每个像素
   data[j] = data[j] / div*div + div / 2;
  }
 }
}

    备注:.clone、.rows、.cols、.channels()分别表示图像复制、读取图像行数、列数、通道数,灰度图像通道数为1,RGB图像通道数为3。opencv中的Mat类提供了ptr函数(作用:读取图像任意行的首地址),data[j]则表示第i行j列的具体像素值。

方法二:用迭代器操作像素

void colorReduce(Mat& inputImage, Mat& outputImage,int div)
{
  outputImage = inputImage.clone();//复制实参到临时变量
  //获取迭代器
  Mat_<Vec3b>::iterator it = outputImage.begin<Vec3b>();//初始位置的迭代器
  Mat_<Vec3b>::iterator itend = outputImage.end<Vec3b>();//终止位置的迭代器

  //存取彩色图像像素
  for (; it != itend; ++it) 
  {
    //处理每个像素
    (*it)[0] = (*it)[0] / div*div + div / 2;
    (*it)[1] = (*it)[1] / div*div + div / 2;
    (*it)[2] = (*it)[2] / div*div + div / 2;
  }
}

    备注:使用迭代器读取图像像素,可以防止访问越界的问题。迭代法通过获取图像矩阵的初始位置begin和终止位置end,*it表示访问当前指向的内容,++it表示从初始位置访问到终止位置。

方法三:用动态地址计算

void colorReduce(Mat& inputImage, Mat& outputImage, int div)
{
  outputImage = inputImage.clone();//图像复制
  int rowNumber = outputImage.rows;//行数
  int colNumber = outputImage.cols;//列数

  //双重循环,处理图像每一个像素
 for (int i = 0; i < rowNumber; i++)//行循环
 {
    for (int j = 0; j < colNumber; j++)//列循环
    {
        outputImage.at<Vec3b>(i, j)[0] = outputImage.at<Vec3b>(i, j)[0] / div*div + div / 2;//[0]蓝色通道
        outputImage.at<Vec3b>(i, j)[1] = outputImage.at<Vec3b>(i, j)[1] / div*div + div / 2;//[1]绿色通道
        outputImage.at<Vec3b>(i, j)[2] = outputImage.at<Vec3b>(i, j)[2] / div*div + div / 2;//[2]红色通道
        /*outputImage.at<uchar>(i, j) = outputImage.at<uchar>(i, j)/ div*div + div / 2; */ //单通道
    }
 }
}

    备注:opencv中的Mat类提供了成员函数 at(int y, int x) 可以用来存取图像元素,但必须要知道图像的数据类型和通道数。彩色图像由三通道构成:蓝色通道、绿色通道、红色通道(BGR存储方式),每个通道8位,因而使用Vec3b。具体参考如下表格:  c1,c2,c3......表示通道数,灰度图只有1个通道(c1)。

c1c2c3c4c6
ucharucharVec2bVec3bVec4b
shortshortVec2sVec3sVec4s
int intVec2iVec3iVec4i
floatfloatVec2fVec3fVec4fVec6f
doubledoubleVec2dVec3dVec4dVec6d

  附录:数据类型及其取值范围

数值具体类型取值范围
CV_8U8 位无符号整数(0…..255)
CV_8S8 位符号整数(-128…..127)
CV_16U16 位无符号整数(0……65535)
CV_16S16 位符号整数(-32768…..32767)
CV_32S32 位符号整数(-2147483648……2147483647)
CV_32F32 位浮点数(-FLT_MAX ………FLT_MAX,INF,NAN)
CV_64F64 位浮点数(-DBL_MAX ……….DBL_MAX,INF,NAN)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值