opencv学习(六)书本《学习Opencv》(中文版)第四章的作业答案第二题(opencv3.0.0+VS2012+win7)
来源:互联网 发布:笛子软件下载 编辑:程序博客网 时间:2024/04/30 09:54
显示坐标很简单,但是显示RGB就必须要非常了解IPlImage结构如何获取数据了,书上讲的非常繁杂,下面仔细分析一下IPlImage结构,
opencv最重要的结构体是IplImage结构。从本质上讲,这是一个CvMat对象,但它还有一些其他成员变量将矩阵解释为图像
IplImage结构具体定义如下:
typedef struct _IplImage{int nSize; /* IplImage大小 */int ID; /* 版本 (=0)*/int nChannels; /* 大多数OPENCV函数支持1,2,3 或 4 个通道 */int alphaChannel; /* 被OpenCV忽略 */int depth; /* 像素的位深度,主要有以下支持格式: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16U,IPL_DEPTH_16S, IPL_DEPTH_32S,IPL_DEPTH_32F 和IPL_DEPTH_64F */char colorModel[4]; /* 被OpenCV忽略 */char channelSeq[4]; /* 同上 */int dataOrder; /* 0 - 交叉存取颜色通道, 1 - 分开的颜色通道.只有cvCreateImage可以创建交叉存取图像 */int origin; /*图像原点位置: 0表示顶-左结构,1表示底-左结构 */int align; /* 图像行排列方式 (4 or 8),在 OpenCV 被忽略,使用 widthStep 代替 */int width; /* 图像宽像素数 */int height; /* 图像高像素数*/struct _IplROI *roi; /* 图像感兴趣区域,当该值非空时,只对该区域进行处理 */struct _IplImage *maskROI; /* 在 OpenCV中必须为NULL */void *imageId; /* 同上*/struct _IplTileInfo *tileInfo; /*同上*/int imageSize; /* 图像数据大小(在交叉存取格式下ImageSize=image->height*image->widthStep),单位字节*/char *imageData; /* 指向排列的图像数据 */int widthStep; /* 排列的图像行大小,以字节为单位 */int BorderMode[4]; /* 边际结束模式, 在 OpenCV 被忽略*/int BorderConst[4]; /* 同上 */char *imageDataOrigin; /* 指针指向一个不同的图像数据结构(不是必须排列的),是为了纠正图像内存分配准备的 */} IplImage;
IplImage结构体是整个OpenCV函数库的基础,在定义该结构变量时需要用到函数cvCreatImage,变量定义方法如下:
IplImage* src= cvCreateImage(cvSize(400,300), IPL_DEPTH_8U,3);上句定义了一个IplImage指针变量src,图像的大小是400×300,图像颜色深度8位,3通道图像。
关键在这一句:
uchar* bgr = (uchar*)Img->imageData + Img->widthStep * point.y + Img->nChannels * point.x;//获取某个像素点大神的分析:
你应该是刚学opncv吧,widthstep是指图像每行所占的字节数,主要要和width区别,width是指每行所含的像素个数,但是一个像素也可能占一个字节,也可能占三个字节或者四个.imagedata是指向存储图像像素值数组的指针,内容是这个数组的首地址,point.y指的是像素点的行坐标,所以Img->imageData + Img->widthStep*point.y便是该像素点所在行的首地址,然后再加上该像素点所在的列,即point.x,就得到了该像素点的地址.
真大神:http://www.cnblogs.com/uriboyka/archive/2013/04/23/3038788.html
假设你要访问第K通道,第i行,第j列的像素
一 间接访问:(通用,但效率低,可访问任意格式的图像)
对于单通道字节型图像:
IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1); CvScalar s; s=cvGet2D(img,i,j); /* get the (j,i) pixel value, 注意cvGet2D与cvSet2D中坐标参数的顺序与其它opencv函数坐标参数顺序恰好相反.本函数中i代表y轴,即height;j代表x轴,即weight.也即先cvGet2D的第二个参数i表示行号,第三个参数j表示列号。而元素的坐标值的(j,i) printf("intensity=%f\n",s.val[0]);*/ s.val[0]=111; cvSet2D(img,i,j,s); // set the (j,i) pixel value设置像素值
对于多通道字节型/浮点型图像:
IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3); CvScalar s; s=cvGet2D(img,i,j); // get the (j,i) pixel value printf("B=%f, G=%f, R=%f\n",s.val[0],s.val[1],s.val[2]); s.val[0]=111; s.val[1]=111; s.val[2]=111; cvSet2D(img,i,j,s); // set the (j,i) pixel value
二 直接访问:(效率高,但容易出错)
对于单通道字节型图像:
1 IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1); 2 ((uchar *)(img->imageData + i*img->widthStep))[j]=111;对于多通道字节型图像:
1 IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3); 2 ((uchar *)(img->imageData + i*img->widthStep))[j*img->nChannels + 0]=111; // B 3 ((uchar *)(img->imageData + i*img->widthStep))[j*img->nChannels + 1]=112; // G 4 ((uchar *)(img->imageData + i*img->widthStep))[j*img->nChannels + 2]=113; // R
对于多通道浮点型图像:
1 IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3); 2 ((float *)(img->imageData + i*img->widthStep))[j*img->nChannels + 0]=111; // B 3 ((float *)(img->imageData + i*img->widthStep))[j*img->nChannels + 1]=112; // G 4 ((float *)(img->imageData + i*img->widthStep))[j*img->nChannels + 2]=113; // R
三 基于指针的直接访问:(简单高效)
对于单通道字节型图像:
1 IplImage* img = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1); 2 int height = img->height; 3 int width = img->width; 4 int step = img->widthStep; 5 uchar* data = (uchar *)img->imageData; data[i*step+j] = 111;
对于多通道字节型图像:
1 IplImage* img = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3); 2 int height = img->height; 3 int width = img->width; 4 int step = img->widthStep; 5 int channels = img->nChannels; 6 uchar* data = (uchar *)img->imageData; 7 data[i*step+j*channels+k] = 111;
对于多通道浮点型点型图像(假设图像数据采用4字节(32位)行对齐方式):
1 IplImage* img = cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3); 2 int height = img->height; 3 int width = img->width; 4 int step = img->widthStep; 5 int channels = img->nChannels; 6 float * data = (float *)img->imageData; 7 data[i*step+j*channels+k] = 111;
由此可以知道第二题找到BGR像素值就不难了
源码如下:
#include "cv.h" #include "highgui.h" #include<string>#include<iostream>#include<cstdio>using namespace std;void my_mouse_callback(int event, int x, int y, int flags, void* param); void putText(IplImage* image, CvPoint point); void putText2(IplImage* image, CvPoint point); CvPoint point;int main(int argc, char** argv){ cvNamedWindow("taenshow",CV_WINDOW_AUTOSIZE); IplImage* image = cvLoadImage(argv[1]); cvShowImage("taenshow",image);while(1){cvSetMouseCallback("taenshow",my_mouse_callback,(void*)image); char c = (char)cvWaitKey(33); if( c == 27 ) break; } return 0; } void my_mouse_callback(int event, int x, int y, int flags, void* param) { IplImage* img = (IplImage*)param; switch(event){case CV_EVENT_LBUTTONDOWN :point.x = x;point.y = y;putText(img,point);break;case CV_EVENT_RBUTTONDOWN:point.x=x;point.y=y;putText2(img,point);break; }} void putText(IplImage* image, CvPoint point) { char color[100],px[100],py[100];_itoa(point.x,px,10);//整数转换成字符串;_itoa(point.y,py,10);//整数转换成字符串;strcpy(color,"("); strcat(color,px);strcat(color,",");strcat(color,py);strcat(color,")"); CvFont font ; cvInitFont(&font,CV_FONT_HERSHEY_SIMPLEX,0.5,0.5,0); cvPutText(image,color,point,&font,cvScalar(0,0,255)); //BGR cvShowImage("taenshow",image);}void putText2(IplImage* Img,CvPoint point)//鼠标左键显示颜色值RGB{ //定义bgr接受像素颜色信息 uchar* bgr = (uchar*)Img->imageData + Img->widthStep * point.y + Img->nChannels * point.x;//获取某个像素点,直接访问//CvScalar s = cvGet2D(Img,point.x,point.y);//获取像素点为(x,y)点的BGR的值,貌似有问题,在某些像素点报错?char color[100];//显示颜色值字符串char cb[16],cg[16],cr[16];//单个颜色值字符串 //sprintf_s(cb,"%f",bgr[0]);//double转string//sprintf_s(cg,"%f",bgr[1]);//sprintf_s(cr,"%f",bgr[2]);_itoa(bgr[0],cb,10);//int转string_itoa(bgr[1],cg,10);_itoa(bgr[2],cr,10); //_itoa(s.val[0],cb,10);//_itoa(s.val[1],cg,10);//_itoa(s.val[2],cr,10); strcpy(color,"("); strcat(color,cb);strcat(color,",");strcat(color,cg);strcat(color,",");strcat(color,cr);strcat(color,")"); //初始化显示字体CvFont font; cvInitFont(&font,CV_FONT_HERSHEY_SIMPLEX,0.5,0.5); //颜色信息显示 cvPutText(Img,color,cvPoint(point.x,point.y),&font,CV_RGB(255,255,0)); //BGR cvShowImage("taenshow",Img);}
- opencv学习(六)书本《学习Opencv》(中文版)第四章的作业答案第二题(opencv3.0.0+VS2012+win7)
- opencv学习(五)书本《学习Opencv》(中文版)第四章的作业答案第一题(opencv3.0.0+VS2012+win7)
- opencv学习(三)书本《学习Opencv》(中文版)第四章的样例Ex4-1(opencv3.0.0+VS2012+win7)
- opencv学习(四)书本《学习Opencv》(中文版)第四章的样例Ex4-2(opencv3.0.0+VS2012+win7)
- opencv学习(二)书本《学习Opencv》(中文版)第二章的习题试着做做(opencv3.0.0+VS2012+win7)
- opencv学习(一)书本《学习Opencv》(中文版)的第二章的10个入门样例的分析
- 学习OpenCV第四章第二题答案
- opencv学习(八)(opencv3.0.0+VS2012+win7)一个找到轮廓并上色的例子
- opencv学习(九)(opencv3.0.0+VS2012+win7)一个运动检测的例子
- opencv学习(十)(opencv3.0.0+VS2012+win7)打开摄像头并且进行人脸识别的例子
- 学习OpenCV第四章第四题答案
- 【读书笔记】学习OpenCV(中文版)第二章
- opencv 学习第四天 学习opencv(中文版) alpha融合
- 学习openCV第四章答案
- opencv学习(七)(opencv3.0.0+VS2012+win7)打开摄像头并且进行边缘检测加上了滑动条
- 学习OpenCV第四章第一题答案
- 学习OpenCV第四章第五题答案
- 【读书笔记】学习OpenCV(中文版)第四章1
- iOS开发:开发中如何更改项目名
- MS SQL Server之光标、存储过程和触发器
- c++中的map用法详解
- 悬崖勒马之三年编码的反省
- C语言字符串处理函数
- opencv学习(六)书本《学习Opencv》(中文版)第四章的作业答案第二题(opencv3.0.0+VS2012+win7)
- android实现类似toast效果的圆角dialog警告框
- tmux(终端方便使用cp:http://wowubuntu.com/tmux.html)
- 南邮 OJ 1585 分礼物
- 怎么编辑pdf文件
- git项目创建
- malloc和new有什么区别
- J2E学习路线
- 彻底理解JAVA动态代理