精华内容
下载资源
问答
  • Mat作为opencv中一种数据类型常常用来存储图像,相对与以前的IplImgae类型来说,Mat类型省去了人工的对内存的分配与释放,转而自动分配释放。Mat Class主要包括两部个数据部分:一个是matrix header(包括matrix的...

    Mat作为opencv中一种数据类型常常用来存储图像,相对与以前的IplImgae类型来说,Mat类型省去了人工的对内存的分配与释放,转而自动分配释放。Mat Class主要包括两部个数据部分:一个是matrix header(包括matrix的大小尺寸,储存方法,储存地址等等..),另一个是指向存储像素值的矩阵的指针。

    Opencv中对Mat的复制分为两种,

    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; //Assignment operator

    Mat D (A, Rect(10, 10, 100, 100) ); // using a rectangle

    Mat E = A(Range::all(), Range(1,3)); // using row and column boundaries

    上面一类仅仅新建了matrix header,对与像素矩阵A,B,C共有,修改其中一项的像素值,其他的也都会改变,可以理解为他们提供了对相同底层数据的不同读取方法。 这么做的好处是为了减少计算成本。

    如果仅仅想操作其中的一部分像素,可以创建一个读取部分的header matrix

    当然Opencv也提供深度复制的方法

    Mat F =A.clone();

    Mat G;

    A.copyTo(G);

    Mat的创建

    cv::Mat::Mat Constructor:

    Mat M(2,2, CV_8UC3, Scalar(0,0,255));

    cout << "M = " << endl << " " << M << endl << endl;

    M.create(4,4, CV_8UC(2));

    cout << "M = "<< endl << " " << M << endl << endl;

    Mat E = Mat::eye(4, 4, CV_64F);

    cout << "E = " << endl << " " << E << endl << endl;

    Mat O = Mat::ones(2, 2, CV_32F);

    cout << "O = " << endl << " " << O << endl << endl;

    Mat Z = Mat::zeros(3,3, CV_8UC1);

    cout << "Z = " << endl << " " << Z << endl << endl;

    对于一些小的kernel可以自定义如下:

    Mat C = (Mat_(3,3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);

    cout << "C = " << endl << " " << C << endl << endl;

    在对图像进行分析及操作时往往需要进行遍历或对某一区域的像素值进行操作。总结了一下比较常用的有以下几种方法。

    1.利用ptr指针访问Mat像素

    for(int j = 1; j < myImage.rows - 1; ++j)

    {

    const uchar* previous = myImage.ptr(j - 1);

    const uchar* current = myImage.ptr(j );

    const uchar* next = myImage.ptr(j + 1);

    uchar* output = Result.ptr(j);

    for(int i = nChannels; i < nChannels * (myImage.cols - 1); ++i)

    {

    *output++ = saturate_cast(5 * current[i]

    -current[i - nChannels] - current[i + nChannels] - previous[i] - next[i]);

    }

    }

    2.使用 Mat::at 函数

    int main()

    {

    Mat img = imread("lena.jpg");

    imshow("Lena Original", img);

    if(img.channel() > 1)

    {

    for (int row = 0; row < img.rows; row++)

    {

    for (int col = 0; col < img.cols; col++)

    {

    /* 注意 Mat::at 函数是个模板函数, 需要指明参数类型, 因为这张图是具有红蓝绿三通道的图,

    所以它的参数类型可以传递一个 Vec3b, 这是一个存放 3 个 uchar 数据的 Vec(向量). 这里

    提供了索引重载, [2]表示的是返回第三个通道, 在这里是 Red 通道, 第一个通道(Blue)用[0]返回 */

    if(img.at(row, col)[2] > 128)

    img.at(row, col) = Vec3b(255, 255, 255);

    }

    }

    }

    else

    {

    for (int row = 0; row < img.rows; row++)

    {

    for (int col = 0; col < img.cols; col++)

    {

    if(img.at(row, col) > 128)

    img.at(row, col) = 255;

    }

    }

    }

    imshow("Lena Modified", img);

    cvWaitKey();

    return 0;

    }

    展开全文
  • 突然发现有一篇opencv操作mat数据的基础操作搞忘了,现在发出来,原来有一篇是只有操作结果,而且是用emgu写的,这里用c++实现并给出详细的代码。数字图像处理其实就是处理二维矩阵数据。利用opencv来学习处理算法是...

    突然发现有一篇opencv操作mat数据的基础操作搞忘了,现在发出来,原来有一篇是只有操作结果,而且是用emgu写的,这里用c++实现并给出详细的代码。

    数字图像处理其实就是处理二维矩阵数据。利用opencv来学习处理算法是一种比较好的方式。学习opencv,主要就是调用其中的图像处理函数来实现各种操作。如果要得到想要的处理结果,还需要对图像处理算法有一定的了解。同时,可能也有自己想写一些算法的冲动,并急切的想验证自己写的算法是否能够满足处理的要求。可是,真正到自己动手写的时候,总发现无从下手,比如,想得到图像中的ROI区域(感兴趣区域),想对图像做加减运算算,将两幅图像连接成一幅图像等等。如果要想随心所欲的按照自己的想法来操作一幅图像,则需要对opencv的mat数据操作非常熟练,建议初学者将这些基本的操作背下来,然后你会发现,你再进行这样的操作将是得心应手。

    在opencv中对图像数据进行操作,我们可以简单的把mat数据看成一个二维数,里面存储的就是图像的数据,所以,对mat数组的操作就是在操作二维图像数据。下面我们来实现常见的Mat数据操作。

    首先,在c++中新建一个空的控制台程序,然后,在属性管理器中添加我们之前设置好的opencv4.0配置文件,回到解决方案界面,选择源文件,右键添加新项目,然后得到一个空白的源文件,如图1和图2所示。

    c10515cbab86b43a812d5069f703cb68.png
    图1添加配置好的opencv配置文件

    f87aabcb48e3bb55b1db9e625e44a9cf.png
    图2 添加空白的源文件

    然后,就可以在这个空白的源文件中写代码了。下面用具体的代码来说明怎么操作mat数据。下面的代码都可以直接复制到自己的工程中直接运行如果涉及到要打开图像文件的,直接替换代码中的文件路径为自己电脑中的图像路劲就可以了。

    int main(int argc, char** argv)
    {
    //构造3X3的Mat矩阵
    // CV_8UC1和CV_8UC3是数据类型和通道,指8位无符号单通道和3数据,通道数据
    Mat a(Size(3,3),CV_8UC1); 
    Mat b = Mat(Size(3,3),CV_8UC3);
     cout<<"a=="<<a<<endl;//输出构造的mat数据
     cout<<"b=="<<b<<endl;// 输出构造的mat数据
    system("pause");//暂停
    }

    6b002596581b56c564402552f82ebc16.png
    图3 输出构造的mat数据

    图3是上面代码输出的结果,a是单通道,b是三通道,所以b是3行9列。里面的具体的值是opencv随机自动给的,因为我们还没有对mat赋值,这个不用管。再来看几个操作,

    Mat mz = Mat::zeros(Size(5,5),CV_8UC1);//构造5X5的全是0的mat数据

    Mat mo = Mat::ones(Size(5,5),CV_8UC1);// 构造5X5的全是1的mat数据

    Mat me = Mat::eye(Size(5,5),CV_8UC1); 构造5X5的单位矩阵的mat数据

    上面的代码可以直接在上面的main函数里面接着往下写。图4是输出结果

    60f118b29fe365d264c9d67524b27e23.png
    图4 上面三行代码的输出结果

    接着往下写。

     Mat m1 = Mat::eye(Size(3,3),CV_32F);// CV_32F表示浮点数
     Mat m2 = Mat::ones(Size(3,3),CV_32F);
    Mat add = m1 + m2;//mat相加
     Mat sub = m1 –m2;//mat相减
    Mat mul1 = m1 * 2;//mat乘一个常数
     Mat mul2 = m1 + 2;//mat加一个常数
    Mat m1t = m1.t();//mat矩阵转置
    Mat meInv = mul2.inv();//mat矩阵的逆矩阵
    int nonZeroNum = countNonZero(m1);//统计mat中非0的个数

    下面我们重新写一个main函数,不自己构造mat数据,直接从图像中得到。然后对图像数据的mat进行操作

    int main(int argc, char** argv)
    {
    Mat src1 = imread("E:1.bmp", 0);//0表示单通道,1表示3通道
     Mat src2 = imread("E:2.bmp", 0);
     Mat absSub;
     absdiff(src1, src2, absSub);//两图相减的绝对值
     namedWindow("absSub",0);
     imshow("absSub", absSub);
     Mat roiMat = src1(Range(0,3),Range(0,4));//取图像中的0到3行和0到4列
     cout<< roiMat <<endl;
     roiMat = roiMat.t();//图像矩阵转置
     cout<< roiMat <<endl;
     Mat addimg;
     add(src1, src2, addimg);//两图相加
     namedWindow("addimg",0);
     imshow("addimg", addimg);
     Mat addNum;
     add(src1,100, addNum);//图像加一个数字
     namedWindow("addNum",0);
     imshow("addNum", addNum);
     Mat ddWeightedImg;
    cv::addWeighted(src1,0.3,src2,0.7,0, ddWeightedImg);//两图带权重相加,可以用于图像融合
     namedWindow("ddWeightedImg",0);
     imshow("ddWeightedImg", ddWeightedImg);
     Mat subImg;
     subtract(src1,src2, subImg);//两图相减
     namedWindow("subImg",0);
     imshow("subImg", subImg);
     Mat subNum;
     subtract(100,src1, subNum);//一个数字减去图像
     namedWindow("subNum",0);
     imshow("subNum", subNum);
     Mat divideImg;
     cv::divide(src1,src2, divideImg,1.0);//两图相除
     namedWindow("divideImg",0);
     imshow("divideImg", divideImg);//不能直接显示,因为是浮点数,需要转换
     Mat mulImg;
     cv::multiply(src1,src2, mulImg,1.0);//两图相乘
     namedWindow("mulImg",0);
     imshow("mulImg", mulImg); //不能直接显示,因为是浮点数,需要转换
     Mat transposeImg;
     cv::transpose(src1, transposeImg);//图像转置
     namedWindow("transposeImg", 0);
     imshow("transposeImg", transposeImg);
     Mat tImg;
     tImg =src1.t();//图像转置,和上面的转置一样
     namedWindow("tImg", 0);
     imshow("tImg", tImg);
     
     Mat copyImg;
     src1.copyTo(copyImg);//图像复制
     namedWindow("copyImg",0);
     imshow("copyImg", copyImg);
     Mat maxImg;
     cv::max(src1,src2, maxImg);//两图中的最大值
     namedWindow("maxImg",0);
     imshow("maxImg", maxImg);
     
     Mat inRangeImg;
     cv::inRange(src1,40,100, inRangeImg);//相当于在一定范围内的值二值化
     namedWindow("inRangeImg",0);
     imshow("inRangeImg", inRangeImg);
     
     int r = src1.rows;
     int c = src2.cols;
     Mat r1 = src1.row(10);
     Scalar meanValue = cv::mean(src1);//图像均值
     cout<<"meanValue=="<< meanValue[0]<<endl;
     
     Mat colRangeImg = src1.colRange(0,10);//取图像中一定列
     Mat rowRangeImg = src1.rowRange(0,10); //取图像中一定行
     
     纵向合并图像
     Mat colMergeImg =Mat(src1.rows*2,src1.cols,0);
     Mat subM = colMergeImg.rowRange(0,src1.rows);
     src1.copyTo(subM);
     subM = colMergeImg.rowRange(src1.rows, src1.rows*2);
     src2.copyTo(subM);
     namedWindow("colMergeImg",0);
     imshow("colMergeImg", colMergeImg);
     ///横向合并矩阵
     Mat rowMergeImg =Mat(src1.rows,src1.cols*2,0);
     subM = rowMergeImg.colRange(0,src1.cols);
     src1.copyTo(subM);
     subM = rowMergeImg.colRange(src1.cols, src1.cols*2);
     src2.copyTo(subM);
     namedWindow("rowMergeImg",0);
     imshow("rowMergeImg", rowMergeImg);
     
     第二种在纵向合并两个图像的方法,横向合并类似,可以先对图像做转置,然后合并,最后再转置回来
     Mat mergeImg2;
     mergeImg2.push_back(src1);
     mergeImg2.push_back(src2);
     namedWindow("mergeImg2", 0);
     imshow("mergeImg2", mergeImg2);
     
     double minValue,maxValue;
     Point minLoc,maxLoc;
    minMaxLoc(src1,&minValue,&maxValue,&minLoc,&maxLoc);//取图像矩阵中的最大最小值和位置
     cout<<"minValue=="<<minValue<<endl;
     cout<<"maxValue=="<<maxValue<<endl;
     cout<<"minLoc"<<minLoc.x<<"--"<<minLoc.y<<endl;
     cout<<"maxLoc"<<maxLoc.x<<"--"<<maxLoc.y<<endl;
     Mat mean;
     Mat stddev;
     meanStdDev(src1, mean, stddev);//求图像矩阵的均值和方差
     cout << "mean==" << mean << endl;
     cout << "stddev==" << stddev << endl;
     waitKey(0);
    system("pause");
    }

    7896785d9e7e03681b10f72ffb9b8b95.png
    图5 输出结果显示

    上面包括了mat数据的主要操作命令,如果能够把这些命令记住了,要对图像做一般的操作基本上没有什么问题了。

    此外,如果要访问图像中的每一个像素值,可以采用下面指针的方式,速度是最快的。下面的代码只是演示了怎么使用指针访问像素,没有什么特别的目的。

    Mat dyImg = Mat(src1.rows, src1.cols,0);
    for(int i=0;i<src1.rows;i++)
    {
     uchar* srcdata = src1.ptr<uchar>(i);
     uchar* dydata = dyImg.ptr<uchar>(i);
     for(int j=0;j< src1.cols;j++)
     {
     double tempValue = double(srcdata [j]) + 20.0;
     if(tempValue < 0)
     dydata[j] = 0;
     else if(tempValue > 255)
     dydata[j] = 255;
     else
     dydata[j] = tempValue;
     }
     }
    namedWindow("dyImg ",0);
    imshow("dyImg ", dyImg);
    展开全文
  • 突然发现有一篇opencv操作mat数据的基础操作搞忘了,现在发出来,原来有一篇是只有操作结果,而且是用emgu写的,这里用c++实现并给出详细的代码。数字图像处理其实就是处理二维矩阵数据。利用opencv来学习处理算法是...

    突然发现有一篇opencv操作mat数据的基础操作搞忘了,现在发出来,原来有一篇是只有操作结果,而且是用emgu写的,这里用c++实现并给出详细的代码。

    数字图像处理其实就是处理二维矩阵数据。利用opencv来学习处理算法是一种比较好的方式。学习opencv,主要就是调用其中的图像处理函数来实现各种操作。如果要得到想要的处理结果,还需要对图像处理算法有一定的了解。同时,可能也有自己想写一些算法的冲动,并急切的想验证自己写的算法是否能够满足处理的要求。可是,真正到自己动手写的时候,总发现无从下手,比如,想得到图像中的ROI区域(感兴趣区域),想对图像做加减运算算,将两幅图像连接成一幅图像等等。如果要想随心所欲的按照自己的想法来操作一幅图像,则需要对opencv的mat数据操作非常熟练,建议初学者将这些基本的操作背下来,然后你会发现,你再进行这样的操作将是得心应手。

    在opencv中对图像数据进行操作,我们可以简单的把mat数据看成一个二维数,里面存储的就是图像的数据,所以,对mat数组的操作就是在操作二维图像数据。下面我们来实现常见的Mat数据操作。

    首先,在c++中新建一个空的控制台程序,然后,在属性管理器中添加我们之前设置好的opencv4.0配置文件,回到解决方案界面,选择源文件,右键添加新项目,然后得到一个空白的源文件,如图1和图2所示。图1添加配置好的opencv配置文件图2 添加空白的源文件

    然后,就可以在这个空白的源文件中写代码了。下面用具体的代码来说明怎么操作mat数据。下面的代码都可以直接复制到自己的工程中直接运行如果涉及到要打开图像文件的,直接替换代码中的文件路径为自己电脑中的图像路劲就可以了。

    int main(int argc, char** argv)

    {

    //构造3X3的Mat矩阵

    // CV_8UC1和CV_8UC3是数据类型和通道,指8位无符号单通道和3数据,通道数据

    Mat a(Size(3,3),CV_8UC1);

    Mat b = Mat(Size(3,3),CV_8UC3);

    cout<

    cout<

    system("pause");//暂停

    }图3 输出构造的mat数据

    图3是上面代码输出的结果,a是单通道,b是三通道,所以b是3行9列。里面的具体的值是opencv随机自动给的,因为我们还没有对mat赋值,这个不用管。再来看几个操作,

    Mat mz = Mat::zeros(Size(5,5),CV_8UC1);//构造5X5的全是0的mat数据

    Mat mo = Mat::ones(Size(5,5),CV_8UC1);// 构造5X5的全是1的mat数据

    Mat me = Mat::eye(Size(5,5),CV_8UC1); 构造5X5的单位矩阵的mat数据

    上面的代码可以直接在上面的main函数里面接着往下写。图4是输出结果

    图4 上面三行代码的输出结果

    接着往下写。

    Mat m1 = Mat::eye(Size(3,3),CV_32F);// CV_32F表示浮点数

    Mat m2 = Mat::ones(Size(3,3),CV_32F);

    Mat add = m1 + m2;//mat相加

    Mat sub = m1 –m2;//mat相减

    Mat mul1 = m1 * 2;//mat乘一个常数

    Mat mul2 = m1 + 2;//mat加一个常数

    Mat m1t = m1.t();//mat矩阵转置

    Mat meInv = mul2.inv();//mat矩阵的逆矩阵

    int nonZeroNum = countNonZero(m1);//统计mat中非0的个数

    下面我们重新写一个main函数,不自己构造mat数据,直接从图像中得到。然后对图像数据的mat进行操作

    int main(int argc, char** argv)

    {

    Mat src1 = imread("E:\\1.bmp", 0);//0表示单通道,1表示3通道

    Mat src2 = imread("E:\\2.bmp", 0);

    Mat absSub;

    absdiff(src1, src2, absSub);//两图相减的绝对值

    namedWindow("absSub",0);

    imshow("absSub", absSub);

    Mat roiMat = src1(Range(0,3),Range(0,4));//取图像中的0到3行和0到4列

    cout<< roiMat <

    roiMat = roiMat.t();//图像矩阵转置

    cout<< roiMat <

    Mat addimg;

    add(src1, src2, addimg);//两图相加

    namedWindow("addimg",0);

    imshow("addimg", addimg);

    Mat addNum;

    add(src1,100, addNum);//图像加一个数字

    namedWindow("addNum",0);

    imshow("addNum", addNum);

    Mat ddWeightedImg;

    cv::addWeighted(src1,0.3,src2,0.7,0, ddWeightedImg);//两图带权重相加,可以用于图像融合

    namedWindow("ddWeightedImg",0);

    imshow("ddWeightedImg", ddWeightedImg);

    Mat subImg;

    subtract(src1,src2, subImg);//两图相减

    namedWindow("subImg",0);

    imshow("subImg", subImg);

    Mat subNum;

    subtract(100,src1, subNum);//一个数字减去图像

    namedWindow("subNum",0);

    imshow("subNum", subNum);

    Mat divideImg;

    cv::divide(src1,src2, divideImg,1.0);//两图相除

    namedWindow("divideImg",0);

    imshow("divideImg", divideImg);//不能直接显示,因为是浮点数,需要转换

    Mat mulImg;

    cv::multiply(src1,src2, mulImg,1.0);//两图相乘

    namedWindow("mulImg",0);

    imshow("mulImg", mulImg); //不能直接显示,因为是浮点数,需要转换

    Mat transposeImg;

    cv::transpose(src1, transposeImg);//图像转置

    namedWindow("transposeImg", 0);

    imshow("transposeImg", transposeImg);

    Mat tImg;

    tImg =src1.t();//图像转置,和上面的转置一样

    namedWindow("tImg", 0);

    imshow("tImg", tImg);

    Mat copyImg;

    src1.copyTo(copyImg);//图像复制

    namedWindow("copyImg",0);

    imshow("copyImg", copyImg);

    Mat maxImg;

    cv::max(src1,src2, maxImg);//两图中的最大值

    namedWindow("maxImg",0);

    imshow("maxImg", maxImg);

    Mat inRangeImg;

    cv::inRange(src1,40,100, inRangeImg);//相当于在一定范围内的值二值化

    namedWindow("inRangeImg",0);

    imshow("inRangeImg", inRangeImg);

    int r = src1.rows;

    int c = src2.cols;

    Mat r1 = src1.row(10);

    Scalar meanValue = cv::mean(src1);//图像均值

    cout<

    Mat colRangeImg = src1.colRange(0,10);//取图像中一定列

    Mat rowRangeImg = src1.rowRange(0,10); //取图像中一定行

    纵向合并图像

    Mat colMergeImg =Mat(src1.rows*2,src1.cols,0);

    Mat subM = colMergeImg.rowRange(0,src1.rows);

    src1.copyTo(subM);

    subM = colMergeImg.rowRange(src1.rows, src1.rows*2);

    src2.copyTo(subM);

    namedWindow("colMergeImg",0);

    imshow("colMergeImg", colMergeImg);

    ///横向合并矩阵

    Mat rowMergeImg =Mat(src1.rows,src1.cols*2,0);

    subM = rowMergeImg.colRange(0,src1.cols);

    src1.copyTo(subM);

    subM = rowMergeImg.colRange(src1.cols, src1.cols*2);

    src2.copyTo(subM);

    namedWindow("rowMergeImg",0);

    imshow("rowMergeImg", rowMergeImg);

    第二种在纵向合并两个图像的方法,横向合并类似,可以先对图像做转置,然后合并,最后再转置回来

    Mat mergeImg2;

    mergeImg2.push_back(src1);

    mergeImg2.push_back(src2);

    namedWindow("mergeImg2", 0);

    imshow("mergeImg2", mergeImg2);

    double minValue,maxValue;

    Point minLoc,maxLoc;

    minMaxLoc(src1,&minValue,&maxValue,&minLoc,&maxLoc);//取图像矩阵中的最大最小值和位置

    cout<

    cout<

    cout<

    cout<

    Mat mean;

    Mat stddev;

    meanStdDev(src1, mean, stddev);//求图像矩阵的均值和方差

    cout << "mean==" << mean << endl;

    cout << "stddev==" << stddev << endl;

    waitKey(0);

    system("pause");

    }图5 输出结果显示

    上面包括了mat数据的主要操作命令,如果能够把这些命令记住了,要对图像做一般的操作基本上没有什么问题了。

    此外,如果要访问图像中的每一个像素值,可以采用下面指针的方式,速度是最快的。下面的代码只是演示了怎么使用指针访问像素,没有什么特别的目的。

    Mat dyImg = Mat(src1.rows, src1.cols,0);

    for(int i=0;i

    {

    uchar* srcdata = src1.ptr(i);

    uchar* dydata = dyImg.ptr(i);

    for(int j=0;j< src1.cols;j++)

    {

    double tempValue = double(srcdata [j]) + 20.0;

    if(tempValue < 0)

    dydata[j] = 0;

    else if(tempValue > 255)

    dydata[j] = 255;

    else

    dydata[j] = tempValue;

    }

    }

    namedWindow("dyImg ",0);

    imshow("dyImg ", dyImg);

    展开全文
  • 学习opencv,主要就是调用其中的图像处理函数来实现各种操作。如果要得到想要的处理结果,还需要对图像处理算法有一定的了解。同时,可能也有自己想写一些算法的冲动,并急切的想验证自己写的算法是否能够满足处理的...

    数字图像处理其实就是处理二维矩阵数据。利用opencv来学习处理算法是一种比较好的方式。学习opencv,主要就是调用其中的图像处理函数来实现各种操作。如果要得到想要的处理结果,还需要对图像处理算法有一定的了解。同时,可能也有自己想写一些算法的冲动,并急切的想验证自己写的算法是否能够满足处理的要求。可是,真正到自己动手写的时候,总发现无从下手,比如,想得到图像中的ROI区域(感兴趣区域),想对图像做加减运算算,将两幅图像连接成一幅图像等等。如果要想随心所欲的按照自己的想法来操作一幅图像,则需要对opencv的mat数据操作非常熟练,建议初学者将这些基本的操作背下来,然后你会发现,你再进行这样的操作将是得心应手。

    在opencv中对图像数据进行操作,我们可以简单的把mat数据看成一个二维数,里面存储的就是图像的数据,所以,对mat数组的操作就是在操作二维图像数据。下面我们来实现常见的Mat数据操作。

    首先,在c++中新建一个空的控制台程序,然后,在属性管理器中添加我们之前设置好的opencv4.0配置文件,回到解决方案界面,选择源文件,右键添加新项目,然后得到一个空白的源文件,如图1和图2所示。

    808744b7bce8ce2a89f3523475853584.png

    图1添加配置好的opencv配置文件

    525eff61afcb5a2f418e3ecb141a36f9.png

    图2 添加空白的源文件

    然后,就可以在这个空白的源文件中写代码了。下面用具体的代码来说明怎么操作mat数据。下面的代码都可以直接复制到自己的工程中直接运行如果涉及到要打开图像文件的,直接替换代码中的文件路径为自己电脑中的图像路径就可以了。

    int main(int argc, char** argv){//构造3X3的Mat矩阵// CV_8UC1和CV_8UC3是数据类型和通道,指8位无符号单通道和3数据,通道数据Mat a(Size(3,3),CV_8UC1);Mat b = Mat(Size(3,3),CV_8UC3);cout<
    a08ef8139d105e139f41e68aa1842c5b.png

    图3 输出构造的mat数据

    图3是上面代码输出的结果,a是单通道,b是三通道,所以b是3行9列。里面的具体的值是opencv随机自动给的,因为我们还没有对mat赋值,这个不用管。再来看几个操作,

    Mat mz = Mat::zeros(Size(5,5),CV_8UC1);//构造5X5的全是0的mat数据

    Mat mo = Mat::ones(Size(5,5),CV_8UC1);// 构造5X5的全是1的mat数据

    Mat me = Mat::eye(Size(5,5),CV_8UC1); 构造5X5的单位矩阵的mat数据

    上面的代码可以直接在上面的main函数里面接着往下写。图4是输出结果

    d1c59c632d56d506c265a6cbf74f4f5a.png

    图4 上面三行代码的输出结果

    接着往下写。

    Mat m1 = Mat::eye(Size(3,3),CV_32F);// CV_32F表示浮点数Mat m2 = Mat::ones(Size(3,3),CV_32F);Mat add = m1 + m2;//mat相加Mat sub = m1 –m2;//mat相减Mat mul1 = m1 * 2;//mat乘一个常数Mat mul2 = m1 + 2;//mat加一个常数Mat m1t = m1.t();//mat矩阵转置Mat meInv = mul2.inv();//mat矩阵的逆矩阵int nonZeroNum = countNonZero(m1);//统计mat中非0的个数

    下面我们重新写一个main函数,不自己构造mat数据,直接从图像中得到。然后对图像数据的mat进行操作

    int main(int argc, char** argv){Mat src1 = imread("E:1.bmp", 0);//0表示单通道,1表示3通道Mat src2 = imread("E:2.bmp", 0);Mat absSub;absdiff(src1, src2, absSub);//两图相减的绝对值namedWindow("absSub",0);imshow("absSub", absSub);Mat roiMat = src1(Range(0,3),Range(0,4));//取图像中的0到3行和0到4列cout<< roiMat <
    5b376eb3e5a85ba52e9863acc6e2992f.png

    图5 输出结果显示

    上面包括了mat数据的主要操作命令,如果能够把这些命令记住了,要对图像做一般的操作基本上没有什么问题了。

    此外,如果要访问图像中的每一个像素值,可以采用下面指针的方式,速度是最快的。下面的代码只是演示了怎么使用指针访问像素,没有什么特别的目的。

    Mat dyImg = Mat(src1.rows, src1.cols,0);

    for(int i=0;i

    {

    uchar* srcdata = src1.ptr(i);

    uchar* dydata = dyImg.ptr(i);

    for(int j=0;j< src1.cols;j++)

    {

    double tempValue = double(srcdata [j]) + 20.0;

    if(tempValue < 0)

    dydata[j] = 0;

    else if(tempValue > 255)

    dydata[j] = 255;

    else

    dydata[j] = tempValue;

    }

    }

    namedWindow("dyImg ",0);

    imshow("dyImg ", dyImg);

    展开全文
  • 学习opencv,主要就是调用其中的图像处理函数来实现各种操作。如果要得到想要的处理结果,还需要对图像处理算法有一定的了解。同时,可能也有自己想写一些算法的冲动,并急切的想验证自己写的算法是否能够满足处理的...
  • 突然发现有一篇opencv操作mat数据的基础操作搞忘了,现在发出来,原来有一篇是只有操作结果,而且是用emgu写的,这里用c++实现并给出详细的代码。数字图像处理其实就是处理二维矩阵数据。利用opencv来学习处理算法是...
  • 在上一次中的最后,提到了修改图像数据操作。但是,这种操作是比较慢的。下面说一下访问图像数据的几种方式。毕竟在实际的图像处理中,时刻少不了要自己写算法,这就必须访问图像数据,而快的访问方式可以大大提高...
  • Opencv图像处理基本操作 1基本数据类型 图像有若干个通道,灰度图像只有一个通道,而彩色具有红,绿,蓝组成,但是OpenCv以逆序的方式来存储三个分量,还可以使用第四个透明度(alpha),可以使用img.channels()获取...
  • OpenCV - Operations on Arrays  对数组(矩阵)的一些操作 Function (函数名) Use (函数用处) Author : Ggicci  QQ : 771017478 / 854032390(prefer)  转载请注明出处! add 矩阵加法,A+B的更高级形式,...
  • 对于Mat数据结构,在对图像进行处理时要注意: 1、 OpenCV函数中输出图像的内存分配是自动完成的(如果不特别指定的话)。 使用OpenCV的C++接口时不需要考虑内存释放问题。 赋值运算符和拷贝构造函数( ctor )...
  • 1: 输出一个Mat对象的像素自定义一个Mat 对象,然后输出像素值(像素值基本都在 0 – 255 之间 ,图像为三通道)代码public static void F1(){Scalar s = new Scalar(0, 0, 255); //定义一个三通道颜色(红色)Mat m = ...
  • Mat作为opencv中一种数据类型常常用来存储图像,相对与以前的IplImgae类型来说,Mat类型省去了人工的对内存的分配与释放,转而自动分配释放。Mat Class主要包括两部个数据部分:一个是matrix header(包括matrix的...
  • 以前使用OpenCV操作图像都是使用IplImage,现在好像多数都使用的Mat 参考1:http://blog.csdn.net/augusdi/article/details/8876459 OpenCv学习笔记(二)—cv::Mat学习 了解到IplImage是OpenCV1.0中使用的...
  • 本文目录1. 像素读写2. 图像通道与均值方差计算3....在获取图像数据的时候,知道Mat的类型与通道数目关重要,根据Mat的类型与通道数目,开辟适当大小的内存空间,然后通过get方法就可以循环实现每个像素...
  • opencv MAT数据操作

    2016-01-14 14:48:00
    1.存取单个像素值 最通常的方法就是 img.at<...对于一幅图像的扫描,用at就显得不太好了,还是是用指针的操作方法更加推荐。先介绍一种上一讲提到过的 for (int j=0; j<nl; j++) { ...
  • Mat类相关操作Opencv的入门基础 初始化构造函数 mat类是opencv中一个非常重要的数据结构,在这里先记录一下最基础的知识,也是最重要的知识吧,千里之行始于足下。 构造函数 说明 cv:Mat(int rows ,int ...
  • opencv图像数据操作

    2015-12-31 09:22:48
    cv::Mat img; img = cv::imread(image_path, CV_LOAD_IMAGE_COLOR); // image_path为图片存储路径 if (!img.data || !seg.data) {  std::cout  return; } 2.resize cv::Size rescaleSize
  • OpenCV Mat数据类型像素操作

    万次阅读 2016-11-07 19:50:25
    OpenCV图像像素操作及效率分析 ... 在计算机视觉应用中,对于图像内容的读取分析是第一步...一个图像有可能包含数以万计的像素,从根本上说图像就是一系列像素值,所以OpenCV使用数据结构cv::Mat来表示图像。矩阵
  • Mat用来表示图像或稠密数组。 特别注意:数组中的数据不是直接绑定在mat的对象上的。Mat对象实质上是一个数据存储区的头,而非数组本身。如果忽略这点,经常会带来bug。 例如,mat1 = mat2,随后修改mat1或mat2中...
  • opencvmat类型数据操作和内存

    千次阅读 2018-05-03 20:53:02
    Matopencv中的一种矩阵数据类型,用来存储图像Mat类包含两个数据部分:矩阵头和指向存储所有像素值的矩阵的指针。矩阵头包含矩阵的大小尺寸、存储方法、存储地址等。在opencv中,对矩阵Mat的复制分为深复制和浅...
  • 在上一次中的最后,提到了修改图像数据操作。但是,这种操作是比较慢的。下面说一下访问图像数据的几种方式。毕竟在实际的图像处理中,时刻少不了要自己写算法,这就必须访问图像数据,而快的访问方式可以大大提高...
  • openCV中,Mat是一个多维的密集数据数组。可以用来处理向量和矩阵、图像、直方图等等常见的多维数据Mat有3个重要的方法:1、Mat mat = imread(const String* filename); 读取图像2、imshow(const string ...
  • OpenCV图像操作

    2020-12-20 16:33:34
    OpenCV图像操作OpenCVMat数据类型Mat基础操作图像遍历基本遍历指针遍历forEach访问图像像素点像素范围处理空图像创建图像缩放寻找图像像素最大值与最小值计算图像的均值和标准方差convertTo函数cvtColor()函数窗口...
  • Mat类是opencv中最核心的类,它是matrix的缩写,代表矩阵或者数组的含义,所以创建一个Mat类对象就相当于创建一个矩阵或者数组,一个mat类有以下四个最基本的要素组成:行数,列数,通道数及其数据类型,其构造函数...
  • 在学习OpenCV进行图像处理的过程中,常常会用到对指定位置像素的读取和修改, 最常用的就是cv::MAT.at<>()和cv::MAT.ptr<>(),下面我们就介绍OpenCV中这两种常用的对指定位置像素值的读取和修改操作。 ...
  • OpenCV中常见的与图像操作有关的数据容器有Mat,cvMat和IplImage  由于在写上一篇图像数据结构时,发现自己只知道CvMat,竟然还有Mat数据结构,真是无知了,看了这么多程序,貌似没有看到这个结构。有可能...
  • opencv Mat基本操作

    千次阅读 2015-08-07 21:03:04
    1. Mat 初始化为0 Mat img; img= Mat::zeros(int rows, int cols, int type); 2.Mat 数据结构组合: 个人观察:例如: Mat R = Mat( 3, 2, CV_8UC3 ) ...因此猜测:RGB图像Mat应该是 Mat(1,1,CV_8UC3)的.
  • 以前一直用MATLAB做图像仿真,这次学习OPENCV后,第一步就是读取图像,并对图像进行位操作,在OPENCV中比较重要和基础的一个数据结构是MAT,针对MAT型结构的位处理,进行了以下试验。 #include<opencv2/core/core....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 395
精华内容 158
关键字:

mat图像数据操作opencv