OpenCV之鼠标画图

最近在学习OpenCV,网上关于OpenCV编程的介绍有很多,今天学习了MoreWindows博客中的鼠标绘图(http://blog.csdn.net/morewindows/article/details/8426283),自己动手按照教程一步步学习,并做了些改动,相当于是自己举一反三吧。所有代码均验证通过。

1.鼠标画线

这里就按照MoreWindows博客的介绍进行处理,只不过为了偷懒,有些变量名字就自己随便取了。

设计思想是鼠标按下之后,设置画图标志位有效,鼠标移动时调用回调函数进行画线,鼠标恢复之后画图标志位无效,鼠标移动时不再画线。

为了实现这样的功能,需要设置全局标志位draw_flag以及画线的起始点和终点point_start和point_end,每一次画线结束后将point_start用point_end的值进行更新。

#include <opencv2/opencv.hpp>
#include <cv.h>
#include <highgui.h>
bool img_flag=false;
char *window_name="test";
void mousecallback(int event,int x,int y,int flags,void *param)
{
	static CvPoint point_start,point_end;
	static bool draw_flag=false;
	switch(event)
	{
	case CV_EVENT_LBUTTONDOWN:
		{
			draw_flag=true;point_start=cvPoint(x,y);
			break;
		}
	case CV_EVENT_LBUTTONUP:
		{
			draw_flag=false;
			break;
		}
	case CV_EVENT_MOUSEMOVE:
		{
			if(draw_flag==true)
			{
				point_end=cvPoint(x,y);
				cvLine((IplImage *)param,point_start,point_end,CV_RGB(0,255,0));
				cvShowImage(window_name,(IplImage *)param);
				point_start=point_end;
				break;
			}
		}
	}
}
int main(int argc, char* argv[])
{
	IplImage *img=cvCreateImage(cvSize(800,600),IPL_DEPTH_8U,3);
	cvRectangle(img,cvPoint(0,0),cvPoint(img->width,img->height),cvScalar(0xff,0xff,0xff));
	cvNamedWindow(window_name,CV_WINDOW_AUTOSIZE);
	cvShowImage(window_name,img);
	cvSetMouseCallback(window_name,mousecallback,img);
	while(1)
	{
		if(cvWaitKey(15)==27)
			break;
	}
	cvDestroyWindow(window_name);
	cvReleaseImage(&img);
	return 0;
}

2.鼠标画单个矩形

这里与画线的改变在于,画完之后不保存在背景中,因此要复制背景的副本img_clone,并在该副本上进行操作。

#include "stdafx.h"

#include <opencv2/opencv.hpp>
#include <cv.h>
#include <highgui.h>

bool img_flag=false;
char *window_name="test";
void mousecallback(int event,int x,int y,int flags,void *param)
{
	static CvPoint point_start,point_end;
	static bool draw_flag=false;
	IplImage *img_clone=cvCloneImage((IplImage*)param);
	switch(event)
	{
		case CV_EVENT_LBUTTONDOWN:
			{
				draw_flag=true;
				point_start=cvPoint(x,y);
				break;
			}
		case CV_EVENT_LBUTTONUP:
			{
				draw_flag=false;
				break;
			}
		case CV_EVENT_MOUSEMOVE:
			{
				if(draw_flag==true)
					{
						point_end=cvPoint(x,y);
						cvRectangle(img_clone,point_start,point_end,CV_RGB(0,255,0));
						cvShowImage(window_name,img_clone);
						break;
					}
			}
	}
}
int main(int argc, char* argv[])
{

	IplImage *img=cvCreateImage(cvSize(800,600),IPL_DEPTH_8U,3);
	cvRectangle(img,cvPoint(0,0),cvPoint(img->width,img->height),cvScalar(0xff,0xff,0xff));

	cvNamedWindow(window_name,CV_WINDOW_AUTOSIZE);
	cvShowImage(window_name,img);

	cvSetMouseCallback(window_name,mousecallback,img);

	while(1)
	{
		if(cvWaitKey(15)==27)
			break;
	}
	cvDestroyWindow(window_name);
	cvReleaseImage(&img);

	return 0;

}

3.鼠标画矩形并保留

这里与第2个改动在于,在CV_EVENT_BUTTONUP事件发生后,将矩形画在背景中,而不是副本上。同时,CV_EVENT_MOUSEMOVE事件中的操作仍然是对副本进行。

#include "stdafx.h"

#include <opencv2/opencv.hpp>
#include <cv.h>
#include <highgui.h>

bool img_flag=false;
char *window_name="test";
void mousecallback(int event,int x,int y,int flags,void *param)
{
	static CvPoint point_start,point_end;
	static bool draw_flag=false;
	IplImage *img_clone=cvCloneImage((IplImage*)param);
	switch(event)
	{
		case CV_EVENT_LBUTTONDOWN:
			{
				draw_flag=true;
				point_start=cvPoint(x,y);
				break;
			}
		case CV_EVENT_LBUTTONUP:
			{
				draw_flag=false;
				point_end=cvPoint(x,y);
				cvRectangle((IplImage *)param,point_start,point_end,CV_RGB(0,255,0));
				break;
			}
		case CV_EVENT_MOUSEMOVE:
			{
				if(draw_flag==true)
					{
						point_end=cvPoint(x,y);
						cvRectangle(img_clone,point_start,point_end,CV_RGB(0,255,0));
						cvShowImage(window_name,img_clone);
						break;
					}
			}
	}
}
int main(int argc, char* argv[])
{

	IplImage *img=cvCreateImage(cvSize(800,600),IPL_DEPTH_8U,3);
	cvRectangle(img,cvPoint(0,0),cvPoint(img->width,img->height),cvScalar(0xff,0xff,0xff));

	cvNamedWindow(window_name,CV_WINDOW_AUTOSIZE);
	cvShowImage(window_name,img);

	cvSetMouseCallback(window_name,mousecallback,img);

	while(1)
	{
		if(cvWaitKey(15)==27)
			break;
	}
	cvDestroyWindow(window_name);
	cvReleaseImage(&img);

	return 0;

}


猜你喜欢

转载自blog.csdn.net/DY580C/article/details/30831259