《学习OpenCV(中文版)》第4章 练习5a

/*定义各种形状*/
#define SHAPE_NONE 0
#define SHAPE_LINE 1
#define SHAPE_RECT 2
#define SHAPE_CIRCLE 3
#define SHAPE_ELLIPSE 4
#define SHAPE_PLYGON 5
 
#define SHAPE_COUNT 6	//总的形状数,包括清空(SHAPE_NONE)
#define _ERASER 6		//橡皮擦标识
 
int width = 300;
int height = 300;
int shape_status = SHAPE_NONE;		//记录各种状态
CvPoint begin_pointend_point;		//鼠标摁下及松开时的坐标
void on_mouse_callback(int eventint xint yint flagsvoidparam) {
	IplImageimg1 = (IplImage*)param;
	switch(event) {
	case CV_EVENT_LBUTTONDOWN:			//鼠标左边点击,确定行为
		{
			int perWidth = width/SHAPE_COUNT;	//每个按钮的宽度
			if(y>height) {					//点击自定义的按钮
				if(x<perWidth) {
					shape_status = SHAPE_LINE;
				} else if(x<2*perWidth) {
					shape_status = SHAPE_RECT;
				} else if(x<3*perWidth) {
					shape_status = SHAPE_CIRCLE;
				} else if(x<4*perWidth) {
					shape_status = SHAPE_ELLIPSE;
				} else if(x<5*perWidth) {
					shape_status = SHAPE_PLYGON;
				} else {
					shape_status = SHAPE_NONE;
					cvSetImageROI(img1cvRect(0, 0, widthheight));	//清空画面
					cvZero(img1);
					cvResetImageROI(img1);
				}
			} else {
				//记录起点
				if(shape_status != SHAPE_NONE) {
					begin_point.x = x;
					begin_point.y = y;
				}				
			}
			break;
		}
	case CV_EVENT_RBUTTONDOWN:
		{
			shape_status = _ERASER;
			break;
		}
	case CV_EVENT_LBUTTONUP:		//鼠标左键起来时,各种画图
		{
			if(y<height) {			//在画面区域时
				cvSetImageROI(img1cvRect(0, 0, widthheight));	//限定在画面区域,避免自定义按钮被覆盖或清空
				//记录终点
				if(shape_status != SHAPE_NONE) {
					end_point.x = x;
					end_point.y = y;
				}
				switch(shape_status) {
				case SHAPE_LINE:
					{
						cvLine(img1begin_pointend_pointcvScalar(255, 0, 0));	//画直线
						break;
					}
				case SHAPE_RECT:
					{
						cvRectangle(img1begin_pointend_pointcvScalar(0, 255, 0));	//画矩形
						break;
					}
				case SHAPE_CIRCLE:
					{
						cvCircle(
							img1begin_point,	//以起点为圆心
							std::sqrt(std::pow(1.0*(end_point.x-begin_point.x), 2)+std::pow(1.0*(end_point.y-begin_point.y), 2)*1.0f),	//两点距离为半径
							cvScalar(0, 0, 255));
						break;
					}
				case SHAPE_ELLIPSE:
					{
						cvEllipse(
							img1cvPoint((begin_point.x+end_point.x)/2, (begin_point.y+end_point.y)/2),	//两点中点为中心
							cvSize(std::abs(end_point.x - begin_point.x), std::abs(end_point.y - begin_point.y)),	//两点为对角所确定的矩形区域
							0,
							0,
							360,
							cvScalar(255, 255, 0)
							);
						break;
					}
				case SHAPE_PLYGON:
					//do nothing,还没想好怎么画
 
					break;
				}
				cvResetImageROI(img1);
			}
			cvShowImage("Picture"img1);
			break;
		}
	case CV_EVENT_RBUTTONUP:
		{
			shape_status = SHAPE_NONE;
			break;
		}
	case CV_EVENT_MOUSEMOVE:
		{
			if(shape_status == _ERASER && y<height) {
				for(int i=-2; i<=2; i++) {		//橡皮擦,以(x,y)为中心的大小为5的矩形橡皮擦
					for(int j=-2; j<=2; j++) {
						//所经过的点复原为0
						*(cvPtr2D(img1y+ix+j)+0) = 0;
						*(cvPtr2D(img1y+ix+j)+1) = 0;
						*(cvPtr2D(img1y+ix+j)+2) = 0;
					}
				}				
			}
			cvShowImage("Picture"img1);
			break;
		}
	}
}
void myGUI5a() {
	cvNamedWindow("Picture");
	int delta = 40;
	IplImageimg = cvCreateImage(cvSize(widthheight+delta), IPL_DEPTH_8U, 3);	//加20用于做按钮
	cvZero(img);
	//自定义按钮
	//cvLine(img, cvPoint(0, height), cvPoint(width, height), cvScalar(255, 255, 255));
	int perWidth = width/SHAPE_COUNT;	//每个按钮的宽度
	for(int i=0; i<SHAPE_COUNTi++) {
		int next_row = height + delta;
		int next_col = (i+1)*perWidth;
		int color = 255 - 20*i;			//按钮不同颜色
		for(int row=height;row<next_rowrow++) {
			for(int col=i*perWidth;col<next_colcol++) {
				*(cvPtr2D(imgrowcol)+0) = color;
				*(cvPtr2D(imgrowcol)+1) = color;
				*(cvPtr2D(imgrowcol)+2) = color;
			}
		}
	}
	
	cvSetMouseCallback("Picture"on_mouse_callbackimg);
	cvShowImage("Picture"img);
	cvWaitKey(0);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值