Opencv 官方tutorial学习
图片是像素的

来源于Visual studio插件ImageWatch。
OpenCV官方教程
注意额外的参数
Mat image = imread( "/home/yake/Downloads/opencv-2.4.10/samples/c/lena.jpg",1 ); // CV_LOAD_IMAGE_UNCHANGED (<0) loads the image as is (including the alpha channel if present)
// CV_LOAD_IMAGE_GRAYSCALE (0) loads the image as an intensity one.
// Default: CV_LOAD_IMAGE_COLOR (>0) loads the image in the RGB format
AI助手
下面是转化为灰度图(注意注释)
if(!image.data)
{
cout<<"file not fount"<<endl;
return -1;
}
Mat gray_image;
cvtColor( image, gray_image, CV_BGR2GRAY ); // Because of imread has BGR default channel order in case of color images
imwrite( "Gray_Image.jpg", gray_image );
namedWindow( "Display window", WINDOW_AUTOSIZE );// No resize permitted! or WINDOW_NORMAL.
imshow( "Display window", image );
namedWindow( "Gray image", CV_WINDOW_AUTOSIZE );
imshow( "Gray image", gray_image );
waitKey();
AI助手
Mat is essentially a type comprising two sections: the matrix header (which encapsulates essential details like its dimensions, storage technique, and storage address) and a pointer to the matrix containing the pixel values (which can vary in dimensionality based on chosen storage methods). Notably, while the matrix header's dimensions remain consistent across instances, the overall matrix size can vary significantly from one image to another, often differing by orders of magnitude.

2. Mat与Range
为了减少内存占用, copier操作符只会复制header信息和指向该大型矩阵的指针,而不包括数据本身.
Mat A, C; // creates just the header parts
A = imread(argv[1], CV_LOAD_IMAGE_COLOR); // here we'll know the method used (allocate matrix)
Mat B(A); // Use the copy constructor
C = A;
AI助手
他们使用的Header不同, 但所指的数据却完全一致, 同样可以构建指向数据某一特定区域的Header.例如, 在构建感兴趣区域时, 可以设置一个专门针对数据某一部分的Header.
Mat D (A, Rect(10, 10, 4, 4) ); // using a rectangle
Mat E = A(Range::all(), Range(1,3)); // using row and column boundaries
AI助手
Mat D如下

官方说明较为简略 我通过网络搜索补充了相关知识。此处采用RGB编码方式 这里的矩阵D代表彩色图像BGR三色通道 因此总共有12个独立的颜色层 具体来说 则是通过计算矩阵cols与channels的乘积得出。与Matlab中的范围生成函数a:b相对应的是 行或列向量 即使是从一个起点到终点的所有元素 同时也有可能仅限于某个特定维度的数据处理 在这种情况下我们采用了完整的行数据 如前所述 在这种情况下我们采用了完整的行数据 特别地 表示的是从索引值1至3(不包含)的所有元素 因此在处理过程中我们主要关注前两个显著的颜色层 这样不仅能够减少计算复杂度 同时也能提高处理效率 并确保结果更为精确
拷贝所有的数据
Mat F = A.clone();
Mat G;
A.copyTo(G);
AI助手
这里的打印输出有个地方比较有意思
vector<float> v;
v.push_back( (float)CV_PI); v.push_back(2); v.push_back(3.01f);
cout << "Vector of floats via Mat = " << Mat(v) << endl << endl;
AI助手
你可以直接将一个Vector赋值给Mat。
3. Scan Images and get process time遍历图像并统计时间
doublet=(double)getTickCount();// do something ...t=((double)getTickCount()-t)/getTickFrequency();cout<<"Times passed in seconds: "<<t<<endl;
Instead of using RGB, we opt for BGR. However, in many cases, the memory is sufficient to sequentially store rows, allowing them to be stored one after another and forming a continuous sequence. Since all data is stored contiguously, this approach can enhance scanning efficiency. Using OpenCV's isContinuous() function allows us to determine if the data layout meets these criteria.
可以用isContinuous() 函数来检测Matrix是否是row相连的
CV_Assert(I.depth() != sizeof(uchar)); // 检测是否是char type 的matrix
int channels = I.channels();
Mat& ScanImageAndReduceC(Mat& I, const uchar* const table)
{
// accept only char type matrices
CV_Assert(I.depth() != sizeof(uchar));
int channels = I.channels();
int nRows = I.rows;
int nCols = I.cols * channels;
if (I.isContinuous())
{
nCols *= nRows;
nRows = 1;
}
int i,j;
uchar* p;
for( i = 0; i < nRows; ++i)
{
p = I.ptr<uchar>(i);
for ( j = 0; j < nCols; ++j)
{
p[j] = table[p[j]];
}
}
return I;
}
AI助手
这条语句p = I.ptr
Mat& ScanImageAndReduceIterator(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:
{
MatIterator_<uchar> it, end;
for( it = I.begin<uchar>(), end = I.end<uchar>(); it != end; ++it)
*it = table[*it];
break;
}
case 3:
{
MatIterator_<Vec3b> it, end;
for( it = I.begin<Vec3b>(), end = I.end<Vec3b>(); it != end; ++it)
{
(*it)[0] = table[(*it)[0]];
(*it)[1] = table[(*it)[1]];
(*it)[2] = table[(*it)[2]];
}
}
}
return I;
}
AI助手
对于彩色图像中的每个通道层(即蓝色、绿色和红色三个通道),每一个大列都会对应这三个item。这通常被定义为一个Vec3b类型的向量(即vec<uchar, 3>)。获取子通道可以通过操作符[ ]来实现。需要注意的是,在遍历每一列时,默认会跳转至下一行数据。
Mat lookUpTable(1, 256, CV_8U);
uchar* p = lookUpTable.data;
for( int i = 0; i < 256; ++i)
p[i] = table[i];
LUT(I, lookUpTable, J);
优先采用内置函数以提升效率。LUT函数通过查找表的形式处理原始图像I中的每个像素值,并将其映射至结果图像J中。Lookup Table将每个阈值范围划分为5个区间以实现降噪效果。

