您的位置:首页 > 产品设计 > UI/UE

OpenCV学习笔记08--细说HighGUI

2015-06-04 12:45 501 查看
细说HighGUI

HighGUI一共分为三部分:

一、硬件相关部分,即对摄像机的操作

二、文件系统部分,即载入与保存图像

三、窗口系统部分,如对键盘鼠标的响应



1、创建窗口 cvNamedWindow();

销毁窗口 cvDestroyWindow();

调整窗口大小 cvResizeWindow();

2、载入图像 cvLoadImage();

保存图像 cvSaveImage();

显示图像 cvShowImage();

3、等待按键 cvWaitKey();



鼠标按下 cvSetMouseCallback(window_name,on_mouse,param=NULL);

创建滑动条 cvCreateTrackbar(trackname,windowname,value,count,on_change);

鼠标按下和创建滑动条必须使用回调函数,详见例十二(鼠标按下),学习笔记三和学习笔记七(滑动条)。



得到滑动条的位置 cvGetTrackbarPos();

设置滑动条的位置 cvSetTrackbarPos();

4. 从摄像机得到图像 cvCreateCameraCapture();

从文件得到图像 cvCreateFileCapture(); 参数为-1时选择摄像机。



读取视频帧:方法一:cvQueryFrame(); 返回IplImage*指针

方法二:cvGrabFrame(); 将视频帧读入内存

cvRetriveFrame(); 对图像进行解码,并返回IplImage*指针。



得到视频的属性:cvGetCaptureProperty(capture,property_id);

设置视频的属性:cvSetCaptureProperty(capture,property_id,value);



保存视频:

创建写入视频的结构:cvCreateVideoWriter();

写入视频: cvWriteFrame();

释放内存: cvReleaseVideoWriter();

5.一个不属于任何一类的孤立的函数:cvConventImage(src,dst,flags=0);

用于不同图像格式之间的转换

src可以是单个,三个或四个通道,可以是8位或者浮点型像素格式。

dst必须是8位的单通道或三个通道。

也可以将彩色图像转换为灰度图,或单通道的灰度图转换成三个通道的灰度图(彩色)

flags可以垂直旋转图像









例十二:通过鼠标画矩形



1.首先,我们让屏幕上显示一个矩形

我们首先要实现显示图像的功能,而这个图像是不含任何像素的cvCreateImage创建一个图像,再用cvZero(image)将image里所有通道所有元素的值设为0

#include "stdafx.h"
#include "cv.h"
#include "highgui.h"
 
CvRect box;
void draw_box(IplImage *img, CvRect rect){
cvRectangle(img, cvPoint(box.x, box.y), cvPoint(box.x + box.width, box.y + box.height), cvScalar(0xff, 0x00, 0x00));
}
 
int _tmain(int argc, _TCHAR* argv[])
{
box = cvRect(1, 1, 100, 100);
IplImage *image = cvCreateImage(cvSize(200, 200), IPL_DEPTH_8U, 3);
cvZero(image);//将image里所有通道所有元素的值设为0
cvNamedWindow("Box Example", 0);
draw_box(temp, box);
cvShowImage("Box Example", temp);
cvWaitKey(0);
cvReleaseImage(&image);
cvDestroyWindow("test");
return 0;
}




2.通过鼠标控制画出矩形

鼠标左键按下:得到矩形的x,y坐标

鼠标移动:得到矩形的width和height,并不断更新

鼠标左键抬起:画出矩形,如果width<0或height<0,则取左上角为矩形的起点(左上角的点),然后将width和height取绝对值,画出矩形

但是只有左键抬起后矩形才会显示,而我们鼠标移动时会不断调用回调函数,所以我们设置两张画板,一张image来显示真正保存的图像,即鼠标抬起时画出的图像。另一张temp拷贝之前保存的图像,再显示鼠标移动时不断更新的图像,这样就实现了全部功能。代码如下:



#include "stdafx.h"
#include "cv.h"
#include "highgui.h" 

CvRect box;
bool drawing_box = false;
void my_mouse_callback(int event, int x, int y, int flags, void *param);

void draw_box(IplImage *img, CvRect rect){
	cvRectangle(img, cvPoint(box.x, box.y), cvPoint(box.x + box.width, box.y + box.height), cvScalar(0xff, 0x00, 0x00));
}

int _tmain(int argc, _TCHAR* argv[])
{
	box = cvRect(-1, -1, 0, 0);
	IplImage *image = cvCreateImage(cvSize(200, 200), IPL_DEPTH_8U, 3);
	cvZero(image);//将image里所有通道所有元素的值设为0
	IplImage *temp = cvCloneImage(image);//该函数会自己开一段内存,然后复制好image里面的数据
	cvNamedWindow("Box Example", 0);
	cvSetMouseCallback("Box Example", my_mouse_callback, (void*)image);
	while (1){
		cvCopyImage(image, temp);
		if (drawing_box)draw_box(temp, box);
		cvShowImage("Box Example", temp);
		if (cvWaitKey(15) == 27)break;
	}
	cvReleaseImage(&image);
	cvReleaseImage(&temp);
	cvDestroyWindow("test");
	return 0;
}
void my_mouse_callback(int event, int x, int y, int flags, void *param)
{
	IplImage *image = (IplImage*)param;
	switch (event)
	{
	case CV_EVENT_LBUTTONDOWN:{
								  drawing_box = true;
								  box = cvRect(x, y, 0, 0);
	                           }
		                      break;
	case CV_EVENT_MOUSEMOVE:{
								if (drawing_box){
									box.width = x - box.x;
									box.height = y - box.y;
							        }
	                         }
		                      break;
	case CV_EVENT_LBUTTONUP:{
								drawing_box = false;
								if (box.width < 0){
									box.x += box.width;
									box.width *= -1;
								}
								if (box.height < 0){
									box.y += box.height;
									box.height *= -1;
								}
								draw_box(image, box);
	                          }
							  break;
	}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: