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 结构在尾部还有一部分数据。
内存调试的问题,什么后面在内存中看不到我需要的指针数据呢?有我有疑问~~~~