上一篇介绍了Mat的数据结构和存储方式,这里跟随官网学习Mat的遍历操作,因为openCV即是处理像素,所以遍历方法是我们必须要掌握的,这部分内容官网介绍的很详细也易懂,建议大家还是读透这些基础并上手测试加深理解,提前告诉大家,后面的内容比较晦涩,官网的内容很精简不易理解,所以请打好基础。
上篇介绍了Mat数据结构和存储方式:http://blog.csdn.net/jbl20078/article/details/78842477
本章内容官网地址:https://docs.opencv.org/master/db/da5/tutorial_how_to_scan_images.html
uchar table[256];
for(int i = 0; i < sizeof(table)/sizeof(table[0]); i++){
if(i <= 100) {
table[i] = 0;
}
if(i > 100){
table[i] = 255;
}
}
那 我将这个table应用到图片中,图片就会有很强的对比(看下面对比图,上面的是应用的table)
Mat& traverseMethod1(Mat& mat,const uchar* const table){
//直接通过指针访问速度是最快的
//只能处理char 类型的matrices
CV_Assert(mat.depth() != sizeof(uchar));
//获取它有多少个通道
int channels = mat.channels();
//有多少行 多少列
int rows = mat.rows*channels;
int cols = mat.cols;
//是否连续存储的,如果连续存储直接一个for循环就是了
if(mat.isContinuous()){
cols *= rows;
rows = 1;
}
int i,j;
uchar* p;
for(i = 0; i < rows; ++i){
p = mat.ptr(i);
for(j = 0; j < cols; j++){
p[j] = table[p[j]];
}
}
return mat;
}
Mat& traverseMethod2(Mat& mat,const uchar* const table){
//安全的遍历方法,通过迭代器去遍历
CV_Assert(mat.depth() != sizeof(uchar));
const int channels = mat.channels();
switch(channels){
case 1:{
//单通道
MatIterator_ it = mat.begin();
for(;it != mat.end(); ++it){
*it = table[*it];
}
break;
}
case 4:{
//因为我这个图片是4通道的
MatIterator_ it1 = mat.begin();
for(;it1 != mat.end(); ++it1){
(*it1)[0] = table[(*it1)[0]];
(*it1)[1] = table[(*it1)[1]];
(*it1)[2] = table[(*it1)[2]];
(*it1)[3] = table[(*it1)[3]];
}
break;
}
}
return mat;
}
Mat& ScanImageAndReduceRandomAccess(Mat& I, const uchar* const table)
{
// accept only char type matrices
CV_Assert(I.depth() != sizeof(uchar));
const int channels = I.channels();
switch(channels)
{
case 1:
{
for( int i = 0; i < I.rows; ++i)
for( int j = 0; j < I.cols; ++j )
I.at(i,j) = table[I.at(i,j)];
break;
}
case 3:
{
Mat_ _I = I;
for( int i = 0; i < I.rows; ++i)
for( int j = 0; j < I.cols; ++j )
{
_I(i,j)[0] = table[_I(i,j)[0]];
_I(i,j)[1] = table[_I(i,j)[1]];
_I(i,j)[2] = table[_I(i,j)[2]];
}
I = _I;
break;
}
}
return I;
}
Mat& traverseMethod3(Mat& mat,const uchar* const table,Mat& outputMat){
//其实还有一个效率更低的方法 这边不介绍了 官方不推荐使用 是通过mat.at的方法 当确定行数和列数的时候再用吧
//最快的方法是openCV提供的 LUT函数 第一个参数接受一个mat输入 最后一个参数接受一个输出 中间一个参数是table 类型是mat
//我们自定义一个table
Mat lookUpTable(1,256,CV_8U);
uchar* p = lookUpTable.ptr();
for(int i =0 ; i < 256; ++i){
p[i] = table[i];
}
// Mat outputMat;
LUT(mat, lookUpTable, outputMat);
return outputMat;
}