Opencv 学习(1)
Mat提供内联函数
优点:编译的时候会把该段代码直接拷贝到自己的代码中,非内联函数的话会造成堆栈出栈的空间消耗。Mat创建与清理空间
创建:通过构造函数直接创建,
释放:
1、create时会把之前的空间清理。
2、release或者析构-引用计数为1时释放
//创建3000*4000的RGB图像,UC3为unsigned char型,3个字节,对应RGB
Mat mat(3000,4000, CV_8UC3);
//或者
mat.create(rows, cols, CV_8UC1);
3XRGB图像存放方式(连续)
isContinuous
1、判断存储空间是否连续
2、通过step记录直接地址访问连续空间
int size = mat.rows*mat.cols*mat.elemSize;
for(int i=0; i<size; i+=3)
{
mat.data[i] = 0; //B
mat.data[i+1] = 0; //G
mat.data[i+2] = 0; //R
}
- 简单的实例
#include<stdio.h>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
void PrintMs(const char *text = "")
{
static long long last = 0;
long long cur = getTickCount();
if (last == 0)
{
last = cur;
return;
}
long long ms = 0;
ms = ((double)(cur - last) / getTickFrequency()) * 1000;
if (*text != 0)
{
printf("%s = %dms\n ", text, ms);
}
last = getTickCount();
}
int main(int argc, char *argv)
{
Mat mat(3000,4000,CV_8UC3);
int es = mat.elemSize();
int size = mat.rows*mat.cols*es;
PrintMs();//计时
for (int i = 0; i < size; i += es)
{
mat.data[i] = 255; //B
mat.data[i + 1] = 100; //G
mat.data[i + 2] = 100; //R
}
PrintMs("mat.data ms");
namedWindow("img");
imshow("img", mat);
waitKey(0);
return 0;
}
- 直接访问不连续空间
1、
for (int row = 0; row < mat.rows; row++)
{
for (int col = 0; col < mat.cols; col++)
{
(&mat.data[row*mat.step])[col*es] = 0;//B
(&mat.data[row*mat.step])[col*es+1] = 0;//G
(&mat.data[row*mat.step])[col*es+2] = 255;//R
}
}
2、通过ptr接口遍历Mat(模板函数)
mat.ptr<Vec3b>(row);//返回的指针
mat.ptr<Vec3b>(row,col);
例子:
#include<stdio.h>
#include<iostream>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
using namespace std;
void PrintMs(const char *text = "")
{
static long long last = 0;
long long cur = getTickCount();
if (last == 0)
{
last = cur;
return;
}
long long ms = 0;
ms = ((double)(cur - last) / getTickFrequency()) * 1000;
if (*text != 0)
{
printf("%s = %dms\n ", text, ms);
}
last = getTickCount();
}
int main(int argc, char *argv)
{
Mat mat(3000,4000,CV_8UC3);
int es = mat.elemSize();
cout << es << endl;
int size = mat.rows*mat.cols*es;
PrintMs();
for (int i = 0; i < size; i += es)
{
mat.data[i] = 255; //B
mat.data[i + 1] = 100; //G
mat.data[i + 2] = 100; //R
}
PrintMs("mat.data ms");
for (int row = 0; row < mat.rows; row++)
{
for (int col = 0; col < mat.cols; col++)
{
(&mat.data[row*mat.step])[col*es] = 0;//B
(&mat.data[row*mat.step])[col*es+1] = 0;//G
(&mat.data[row*mat.step])[col*es+2] = 255;//R
}
}
PrintMs("mat.step ms");
//使用ptr遍历Mat
for (int row = 0; row < mat.rows; row++)
{
for (int col = 0; col < mat.cols; col++)
{
Vec3b *c = mat.ptr<Vec3b>(row, col);
c->val[0] = 0;//B
c->val[1] = 255;//G
c->val[2] = 0;//R
}
}
PrintMs("mat.ptr ms");
namedWindow("img");
imshow("img", mat);
waitKey(0);
return 0;
}
- 通过at接口遍历Mat(模板函数)
1、接口最简单的遍历法
mat.at<Vec3b>(row,col)[0] = 255;
mat.at<Vec3b>(row,col)[1] = 0;
mat.at<Vec3b>(row,col)[2] = 255;
- 通过迭代器遍历Mat
1、可以不用管mat的行列
auto it = mr.begin<Vec3b>();//自动匹配类型
auto it_end = mr.end<Vec3b>();
for(;it != it_end; ++it)
{
(*it).val[0] = 0;
(*it).val[1] = 222;
(*it).val[2] = 0;
}
所有的访问方式放在一块:
#include<stdio.h>
#include<iostream>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
using namespace std;
void PrintMs(const char *text = "")
{
static long long last = 0;
long long cur = getTickCount();
if (last == 0)
{
last = cur;
return;
}
long long ms = 0;
ms = ((double)(cur - last) / getTickFrequency()) * 1000;
if (*text != 0)
{
printf("%s = %dms\n ", text, ms);
}
last = getTickCount();
}
int main(int argc, char *argv)
{
Mat mat(3000, 4000, CV_8UC3);
int es = mat.elemSize();
cout << es << endl;
int size = mat.rows*mat.cols*es;
PrintMs();
for (int i = 0; i < size; i += es)
{
mat.data[i] = 255; //B
mat.data[i + 1] = 100; //G
mat.data[i + 2] = 100; //R
}
PrintMs("mat.data ms");
for (int row = 0; row < mat.rows; row++)
{
for (int col = 0; col < mat.cols; col++)
{
(&mat.data[row*mat.step])[col*es] = 0;//B
(&mat.data[row*mat.step])[col*es + 1] = 0;//G
(&mat.data[row*mat.step])[col*es + 2] = 255;//R
}
}
PrintMs("mat.step ms");
//使用ptr遍历Mat
for (int row = 0; row < mat.rows; row++)
{
for (int col = 0; col < mat.cols; col++)
{
Vec3b *c = mat.ptr<Vec3b>(row, col);
c->val[0] = 0;//B
c->val[1] = 255;//G
c->val[2] = 0;//R
}
}
PrintMs("mat.ptr ms");
//使用at遍历,易于调试
try //捕获异常,
{
for (int row = 0; row < mat.rows; row++)//乘2越界
{
for (int col = 0; col < mat.cols; col++)
{
Vec3b &m = mat.at<Vec3b>(row, col);
m[0] = 100;
m[1] = 100;
m[2] = 100;
}
}
}
catch (Exception &ex)
{
cout << ex.what() << endl;
}
PrintMs("mat.at ms");
PrintMs("");
auto it = mat.begin<Vec3b>();
auto it_end = mat.end<Vec3b>();
for (; it != it_end; it++)
{
(*it).val[0] = 0; //B
(*it).val[1] = 0; //G
(*it).val[2] = 255; //R
}
PrintMs("mat.auto ms");
namedWindow("img");
imshow("img", mat);
waitKey(0);
return 0;
}