这个系列的目的是通过对OpenCV示例,进一步了解OpenCV函数的使用,不涉及具体原理。
资料地址:http://docs.opencv.org/3.0.0/dc/d16/cout_mat_8cpp-example.html
Example代码
/*
*
* cvout_sample just demonstrates the serial out capabilities of cv::Mat
* That is, cv::Mat M(...); cout << M; Now works.
*
*/
#include "opencv2/core/core.hpp"
#include <iostream>
using namespace std;
using namespace cv;
static void help()
{
cout
<< "\n------------------------------------------------------------------\n"
<< " This program shows the serial out capabilities of cv::Mat\n"
<< "That is, cv::Mat M(...); cout << M; Now works.\n"
<< "Output can be formated to OpenCV, matlab, python, numpy, csv and \n"
<< "C styles Usage:\n"
<< "./cvout_sample\n"
<< "------------------------------------------------------------------\n\n"
<< endl;
}
int main(int,char**)
{
help();
Mat I = Mat::eye(4, 4, CV_64F);
I.at<double>(1,1) = CV_PI;
cout << "I = \n" << I << ";" << endl << endl;
Mat r = Mat(10, 3, CV_8UC3);
randu(r, Scalar::all(0), Scalar::all(255));
cout << "r (default) = \n" << r << ";" << endl << endl;
cout << "r (matlab) = \n" << format(r, Formatter::FMT_MATLAB) << ";" << endl << endl;
cout << "r (python) = \n" << format(r, Formatter::FMT_PYTHON) << ";" << endl << endl;
cout << "r (numpy) = \n" << format(r, Formatter::FMT_NUMPY) << ";" << endl << endl;
cout << "r (csv) = \n" << format(r, Formatter::FMT_CSV) << ";" << endl << endl;
cout << "r (c) = \n" << format(r, Formatter::FMT_C) << ";" << endl << endl;
Point2f p(5, 1);
cout << "p = " << p << ";" << endl;
Point3f p3f(2, 6, 7);
cout << "p3f = " << p3f << ";" << endl;
vector<float> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
cout << "shortvec = " << Mat(v) << endl;
vector<Point2f> points(20);
for (size_t i = 0; i < points.size(); ++i)
points[i] = Point2f((float)(i * 5), (float)(i % 7));
cout << "points = " << points << ";" << endl;
return 0;
}
Example截图
Example分析
这个例子说明Mat类型如何使用。
Mat的定义
Mat作为一个类被声明在Mat.hpp文件中,最大的优点是不需要手动
(1)为其开辟空间;
(2)在不需要时立即将空间释放。
不需要开辟空间
先看两段代码
IplImage* gray = cvCreateImage(size,8,1);
if(src->nChannels == 3)
{
cvCvtColor(src,gray,CV_BGR2GRAY);
}
else
{
cvCopy(src,gray);
}
Mat gray;
if(src.channels() == 3)
{
cv::cvtColor(src,gray,CV_BGR2GRAY);
}
else
{
gray = src.clone();
}
以上分别是IplImage和Mat彩色图像转灰度图像的代码。可以看到Iplimage需要手动申请内存,但是Mat不需要,
这样的好处是很多时候使用Mat进行数据传递时,不需要提前知道其将要保存的图像信息,这样会使代码更加灵活。
不需要立即释放
同样先看两段代码
if(!Threshold(gray,dst,mask1))
{
cvReleaseImage(&mask);
cvReleaseImage(&gray);
cvReleaseImage(&mask1);
return false;
}
cvReleaseImage(&mask);
cvReleaseImage(&gray);
cvReleaseImage(&mask1);
return true;
if (vcvcCC.size() != 4 ||
vcvcCC[0].size() != vcvcCC[1].size() ||
vcvcCC[2].size() != vcvcCC[3].size() ||
vcvcCC[0].size()<2 || vcvcCC[2].size()<2)
{
return false;
}
return true;
以上分别采用IplIamge和Mat的bool型函数,因为IplImage需要手动释放空间,因此代码臃肿,而Mat则简便很多。
Mat现实了Matlab接口
Mat不但实现了如eye,imshow,imread,imwrite等常用的MatLab函数,并且还有很多细节,如
反色可以通过Mat negtive = 255-src;
二值化Mat bw = src < 128;
因此完全可以在使用c++工程化时达到Matlab级别的编码感官。
参考资料