1 Mat对象的构造方法
Mat类提供了构造函数、复制构造函数与赋值构造函数来初始化一个对象。下面选取了Opencv中的部分源代码:
1 //! default constructor 2 Mat(); 3 //! constructs 2D matrix of the specified size and type 4 // (_type is CV_8UC1, CV_64FC3, CV_32SC(12) etc.) 5 Mat(int rows, int cols, int type); 6 Mat(Size size, int type); 7 //! constucts 2D matrix and fills it with the specified value _s. 8 Mat(int rows, int cols, int type, const Scalar& s); 9 Mat(Size size, int type, const Scalar& s); 10 11 //! constructs n-dimensional matrix 12 Mat(int ndims, const int* sizes, int type); 13 Mat(int ndims, const int* sizes, int type, const Scalar& s); 14 15 //! copy constructor 16 Mat(const Mat& m); 17 //! constructor for matrix headers pointing to user-allocated data 18 Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP); 19 Mat(Size size, int type, void* data, size_t step=AUTO_STEP); 20 Mat(int ndims, const int* sizes, int type, void* data, const size_t* steps=0); 21 22 //! creates a matrix header for a part of the bigger matrix 23 Mat(const Mat& m, const Range& rowRange, const Range& colRange=Range::all()); 24 Mat(const Mat& m, const Rect& roi); 25 Mat(const Mat& m, const Range* ranges); 26 //! converts old-style CvMat to the new matrix; the data is not copied by default 27 Mat(const CvMat* m, bool copyData=false); 28 //! converts old-style CvMatND to the new matrix; the data is not copied by default 29 Mat(const CvMatND* m, bool copyData=false); 30 //! converts old-style IplImage to the new matrix; the data is not copied by default 31 Mat(const IplImage* img, bool copyData=false); 32 //! builds matrix from std::vector with or without copying the data 33 template<typename _Tp> explicit Mat(const vector<_Tp>& vec, bool copyData=false); 34 //! builds matrix from cv::Vec; the data is copied by default 35 template<typename _Tp, int n> explicit Mat(const Vec<_Tp, n>& vec, bool copyData=true); 36 //! builds matrix from cv::Matx; the data is copied by default 37 template<typename _Tp, int m, int n> explicit Mat(const Matx<_Tp, m, n>& mtx, bool copyData=true); 38 //! builds matrix from a 2D point 39 template<typename _Tp> explicit Mat(const Point_<_Tp>& pt, bool copyData=true); 40 //! builds matrix from a 3D point 41 template<typename _Tp> explicit Mat(const Point3_<_Tp>& pt, bool copyData=true); 42 //! builds matrix from comma initializer 43 template<typename _Tp> explicit Mat(const MatCommaInitializer_<_Tp>& commaInitializer); 44 45 //! download data from GpuMat 46 explicit Mat(const gpu::GpuMat& m); 47 48 //! destructor - calls release() 49 ~Mat(); 50 //! assignment operators 51 Mat& operator = (const Mat& m); 52 Mat& operator = (const MatExpr& expr);
我们可以采用上述函数构造Mat对象,如
1 Mat A, C; //缺省构造函数,只创建了头部分,没有实际数据 2 A = imread("1.jpg", CV_LOAD_IMAGE_COLOR);//将图片1数据读入A中 3 Mat B(A); //使用复制构造函数使B指向A的数据 4 C=A; //使用赋值构造函数使C指向A的数据 5 Mat D(2,2, CV_8UC3, Scalar(0,0,255)) //利用带参数的构造函数创建对象
Mat对象采用了引用计算的方法,A,C,B只是头不同,但都指向相同的数据,每当复制一个Mat对象的头时,引用计数加1,当清除一个头时,引用计数减1,当引用计数为0时,释放资源。为了复制数据,可以采用Mat类中的clone()和copyTo()方法。
2 用Mat类中的方法处理图像
利用at方法改变图像中每一个位置的像素值
Process(Mat & image) {
for(int i=0;i<image.rows;i++)
for(int j=0;j<image.cols;j++)
{ if (image.channels() == 1) { // gray-level image image.at<uchar>(j,i)= 255; } else if (image.channels() == 3) { // color image image.at<cv::Vec3b>(j,i)[0]= 255; image.at<cv::Vec3b>(j,i)[1]= 255; image.at<cv::Vec3b>(j,i)[2]= 255; }
} }
利用ptr方法可以进行同样的操作
Process(Mat & image) { int row=image.rows; int cn=image.cols*image.channel();//每一行的数据 for(int i=0;i<row;i++) { //得到第i行的地址 uchar* data= image.ptr<uchar>(j); for(int j=0;j<cn;j++) { data[j]=255; } } }
使用迭代器
Process(Mat & image) {
if (image.channels() == 1) { // gray-level image Mat_<uchar>::iterator it=image.begin<uchar>();
Mat_<uchar>::iterator itend=image.end<uchar>();
for(;it!=itend;it++)
*it=255; } else if (image.channels() == 3) { // color image Mat_<Vec3b>::iterator it=image.begin<Vec3b>();
Mat_<Vec3b>::iterator itend=image.end<Vec3b>();
for(;it!=itend;it++)
{
(*it)[0]=255;
(*it)[1]=255;
(*it)[2]=255;
}
}
}
利用邻域像素点作处理,如图像的锐化
void sharpen(const cv::Mat &image, cv::Mat &result)
{ // allocate if necessary result.create(image.size(), image.type()); for (int j= 1; j<image.rows-1; j++)
{
const uchar* previous= image.ptr<const uchar>(j-1); // 前一行 const uchar* current= image.ptr<const uchar>(j); // 当前行 const uchar* next= image.ptr<const uchar>(j+1); // 下一行 uchar* output= result.ptr<uchar>(j); // 输出行 for (int i=1; i<image.cols-1; i++)
{ *output++= cv::saturate_cast<uchar>( 5*current[i]-current[i-1] -current[i+1]-previous[i]-next[i]); } } // 将未处理的像素设为0 result.row(0).setTo(cv::Scalar(0)); result.row(result.rows-1).setTo(cv::Scalar(0)); result.col(0).setTo(cv::Scalar(0)); result.col(result.cols-1).setTo(cv::Scalar(0)); }
上述过程实际是利用一个3×3的模板对原始图像作卷积,opencv中的函数filter2D可以实现该过程
void sharpen2D(const cv::Mat &image, cv::Mat &result)
{ // 创建卷积核 cv::Mat kernel(3,3,CV_32F,cv::Scalar(0)); // 设置卷积核的值 kernel.at<float>(1,1)= 5.0; kernel.at<float>(0,1)= -1.0; kernel.at<float>(2,1)= -1.0; kernel.at<float>(1,0)= -1.0; kernel.at<float>(1,2)= -1.0; //实现卷积计算 cv::filter2D(image,result,image.depth(),kernel); }
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。