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

来源:互联网 发布:中兴无线软件开发 编辑:程序博客网 时间:2024/04/29 05:25
/*定义各种形状*/#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);}
原创粉丝点击