• 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 结构在尾部还有一部分数据。

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

  • 相关阅读:
    中国剩余定理及其扩展
    扩展欧几里得
    乘法逆元
    58-63用ssh远程连接linux系统
    148复习前一天的内容
    165-168函数
    Linux运维命令总结(-)
    177流程控制经典案例讲解
    170-176流程控制
    161【案例讲解】存储过程
  • 原文地址:https://www.cnblogs.com/codeAndlearn/p/11562337.html
Copyright © 2020-2023  润新知