OPenCV中累加一个三通道矩阵中的所有元素:
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OPenCV中累加一个三通道矩阵中的所有元素:相关的知识,希望对你有一定的参考价值。
程序为:
float sum( const CvMat* mat )
float s = 0.0f;
for(int row=0; row<mat->rows; row++ )
const float* ptr=(const float*)(mat->data.ptr + row * mat->step);
for( col=0; col<mat->cols; col++ )
s += *ptr++;
return( s );
我想问const float* ptr=(const float*)(mat->data.ptr + row * mat->step); 这句程序的详细意思,看不懂
而mat中的数据,是float的
所以,在前面进行了强制转换 (const float*)
mat->step,是mat中,每行数据的长度
不过,感觉这里这么用不对头,因为 step,也是以byte为单位的,而前面已经强制成float了,所以就被人为放大了
先定义一个中间指针
char *ptr1;
ptr1 = mat->data.ptr + row * mat->step;
ptr = =(const float*)ptr1;
这样就可以了
还有可改进的地方,循环内
每次指针
ptr1 += mat->step;
就可以,不用乘row了追问
加一个中间指针,把const float* ptr=(const float*)(mat->data.ptr + row * mat->step); 分成两句有本质的区别吗?不太清楚哦,请指教!!
追答分开后 step 就是按 char 的长度增加指针
不分,就是按 float 的长度
mat是CvMat类型,根据OpenCV的API帮助,CvMat.data是一个union,当然其中每种类型都是指针,data.ptr是把数据看成unsigned char的指针,而CvMat.step是这个矩阵中一行的实际数据长度,row是从0开始的行号,所以整个计算式的结果就是第row行的数据开头。
图像处理和OpenCV初步
图像从数学和计算机的角度理解就是一个矩阵
,矩阵中的每一个元素叫做像素
,又由于图像有灰度图像和彩色图像之分,所以图像在矩阵的基础上引入通道(channel)
,其中色彩用数字来表示的时候,规定数字0表示黑色,数字255表示白色。
OpenCV角度来看图像
OpenCV中的cv::Mat
类就是用来表示图像的矩阵而存在的,其中cv::Mat
类由头部
和数据块
组成。
头部包含了矩阵的所有相关信息(大小、通道数量、数据类型等),
cv::Mat
头部文件的某些属性(例如cols、rows 或 channels)。头部有一个指向 数据块的指针,即 data 属性。数据块包含了图像中所有像素的值。
cv::Mat
有一个很重要的属性,即只有在明确要求时,内存块才 会被复制。实际上,大多数操作仅仅复制了cv::Mat
的头部,因此多个对象会指向同一个数据块。这种内存管理模式可以提高应用程序的运行效率,避免内存泄漏,
#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
// 测试函数,它创建一幅图像
cv::Mat function() {
// 创建图像
cv::Mat ima(500,500,CV_8U,50);
// 返回图像
return ima;
}
int main() {
// // 创建一个 240 行×320 列的新图像
cv::Mat image1(240,320,CV_8U,100);
// or:
// cv::Mat image1(240,320,CV_8U,cv::Scalar(100));
cv::imshow("Image", image1); // show the image
cv::waitKey(0); // wait for a key pressed
// 重新分配一个新图像
// (only if size or type are different)
image1.create(200,200,CV_8U);
image1= 200;
cv::imshow("Image", image1); // show the image
cv::waitKey(0); // wait for a key pressed
// create a red color image
// channel order is BGR
cv::Mat image2(240,320,CV_8UC3,cv::Scalar(0,0,255));
// or:
// cv::Mat image2(cv::Size(320,240),CV_8UC3);
// image2= cv::Scalar(0,0,255);
cv::imshow("Image", image2); // show the image
cv::waitKey(0); // wait for a key pressed
// read an image
cv::Mat image3= cv::imread("puppy.bmp");
// all these images point to the same data block
cv::Mat image4(image3);
image1= image3;
// these images are new copies of the source image
image3.copyTo(image2);
cv::Mat image5= image3.clone();
// transform the image for testing
cv::flip(image3,image3,1);
// check which images have been affected by the processing
cv::imshow("Image 3", image3);
cv::imshow("Image 1", image1);
cv::imshow("Image 2", image2);
cv::imshow("Image 4", image4);
cv::imshow("Image 5", image5);
cv::waitKey(0); // wait for a key pressed
// 从函数中获取一个灰度图像
cv::Mat gray= function();
cv::imshow("Image", gray); // show the image
cv::waitKey(0); // wait for a key pressed
// 作为灰度图像读入
image1= cv::imread("puppy.bmp", CV_LOAD_IMAGE_GRAYSCALE);
// convert the image into a floating point image [0,1]
image1.convertTo(image2,CV_32F,1/255.0,0.0);
cv::imshow("Image", image2); // show the image
// Test cv::Matx
// a 3x3 matrix of double-precision
cv::Matx33d matrix(3.0, 2.0, 1.0,
2.0, 1.0, 3.0,
1.0, 2.0, 3.0);
// a 3x1 matrix (a vector)
cv::Matx31d vector(5.0, 1.0, 3.0);
// multiplication
cv::Matx31d result = matrix*vector;
std::cout << result;
cv::waitKey(0); // wait for a key pressed
return 0;
}
灰度图像
一个通道的图像就是灰度图像,就是类似以前的老照片,不是彩色的,也可以理解成黑白的。
- OpenCV中对灰度图像的处理
// 作为灰度图像读入
image1= cv::imread("puppy.bmp", CV_LOAD_IMAGE_GRAYSCALE);
// 创建灰度图像
cv::Mat ima(500,500,CV_8U,50);
//0表示灰度图像
cv::Mat image2= cv::imread("boldt.jpg",0);//0表示灰度图
彩色图像
对彩色图像而言,需要用三原色数据来重现不同的可见色。
这是因为人类的视觉系统是三原色的,视网膜上有三种类型的视锥细胞,它们将颜色信息传递给大脑。
所以彩色图像的每个像素都要对应三个数值。在摄影和数字成像技术中,常用的主颜色通道是红色、绿色和蓝色,因此每三个 8 位数值组成矩阵的一个元素,特别说明,8 位通道通常是够用的,但有些特殊的应用程序需要用 16 位通道(医学图像就是用16位通道表示)。
- OpenCV对图像的读入
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
int main()
{
// open the image
cv::Mat image= cv::imread("boldt.jpg",1);
// display result
cv::namedWindow("Image1");
cv::imshow("Image1",image);
// write on disk
cv::imwrite("salted.bmp",image);
cv::waitKey();
// test second version
cv::Mat image2= cv::imread("boldt.jpg",0);//0表示灰度图
cv::namedWindow("Image2");
cv::imshow("Image2",image2);
cv::waitKey();
return 0;
}
以上是关于OPenCV中累加一个三通道矩阵中的所有元素:的主要内容,如果未能解决你的问题,请参考以下文章