Opencv基础学习笔记
2017-03-20 19:52
330 查看
GUI指令
创建和定位一个新窗口:
cvNamedWindow("win1",CV_WINDOW_AUTOSIZE); cvMoveWindow("win1",100,100);//从屏幕的左上开始偏移
载入图像:
IPlImage* img = 0; img = cvLoadImage(filename); if(!img) printf("Could not load image file: %s\n",filename);
显示图像:
cvShowImage("win1,img");
关闭窗口:
cvDestroyWindow("win1");
改变窗口大小:
cvResizeWindow("win1",100,100);//新的窗口大小输入处理
(1) 处理鼠标事件:
1 定义一个鼠标处理程序(监听):void mouseHandler( int event, //各种鼠标事件:CV_EVENT_LBUTTONDOWN CV_EVENT_RBUTTONDOWN …… int x, int y, //x,y相当于左上角的像素坐标 int flags, // void* param)
例子:
e.g. void mouseHandler(int event,int x,int y,int flags,void* param) { switch(event) { case CV_EVENT_LBUTTONDOWN: { if(flags & CV_EVENT_FLAG_CTRLKEY) printf("Left button down with CTRL pressed\n"); break; } case CV_EVENT_LBUTTONUP: { printf("Left button up!\n");//左键按住了 break; } } }
2 注册该事件处理程序(响应):
mouseParam = 5; cvSetMouseCallback("win1",mouseHandler,&mouseParam);
处理键盘事件
//1 按一定时间间隔检测键盘输入(适用于循环体中) int key; key = cvWaitKey(10); //2 中止程序等待键盘输入: int key; key = cvWaitKey(0);
例子:
e.g. while(1) { key = cvWaitKey(10);//返回值为按下的码键 if(key == 27) break; switch(key) { case 'h': ... break; case 'i': ... break; } }
处理滑动条事件
//1 定义一个滑动条处理程序: void trackbarHandler(int pos) { printf("Trackbar position: %d\n",pos); } //2 注册该事件的处理程序: int trackbarVal = 25; int maxVal = 100; cvCreateTrackbar("bar1","win1",&trackbarVal,maxVal,trackbarHandler); //3 获取当前滑动条的位置: int pos = cvGetTrackbarPos("bar1","win1"); //4 设置滑动条的位置: cvSetTrackbarPos("bar1","win1",25);
例子:
e.g. one //弹出一个窗口并显示图片 #include<cv.h> #include<highgui.h> int main(int argc,char* argv[]) { IPlImage* image; if(argc != 2) return -1; image = cvLoadImage(argv[1]); if(!image) return -1; cvNamedWindow("Sample",1); cvShowImage("Sample",image); cvWaitKey(); cvDestroyWindow("sample"); cvReleaseImage(&image); return 0; } //run:sample example_pic.jpg
OpenCV数据结构
//PlImage:
typedef struct _IplImage{
int nSize; /*该结构体的大小*/
int ID; /*图像头的版本=0*/
int nChannels; /*通道数,可取1,3,4。如24位图,即RGB是3通道x8位(depth)。取值4,表示32位位图,有Alpha值,即位图透明度*/
int alphaChannel; /*Alpha通道数,没有取0,有则取4(被OpenCV忽略)*/
int depth; /*每个通道的位数*/
char colorModel[4]; /*颜色模式,有Gray、RGB、RGBA、CMYK等(被OpenCV忽略)*/
char channelSeq[4]; /*通道顺序,如“RGB”、“BGR”等*/
int dataOrder; /*0 - 交叉存取颜色通道, 1 - 分开的颜色通道.数据的排列方式(使用像素格式)
cvCreateImage只能创建交叉存取图像*/
int origin; /*坐标原点,有左上角和左下角两种*/
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;
//matrix:
typedef struct CvMat{ /*一维矩阵*/
int type; /*数据类型(CV_32FC1、CV_8UC3)*/
int step; /*每行数据的字节数:元素个数*元素类型的字节长度*/
/*仅供内部使用*/
int* refcount;
int hdr_refcount;
union
{
uchar* ptr; /*指向date的第一个元素*/
short* s;
int* i;
float* fl;
double* db;
} data;
typedef struct CvMatND /*N-维矩阵*/
{
int type; /*数据类型*/
int dims; /*矩阵维数*/
int* refcount;
int hdr_refcount;
union
{
uchar* ptr;
float* fl;
double* db;
int* i;
short* s;
} data;
struct /*各维信息*/
{
int size; /*元素数目*/
int step; /*元素间距:字节*/
}dim[CV_MAX_DIM];
}CvMatND;
//point:
CvPoint p = cvPoint(int x,int y);CvPoint2D32f p = cvPoint(float x,float y);
p.x = 5.0;
p.y = 5.0;
//矩形框大小:
CvSize r = cvSize(int width,int height);CvSize2D32f r = cvSize2D32f(float width,float height);
//矩形框的偏置和大小:
CvRect r = cvRect(int x,int y,int width,int height);图像和视频处理
复制图像:
IPlImage* img1 = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1); IPlImage* img2; imag2 = cvCloneImage(img1);/*通过克隆得到的图像也需要使用cvReleaseImage释放内存*/
图像的读写和保存:
Opencv默认将读入的图像转换为一副三通道彩色图像,但可以通过一下方法修改:Opencv默认将读入的图像转换为一副三通道彩色图像,但可以通过一下方法修改: img = cvLoadImage(filename,flag); flag: >0 将读入的图像强制转换为一幅三通道彩色图像 =0 将读入的图像强制转换为一个单通道灰度图像 <0 读入图像保持原样
保存图像:
cvSaveImage(outfilename,img);//保存的图像格式由outfilename的后缀决定
访问图像像素
假设要访问第K通道,第i行,第j列的像素way1:间接访问(通用,但效率低,可以访问任意格式的图像)
//a、 对于单通道字节型: IPlImage* img = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1); CvScalar s; s = cvGet2D(img,i,j);//获取该图像中第i行,第j列的像素值 printf("intensity = %f\n",s.val[0]);//输出原来的像素值 s.val[0] = 111;//输入最新值 cvSet2D(img,i,j,s);//重置像素值 //b、 对于多通道字节型/浮点型: IPlImage* img = cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3); CvScalar s; s = cvGet2D(img,i,j); 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);
way2:直接访问(效率高,但容易出错)
//a、 对于单通道字节型图像: IPlImage* img = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1); ((uchar*)(img->imageData + i*img->widthStep))[j] = 111;//偏移地址 //b、 对于多通道字节型图像: IPlImage* img = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3); ((uchar*)(img->imagData + i*img->widthStep))[j*img->nChannels + 0] = 111;//B ((uchar*)(img->imagData + i*img->widthStep))[j*img->nChannels + 1] = 112;//B ((uchar*)(img->imagData + i*img->widthStep))[j*img->nChannels + 2] = 113;//B //c、 对于单通道浮点型图像: IPlImage* img = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3); ((float*)(img->imagData + i*img->widthStep))[j*img->nChannels + 0] = 111;//B ((float*)(img->imagData + i*img->widthStep))[j*img->nChannels + 1] = 112;//B ((float*)(img->imagData + i*img->widthStep))[j*img->nChannels + 2] = 113;//B
way3:基于指针的直接访问:(简单高效)
//a、 对于单通道字节型图像: IPlImage* img = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1); int height = img->heigth; int width = img->width; int step = img->widthStep/sizeof(uchar);//每一行字节数 uchar* data = (uchar*)img->imagData;//获取原图像数据的字节型指针 data[i*step +j] = 111; //b、 对于多通道字节型图像: IPlImage* img = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1); int height = img->heigth; int width = img->width; int step = img->widthStep/sizeof(uchar);//每一行字节数 uchar* data = (uchar*)img->imagData;//获取原图像数据的字节型指针 data[i*step +j*channels] = 111; //c、 对于多通道浮点型图像:假设图像采用4字节行对齐方式,即每行数据的长度必须是四字节的整数倍数 IPlImage* img = cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,1); int height = img->heigth; int width = img->width; int step = img->widthStep/sizeof(float);//每一行字节数 float* float = (float*)img->imagData;//获取原图像数据的字节型指针 data[i*step +j*channels] = 111;
图像转换:
//a、 字节型图像的灰度-彩色转换: cvConvertImage(src,dst,flags=0);//图像转换函数 src = float/byte grayscale/color imag data = byte grayscale/color imag //输入图像的通道数必须是1,3或者4 //输出图像的深度必须是8位的单通道或3通道。 flags: CV_CVTIMG_FLIP //(垂直翻转图像) CV_CVTIMG_SWAP_RB //(置换R-B通道) //b、 彩色图像->灰度图像: //way1:使用函数 cvCvtColor(cimg,gimg,CV_BGR2GRAY);//cimg->gimg //way2:直接转换 for(i=0;i<cimg->height;i++) for(j=0;j<cimg->width;j++) gimgA[i][j] = (uchar)(cimgA[i][j].b*0.114+cimgA[i][j].g*0.587+cimgA[i][j].r*0.299); //c、 不同彩色空间之间的转换: cvCvColor(src,dst,code)://src->dst //格式:code = CV_<X>2<Y> <X>/<Y> = RGB,BGR,GRAY,HSV,YCrCb,XYZ,Lab,Luv,HLS e.g. CV_BGR2GRAY,CV_BGR2HSV,CV_BGR2Lab
绘图指令:
//1 绘制矩形 //在坐标为(100,100)和(200,200)的点之间画一个矩形,边线为红色,宽度为1 cvRectangle(img,cvPoint(100,100),cvPoint(200,200),cvScalar(255,0,0),1); //2 绘制原形 //圆心坐标(100,100),半径20,圆周为绿色,宽度为1 cvCircle(img,cvPoint(100,100),20,cvScalar(0,255,0),1); //3 绘制线段 //在坐标为(100,100)和(200,200)的点之间画一条宽为1的绿色线段 cvLine(img,cvPoint(100,100),cvPoint(200,200),cvScalar(0,255,0),1);
e.g.
//获取摄像头图像实例:获取摄像头视频显示在窗口里 #include "stdafx.h" #include "cv.h" #include "highgui.h" int _tmain(int argc, _TCHAR* argv[]) //vs2013中需改为多字节编码方式 { cvNamedWindow("video", CV_WINDOW_AUTOSIZE); //创建窗口 CvCapture* caputre; //该结构体存放一帧图像 if (argc == 1) caputre = cvCaptureFromCAM(0); //从摄像头获取视频初始化caputre结构体 else caputre = cvCreateFileCapture(argv[1]); //从指定视频文件中获取视频初始化caputre结构体 assert(caputre != NULL); IplImage* frame; while (1) { frame = cvQueryFrame(caputre); //从摄像头或者文件中抓取并返回一帧 if (!frame) break; cvShowImage("video",frame); //将一帧画面显示在窗口 char c = cvWaitKey(33); //每帧显示33ms if (c == 27) //ESC退出 break; } cvReleaseCapture(&caputre); //停止读取文件并释放内存 cvDestroyWindow("video"); return 0; }
效果:
参考:《学习OpenCv》
ps:第一次用目录,貌似有的风格显示不了目录
相关文章推荐
- 基础学习笔记之opencv(3):haartraining生成.xml文件过程
- 基础学习笔记之opencv(8):Mat - 基本图像容器
- 基础学习笔记之opencv(1):opencv中facedetect例子浅析
- 基础学习笔记之opencv(3):haartraining生成.xml文件过程
- 基础学习笔记之opencv(5):实现鼠标选定矩形框
- 基础学习笔记之opencv(4):直方图使用学习
- openCv学习笔记(一)——数字图形的基础和结构
- 基础学习笔记之opencv(20):OpenCV中的颜色空间(ing...)
- 基础学习笔记之opencv(17):皮肤检测类CvAdaptiveSkinDetector的使用
- 基础学习笔记之opencv(18):kmeans函数使用实例
- 基础学习笔记之opencv(6):实现将图片生成视频
- 基础学习笔记之opencv(13):基本绘图
- 基础学习笔记之opencv(1):opencv中facedetect例子浅析
- 基础学习笔记之opencv(10):Mat mask操作
- 基础学习笔记之opencv(21):一个简单有趣的皮肤检测代码
- 基础学习笔记之opencv(7):ubuntu下opencv在Qt中的使用
- 基础学习笔记之opencv(12):改变图像对比度和亮度
- 基础学习笔记之opencv(14):随机数发生器&绘制文字
- 基础学习笔记之opencv(24):imwrite函数的使用
- 基础学习笔记之opencv(23):OpenCV坐标体系的初步认识