openCV学习笔记-三种访问像素的方法

来源:互联网 发布:刻绘大师大软件下载 编辑:程序博客网 时间:2024/06/04 18:43
//方法一:C语言数组方式访问void colorReduce(Mat& inputImage, Mat& outputImage, int div){outputImage = inputImage.clone();//复制实参到临时变量int nRow = static_cast<int>(outputImage.rows);//行数int nRowPix = static_cast<int>(outputImage.cols*outputImage.channels());//每行的像素点//遍历所有的像素点for (int i = 0; i < nRow; i++){uchar* data = (outputImage.ptr<uchar>(i));//获取行首地址for (int j = 0; j  < nRowPix; j ++){//对像素点进行操作data[j] = data[j]/div*div - div/2;}}}

  • inputImage.clone();神拷贝,这里不要用浅拷贝
  • image.cols*image.channels(); 像素点矩阵的列数x通数量道数=每行像素点
  • 对像素点的操作,对像素阈值除以再成div,再减div/2. 作用是减少颜色空间,就是减少色域

//方法二:使用迭代器void colorReduce_2(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;}}

  • 迭代器(iterator)是一种对象,它能够用来遍历标准模板库容器中的部分或全部元素,每个迭代器对象代表容器中的确定的地址。迭代器修改了常规指针的接口,所谓迭代器是一种概念上的抽象:那些行为上像迭代器的东西都可以叫做迭代器。然而迭代器有很多不同的能力,它可以把抽象容器和通用算法有机的统一起来。
  • 用到的容器Vec3b.就是一个数组,一个向量
//方法三:采用动态地址计算void colorReduce_3(Mat& inputImage, Mat& outputImage, int div){outputImage = inputImage.clone();int nRow =  static_cast<int>(outputImage.rows);int nCol = static_cast<int>(outputImage.cols);//开始遍历for (int i = 0; i < nRow; i++){for (int j = 0; j < nCol; j++){outputImage.at<Vec3b>(i,j)[0] = outputImage.at<Vec3b>(i,j)[0]/div*div + div/2;//蓝色通道,顺序是BGRoutputImage.at<Vec3b>(i,j)[1] = outputImage.at<Vec3b>(i,j)[1]/div*div + div/2;//绿色通道outputImage.at<Vec3b>(i,j)[2] = outputImage.at<Vec3b>(i,j)[2]/div*div + div/2;//红色通道}}}
  • Vec3b容器中颜色通道的顺序是BGR,一般opencv的默认顺序也是BGR
#include<opencv2/opencv.hpp>#include<opencv2/highgui/highgui.hpp>#include<iostream>using namespace cv;using namespace std;//函数声明void colorReduce(Mat& inputImage, Mat& outputImage, int div);void colorReduce_2(Mat& inputImage, Mat& outputImage, int div);void colorReduce_3(Mat& inputImage, Mat& outputImage, int div);/*==========  主函数==========*/int main(int argc, char** argv){//创建原始图像,并显示Mat srcImage = imread("haoming.jpg");imshow("srcImage",srcImage);//创建一个与源图像相同规格的图片Mat dstIamge;dstIamge.create(srcImage.rows, srcImage.cols,srcImage.type());double time = static_cast<double>(getTickCount());//起始时间colorReduce(srcImage, dstIamge, 32);time = ((double)getTickCount() - time)/getTickFrequency();cout<<"运行时间为:"<<time<<"s"<<endl;//显示颜色减少后的图片imshow("dstImage",dstIamge);waitKey(0);return 0;}//方法一:C语言数组方式访问void colorReduce(Mat& inputImage, Mat& outputImage, int div){outputImage = inputImage.clone();//复制实参到临时变量int nRow = static_cast<int>(outputImage.rows);//行数int nRowPix = static_cast<int>(outputImage.cols*outputImage.channels());//每行的像素点//遍历所有的像素点for (int i = 0; i < nRow; i++){uchar* data = (outputImage.ptr<uchar>(i));//获取行首地址for (int j = 0; j  < nRowPix; j ++){//对像素点进行操作data[j] = data[j]/div*div - div/2;}}}//方法二:使用迭代器void colorReduce_2(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;}}//方法三:采用动态地址计算void colorReduce_3(Mat& inputImage, Mat& outputImage, int div){outputImage = inputImage.clone();int nRow =  static_cast<int>(outputImage.rows);int nCol = static_cast<int>(outputImage.cols);//开始遍历for (int i = 0; i < nRow; i++){for (int j = 0; j < nCol; j++){outputImage.at<Vec3b>(i,j)[0] = outputImage.at<Vec3b>(i,j)[0]/div*div + div/2;//蓝色通道,顺序是BGRoutputImage.at<Vec3b>(i,j)[1] = outputImage.at<Vec3b>(i,j)[1]/div*div + div/2;//绿色通道outputImage.at<Vec3b>(i,j)[2] = outputImage.at<Vec3b>(i,j)[2]/div*div + div/2;//红色通道}}}





1 0
原创粉丝点击