004 :opencv 中矩阵操作以及通过内存的方式取像素

 1.以下代码是对于矩阵和像素运算总结

#include <iostream>
#include <string>
#include <sstream>
using namespace std;

// OpenCV includes
#include "opencv2/core/utility.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
using namespace cv;

// OpenCV command line parser functions
// Keys accecpted by command line parser
const char* keys =
{
    "{help h usage ? | | print this message}"
    "{@sample |0 | Sample number to show}"
};


int main( int argc, const char** argv )
{
    CommandLineParser parser(argc, argv, keys);
    parser.about("Chapter 2. v1.0.0");
    //If requires help show
    if (parser.has("help"))
    {
        parser.printMessage();
        return 0;
    }

    int sample= parser.get<int>(0);

    // Check if params are correctly parsed in his variables
    if (!parser.check())
    {
        parser.printErrors();
        return 0;
    }


    switch(sample)
    {
        case 0:
        {    cout << "Sample 0, Mat zeros" << endl;
            Mat m= Mat::zeros(5,5, CV_32F);//元素全部为0的矩阵
            cout << m << endl;
            break;
        }
        case 1:
        {    cout << "Sample 0, Mat ones" << endl;
            Mat m= Mat::ones(5,5, CV_32F);//元素全部为1的矩阵
            cout << m << endl;
            break;
        }
        case 2:
        {    cout << "Sample 0, Mat eye" << endl;
            Mat m= Mat::eye(5,5, CV_32F); //单位矩阵
            cout << m << endl;

            Mat a= Mat::eye(Size(3,2), CV_32F);
            Mat b= Mat::ones(Size(3,2), CV_32F);
            Mat c= a+b;                    //矩阵相加
            Mat d= a-b;                    //矩阵相加
            cout << a << endl;
            cout << b << endl;
            cout << c << endl;
            cout << d << endl;
            break;
        }
        case 3:
        {    cout << "Sample 0, Mat operations:" << endl;
            Mat m0= Mat::eye(3,3, CV_32F);
            m0=m0+Mat::ones(3,3, CV_32F);
            Mat m1= Mat::eye(2,3, CV_32F);
            Mat m2= Mat::ones(3,2, CV_32F);

            cout << "
m0
" << m0 << endl;
            cout << "
m1
" << m1 << endl;
            cout << "
m2
" << m2 << endl;
            

            cout << "
m1.*2
" << m1*2 << endl;        //矩阵与标量相乘,每一个元素都乘以该标量
            cout << "m1+3" << m1 + 3 << endl;            //矩阵与标量相乘,每一个元素都加上该标量
            cout << "
(m1+2).*(m1+3)
" << (m1+1).mul(m1+3) << endl;//矩阵相乘
            cout << "
m1*m2
" << m1*m2 << endl;//矩阵相乘
            cout << "
t(m2)
" << m2.t() << endl;//矩阵转置
            cout << "
inv(m0)
" << m0.inv() << endl;//矩阵求逆  前提矩阵必须可逆
            break;
        }
        case 4:
        {
            Mat image= imread("lena.jpg", 0);
            int myRow=511;
            int myCol=511;

            uchar* ptr1 = (image.data + myRow * image.cols*image.channels() + myCol);///通过uchar获取对应的像素地址
            int val1=*(image.data+myRow*image.cols*image.channels()+ myCol);
            cout << "Pixel value:(511,511)" << val1 << endl;
            int endRow = 0;
            int endCol = 0;
            int val2 = *(image.data + endRow * image.cols*image.channels() + endCol);
            cout << "END Pixel value:(512,512)" << val2 << endl;
            endRow = 1;
            endCol = 1;
            int val3 = *(image.data + endRow * image.cols*image.channels() + endCol);
            cout << "END Pixel value:(1,1)" << val3 << endl;
            int startRow = 512;
            int startCol = 512;
             uchar* ptr2 = (image.data + startRow * image.cols*image.channels() + startCol);///通过uchar获取对应的像素地址

            int val4 = *(image.data + startRow * image.cols*image.channels() + startCol);
            cout << "Start Pixel value:(512,512)" << val4 << endl;
            Mat Bimage = imread("lena.jpg", 1);
            endRow = 1;
            endCol = 1;
            int val5 = *(Bimage.data + endRow * Bimage.cols*Bimage.channels() + endCol);
            cout << "END G Pixel value:(1,1)" << val5 << endl;



            imshow("Lena", image);
            waitKey(0);
            break;
        }
        case 5:
        {
            Mat image= imread("lena.jpg");
            int myRow=511;
            int myCol=511;
            int B=*(image.data+myRow*image.cols*image.channels()+ myCol + 0);
            int G=*(image.data+myRow*image.cols*image.channels()+ myCol + 1);
            int R=*(image.data+myRow*image.cols*image.channels()+ myCol + 2);
            cout << "Pixel value (B,G,R): (" << B << "," << G << "," << R << ")" << endl;
            imshow("Lena", image);
            waitKey(0);
            break;
        }
        case 6:
        {
            Vec<double,19> myVector;
            for(int i=0; i<19; i++){
                myVector[i]= i;
            }
            cout << myVector << endl;

        }
    }

    return 0;

}

2。直接获取像素内存地址,访问内存地址

    单通道的图像的访问第(Row,Col)的像素的灰度值方式

  访问单个通道的图像(Row,Col)位置的像素指针为(注意图像矩阵的索引是从(0,0)开始的

  uchar * ptr = image.data(图像的指针)+Row*image.cols(图像的Col数量)*image.channels(图像的通道数量1)+Col

 访问多通道中的第n个通道(注意通道是从0开始的

 uchar * ptr = image.data(图像的指针)+Row*image.cols(图像的Col数量)*image.channels(图像的通道数量1)+Col+n

    

 3.查看vs2017中的指针对应的的数据的方式。

  通过调试——》窗口——》内存——》内存块1/2/3/4(这里每一次调试系统给分配的内存地址的位置可能不同)

这事界面上会出现一个窗口,显示内存中的数据。

但是为什么通过(512,512)的位置也会取到值呢,不应该报数组越界吗?跟踪了下对应的512,512的指针的位置,确实值为dd,即是221,说明mat 结构在尾部还有一部分数据。

内存调试的问题,什么后面在内存中看不到我需要的指针数据呢?有我有疑问~~~~

原文地址:https://www.cnblogs.com/codeAndlearn/p/11562337.html