OpenCV2 访问各个像素点的方法

内容来自《OpenCV 2 Computer Vision Application Programming Cookbook》

OpenCV2 访问图像的各个像素有各种方法

我们来用各种方法来实现减少图像的颜色数量

color = color/div*div +div/2;

若div为8,则原来RGB每个通道的256种颜色减少为32种。

若div为64,则原来RGB每个通道的256种颜色减少为4种,此时三通道所有能表示的颜色有4×4×4 = 64 种

首先,我们来看一个函数

**C++:**uchar*Mat::ptr(int **i**=0)
i 是行号,返回的是该行数据的指针。
在OpenCV中,一张3通道图像的一个像素点是按BGR的顺序存储的。
先来看看第一种访问方案
void colorReduce1(cv::Mat& image, cv::Mat& result, int div=64){    int nrow = image.rows;    int ncol = image.cols * image.channels();    for(int i=0; i<nrow; i++){        uchar* data = image.ptr<uchar>(i);        uchar* data_out = result.ptr<uchar>(i);        for(int j=0; j<ncol; j++){            data_out[j] = data[j]/div*div +div/2;        }    }}

第二种方案:

先来看如下函数:

C++:boolMat::isContinuous()const

C++:MatMat::reshape(int cn, int rows=0)const

出于性能方面的考虑,在图像每一行的最后可能会填充一些像素,这样图像的数据就不是连续的了

我们可以用函数isContinuous()来判断图像的数据是否连续

reshape函数的作用如下:

Changes the shape and/or the number of channels of a 2D matrix without copying the data.

这样,我们就提出了对第一种方法的改进

void colorReduce2(cv::Mat& image, cv::Mat& result, int div){    if(image.isContinuous()){        image.reshape(1,image.cols*image.rows);    }    int nrow = image.rows;    int ncol = image.cols * image.channels();    for(int i=0; i<nrow; i++){        uchar* data = image.ptr<uchar>(i);        uchar* data_out = result.ptr<uchar>(i);        for(int j=0; j<ncol; j++){            data_out[j] = data[j]/div*div +div/2;        }    }}
第三种方案:
先来看看下面的函数
**C++:**template T&Mat::at(int **i**, int **j**)
其作用是Returns a reference to the specified array element.
void colorReduce3(cv::Mat& image, cv::Mat& result, int div){    int nrow = image.rows;    int ncol = image.cols * image.channels();    for(int i=0; i<nrow; i++){        for(int j=0; j<ncol; j++){            image.at<cv::Vec3b>(j,i)[0]= image.at<cv::Vec3b>(j,i)[0]/div*div + div/2;            image.at<cv::Vec3b>(j,i)[1]= image.at<cv::Vec3b>(j,i)[1]/div*div + div/2;            image.at<cv::Vec3b>(j,i)[2]= image.at<cv::Vec3b>(j,i)[2]/div*div + div/2;        }    }}
第四种方案是使用迭代器
会使用到如下函数:
**C++:**templateMatIterator_<_Tp>Mat::begin()
**C++:**MatIterator_<_Tp>Mat::end()
void colorReduce4(cv::Mat& image, cv::Mat& result, int div){    cv::Mat_<cv::Vec3b>::iterator it = image.begin<cv::Vec3b>();    cv::Mat_<cv::Vec3b>::iterator itend = image.end<cv::Vec3b>();    cv::Mat_<cv::Vec3b>::iterator itout = result.begin<cv::Vec3b>();    for(; it!=itend; ++it,++itout){        (*itout)[0] = (*it)[0]/div*div + div/2;        (*itout)[1] = (*it)[1]/div*div + div/2;        (*itout)[2] = (*it)[2]/div*div + div/2;    }}

OpenCV2 访问各个像素点的方法

原文链接: https://www.cnblogs.com/xianglan/archive/2011/07/30/2122302.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/29567

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月8日 上午7:02
下一篇 2023年2月8日 上午7:02

相关推荐