C++的opencv图像拼接里怎么读取Mat图像中特定坐标的灰度值?

OpenCV中访问Mat图像像素的一个小技巧
在OpenCV2里面,访问图像像素的方法一般有三种:
1、 使用迭代器iterator。
2、 使用指针和[ ]进行读取。
3、 利用Mat里的at方法。
关于这三种方法的使用,网上有很多大神发的博客教程,这里给大家一个,大家可以看看。
在实际使用过程中,大家可能会发现,迭代器和指针非常适合顺序访问,即当我们需要遍历图像的像素时,先获取像素矩阵的首地址(或行首地址),再用指针或迭代器访问效率是很高的,编程也简单、但有时候我们需要随机的访问图像矩阵的某个元素,比如在连通域检测时我们要访问某一像素的邻域,这时候用这两种方法就显的比较笨重和麻烦了。这是时候使用第三种方法就比较方便。但at方法的效率没有指针高,而且代码书写也比较长。
那么我们自然会想到,我们能不能使用二维数组的形式去访问图像矩阵呢?这样既可以比较直观方便地访问元素,又不失效率。
啊哈,其实你要是C语言指针学得好的话,这一点根本就难不倒你。
对于一个单通道8bit深度的二维图像,可以先定义一个二维指针:
typedef uchar *
pixel imgMatrix = new pixel[img.rows];
for(int i = 0; i & img. i++)
imgMatrix[i] = img.ptr&uchar&(i);
这样,我们就把每一行的首地址保存在数组imgMatrix[ ]里面了,如果你要访问第i行第j列的像素,你可以使用imgMatrix[i][j]去访问。其本质上还是用指针来访问来访问元素,只不过我们事先把每一行的首地址都保存起来了,不必每次用“uchar *p = img.ptr(i)”这个的语句去获取行首地址,而且更直观。
这里,我们可以随便写个灰度调整的程序来比较这种访问方法和利用at方法所用的时间。
#include &opencv2\opencv.hpp&
#include &iostream&
using namespace
using namespace std;
typedef uchar *
int main(int argc, char *argv[])
Mat img(imread("lena.jpg",0));
if(img.empty())
imshow("input", img);
int cols = img.
int rows = img.
pixel *imgMatrix = new pixel[rows];
for(int i = 0; i & i++)
imgMatrix[i] = img.ptr&uchar&(i);
double time0 = static_cast&double&(getTickCount());
#define OPTION 1
#if OPTION
for( int i = 0; i & i++)
for( int j = 0; j & j++)
imgMatrix[i][j] = imgMatrix[i][j]/2;
for( int i = 0; i & i++)
for( int j = 0; j & j++)
img.at&uchar&(i, j) = img.at&uchar&(i, j)/2;
time0 = ((double)getTickCount() - time0)/getTickFrequency();
cout&&"此方法运行时间为: "&&time0&&"秒"&&
imshow("output", img);
waitKey();
destroyAllWindows();
system("pause");
编译前改变宏定义OPTION的值可以使程序在两种方法间切换。
下边是在VS2010 debug模式下的运行结果
输入图像:
输出图像:
使用二维数组访问图像的运行时间:
使用at方法访问图像的运行时间:
如果要访问多通道的像素,那也照葫芦画瓢,比如:
typedef Vec3b * pixel3d;
pixel3d imgMatrix3d = new pixel3d[img.rows];
for(int i = 0; i & img. i++)
imgMatrix3d[i] = img.ptr&Vec3b&(i);
于是遍历每个通道就可以这样写
imgMatrix3d[i][j][0] = imgMatrix3d[i][j][0]/2;
imgMatrix3d[i][j][1] = imgMatrix3d[i][j][1]/2;
imgMatrix3d[i][j][2] = imgMatrix3d[i][j][2]/2;
哈哈,是不是觉得C/C++有了指针就特别好玩啊~
请各位不吝赐教!
没有更多推荐了,OpenCV访问图像数据并设定灰度值
首先要了解OpenCV中单通道和多通道的图像,其图像数据格式是不同的,特别注意对于三通道而言,其在某个像素上的通道顺序是B-&G-&R。
/***************************************
第三讲 访问图像数据 ****
****************************************/
#include &iostream&
#include "cv.h"
#include "highgui.h"
/*** 设置图像灰度值的子函数
void setSaltNoise(Mat& image, int count)
srand((unsigned)time(NULL)); //要产生随机数,需要一个随机数种子,这里是以时间作为
//随机数产生的种子
for (int i = 0; i & i++)
y = rand() % image. //将随机数y的取值范围设定在图像的行范围内
x = rand() % image. //将随机数x的取值范围设定在图像的列范围内
if (image.channels() == 1) //如果图像是单通道则直接将其(y,x)点像素的灰度值
//设定为255,即白色。这里注意给定点像素的读取方法
image.at&uchar&(y, x) = 255;
if (image.channels() == 3) //如果是三通道的图像,则注意其特定像素值的不同通道
//的值的设定
image.at&Vec3b&(y, x)[0] = 255; //设定B通道的值为白色
image.at&Vec3b&(y, x)[1] = 255; //设定G通道的值为白色
image.at&Vec3b&(y, x)[2] = 255; //设定R通道的值为白色
int main(int argc, char* argv[])
Mat src = imread("G:/Learning/Machine_version/Photo/1.png");//读取图像
namedWindow("src");
//创建图像显示窗口
setSaltNoise(src,2000);
//设置图像灰度值
imshow("src", src);
//在窗口中显示图像
waitKey(0);
//等待按键响应
system("pause");
没有更多推荐了,使用opencv对读入视频提取相应像素值坐标问题
[问题点数:40分,结帖人darnell_cheng]
本版专家分:0
结帖率 50%
CSDN今日推荐
本版专家分:83051
2017年 总版技术专家分年内排行榜第一
2014年 总版技术专家分年内排行榜第二
2013年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第七
本版专家分:0
本版专家分:83051
2017年 总版技术专家分年内排行榜第一
2014年 总版技术专家分年内排行榜第二
2013年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第七
本版专家分:0
本版专家分:0
匿名用户不能发表回复!|
其他相关推荐http://m.blog.csdn.net/blog/u308979
最近在研究如何用C++来处理图像,而不使用封装好的OpenCV代码,这样能够更好的了解OpenCV的内部原理。
在网上搜了一些关于C++代码来实现RGB(彩色)图像转换为 gray(灰度)的原理以及代码,可读性较差,所以自己整理了一下,若需转载,请标明出处,谢谢!
一、学习cvtColor函数&
void cvCvtColor( const CvArr* src, CvArr* dst, int code );src 输入的 8-bit,16-bit或 32-bit单倍精度浮点数影像。dst 输出的8-bit, 16-bit或 32-bit单倍精度浮点数影像。code 色彩空间转换的模式,该code来实现不同类型的颜色空间转换。比如CV_BGR2GRAY表示转换为灰度图,CV_BGR2HSV将图片从RGB空间转换为HSV空间。其中当code选用CV_BGR2GRAY时,dst需要是单通道图片。当code选用CV_BGR2HSV时,对于8位图,需要将RGB值归一化到0-1之间。这样得到HSV图中的H范围才是0-360,S和V的范围是0-1。
二、利用OpenCV的函数将彩色图像转为灰度图像:#includeint main(){& Mat src = imread("lena.jpg",1);
& //Mat src = imread("lena.jpg",0);
& M& namedWindow("RGB",WINDOW_AUTOSIZE);& imshow("RGB",src);& //waitKey(0);
& cvtColor(src,dst,CV_BGR2GRAY);& namedWindow("GRAY",WINDOW_AUTOSIZE);imshow("GRAY",dst);cout&&dst.channels()&&
waitKey(0);
& src.release();& dst.release();destroyWindow("RGB");destroyWindow("GRAY");& return 0;}
三、imread的函数原型是:Mat imread( const string& filename, int flags=1 );Mat是OpenCV里的一个数据结构,在这里我们定义一个Mat类型的变量img,用于保存读入的图像,在本文开始有写到,我们用imread函数来读取图像,第一个字段标识图像的文件名(包括扩展名),第二个字段用于指定读入图像的颜色和深度,它的取值可以有以下几种:1) CV_LOAD_IMAGE_UNCHANGED (&0),以原始图像读取(包括alpha通道),2) CV_LOAD_IMAGE_GRAYSCALE ( 0),以灰度图像读取3) CV_LOAD_IMAGE_COLOR (&0),以RGB格式读取
转载请注明出处:http://blog.csdn.net/u/article/details/
阅读(...) 评论()怎么用opencv获取图像灰度值(用C语言)_百度知道
怎么用opencv获取图像灰度值(用C语言)
我想做基于NCC的图像匹配,第一步想用opencv获取图像的灰度值,求一个详细的程序。另外我用的图像是彩色的,需要先把彩图变成灰度图吗?这里有点迷惑,彩色图像的灰度值可以直接得到吗?
我有更好的答案
1、可以变成灰度图也可以不变。这里假设你的图像都是IPL_DEPTH_8U类型。2、如果变成灰度图,就是单通道图像,获取的就是每一个像素点的灰度值。 IplImage* img = cvLoadImage(&test.bmp&, 0); for (int i = 0; i & img-& i++) {
for (int j = 0; j & img-& j++)
//方法一:使用cvGet2D()函数间接访问
CvScalar s = cvGet2D(img, i, j); //其中i代表y轴(第i行),即height;j代表x轴(第j列),即width。
printf(&gray value=%f\n&,s.val[0]);
//方法二:使用直接访问
uchar val = ((uchar *)(img-&imageData + i*img-&widthStep))[j]; //i和j的意义同上
printf(&gray value=%d\n&,val);
} }3、如果不变成灰度图,就是3通道图像,获取的就是每一个像素点的BGR值,然后分别获取B值,G值和R值。 IplImage* img = cvLoadImage(&test.bmp&, 1); for (int i = 0; i & img-& i++) {
for (int j = 0; j & img-& j++)
//方法一:使用cvGet2D()函数间接访问
CvScalar s=cvGet2D(img,i,j); //其中i代表y轴(第i行),即height;j代表x轴(第j列),即width。
printf(&B=%f, G=%f, R=%f\n&,s.val[0],s.val[1],s.val[2]); //注意是BGR顺序
//方法二:使用直接访问
int bVal = ((uchar *)(img-&imageData + i*img-&widthStep))[j*img-&nChannels + 0]; // B
int gVal = ((uchar *)(img-&imageData + i*img-&widthStep))[j*img-&nChannels + 1]; // G
int rVal = ((uchar *)(img-&imageData + i*img-&widthStep))[j*img-&nChannels + 2]; // R
printf(&B=%d, G=%d, R=%d\n&,bVal,gVal,rVal);
//注意是BGR顺序
采纳率:57%
1、可以变成灰度图也可以不变。这里假设你的图像都是IPL_DEPTH_8U类型。2、如果变成灰度图,就是单通道图像,获取的就是每一个像素点的灰度值。
IplImage* img = cvLoadImage(&test.bmp&, 0);
for (int i = 0; i & img-& i++)
for (int j = 0; j & img-& j++)
//方法一:使用cvGet2D()函数间接访问
CvScalar s = cvGet2D(img, i, j);
//其中i代表y轴(第i行),即height;j代表x轴(第j列),即width。
printf(&gray value=%f\n&,s.val[0]);
//方法二:使用直接访问
uchar val = ((uchar *)(img-&imageData + i*img-&widthStep))[j];
//i和j的意义同上
printf(&gray value=%d\n&,val);
}3、如果不变成灰度图,就是3通道图像,获取的就是每一个像素点的BGR值,然后分别获取B值,G值和R值。
IplImage* img = cvLoadImage(&test.bmp&, 1);
for (int i = 0; i & img-& i++)
for (int j = 0; j & img-& j++)
//方法一:使用cvGet2D()函数间接访问
CvScalar s=cvGet2D(img,i,j); //其中i代表y轴(第i行),即height;j代表x轴(第j列),即width。
printf(&B=%f, G=%f, R=%f\n&,s.val[0],s.val[1],s.val[2]);
//注意是BGR顺序
//方法二:使用直接访问
int bVal = ((uchar *)(img-&imageData + i*img-&widthStep))[j*img-&nChannels + 0]; // B
int gVal = ((uchar *)(img-&imageData + i*img-&widthStep))[j*img-&nChannels + 1]; // G
int rVal = ((uchar *)(img-&imageData + i*img-&widthStep))[j*img-&nChannels + 2]; // R
printf(&B=%d, G=%d, R=%d\n&,bVal,gVal,rVal);
//注意是BGR顺序
为您推荐:
其他类似问题
图像灰度的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。

我要回帖

更多关于 opencv读取摄像头图像 的文章

 

随机推荐