《学习OpenCV》第四章第5题
来源:互联网 发布:8051单片机内部结构图 编辑:程序博客网 时间:2024/06/01 08:00
创建一个程序,可以新建一个图像,并将图像所有像素值设置为0,然后将其显示出来。允许用户通过鼠标左键画线、矩形、圆、椭圆以及多边形。并使其能在右击鼠标时,实现橡皮擦功能。
#include<iostream>#include"highgui.h"#include"cv.h"using namespace std;using namespace cv;#define WIDTH 512#define HEIGHT 512//用来记录多边形的每个点typedef struct Node { CvPoint p; Node *next;}Node;CvPoint point_start; //建一个全体量,用来作为各个图形的开始点CvPoint point_end; //建一个全体量,用来作为各个图形的结束点int g_rnd, r_rnd, b_rnd; //颜色RGB三值随机变量IplImage *img = cvCreateImage(cvSize(WIDTH, HEIGHT), 8, 3); //建一个图片,在其上进行画图操作IplImage *img_copy = cvCreateImage(cvSize(WIDTH, HEIGHT), 8, 3); //建一个图片,用来储存前一步画好后的图片imgchar flag; //建一个标志,确定当前状态int flagmove = 0; //用来判断是否按过左键,来决定移动鼠标是否有响应int flagstart = 1; //或多边形操作时,判断是否是第一个点CvPoint** ps = (CvPoint**)malloc(sizeof(CvPoint*)); //用来存放多边形顶点的二维CvPoint数组Node *head, *pnode; //Node类型节点,存放顶点数据int count1 = 0; //记录多边形顶点个数int a[1]; //存放count1//先介绍画图操作void introduce() { cout << "按下L键,开始画直线" << endl; cout << "按下R键,开始画矩形" << endl; cout << "按下C键,开始画圆" << endl; cout << "按下E键,开始画椭圆" << endl; cout << "按下P键,开始画多边形(按下左键确定顶点,之后右键完成多边形)" << endl; cout << "右键清除" << endl;}//随机获得一个颜色画图void getColor() { r_rnd = (int)(rand()) % 256; b_rnd = (int)(rand()) % 256; g_rnd = (int)(rand()) % 256;}//画线函数void drawLine() { cvLine(img, point_start, point_end, CV_RGB(r_rnd, g_rnd, b_rnd),2);}//画矩形函数void drawRectangle() { cvRectangle(img, point_start, point_end, CV_RGB(r_rnd, g_rnd, b_rnd),2);}//画圆函数void drawCircle() { int x, y, r; //避免出现负数 if (point_start.x < point_end.x) x = point_end.x - point_start.x; else x = point_start.x - point_end.x; if (point_start.y < point_end.y) y = point_end.y - point_start.y; else y = point_start.y - point_end.y; r = (int)sqrt(x*x + y*y); //半径 cvCircle(img, cvPoint(point_start.x / 2 + point_end.x / 2, point_start.y / 2 + point_end.y / 2), r, CV_RGB(r_rnd, g_rnd, b_rnd),2);}//画椭圆函数void drawEllipse() { int x, y; if (point_start.x < point_end.x) x = point_end.x - point_start.x; else x = point_start.x - point_end.x; if (point_start.y < point_end.y) y = point_end.y - point_start.y; else y = point_start.y - point_end.y; cvEllipse(img, cvPoint(point_start.x / 2 + point_end.x / 2, point_start.y / 2 + point_end.y / 2), cvSize(x / 2, y / 2), 0, 0, 360, CV_RGB(r_rnd, g_rnd, b_rnd),2);}//画多边形函数void drawPolygon() { int i; //取出链表中的数据,放入ps中 pnode = head; ps[0] = (CvPoint*)malloc(sizeof(CvPoint) * count1); for (i = 0; pnode != NULL; i++, pnode = pnode->next) { ps[0][i] = cvPoint(pnode->p.x, pnode->p.y); } ps[0][i] = cvPoint(head->p.x, head->p.y); cvPolyLine(img, ps, a, 1, 1, CV_RGB(r_rnd, g_rnd, b_rnd),2);}//判断当前为何种操作void draw() { if (flag == 'l' || flag == 'L') drawLine(); else if (flag == 'c' || flag == 'C') drawCircle(); else if (flag == 'r' || flag == 'R') drawRectangle(); else if (flag == 'e' || flag == 'E') drawEllipse(); else if (flag == 'p' || flag == 'P') drawPolygon();}//鼠标响应函数void on_my_mouse(int event, int x, int y, int flags, void* userdata) { //因为多边形操作不同,单独提出 if (flag == 'p' || flag == 'P') switch (event) { //每当按下左键,记录下当前坐标,若是起始点,将head复制为pnode,同时计数点值0 case CV_EVENT_LBUTTONDOWN: cvCopy(img_copy, img); if (flagstart) { head = new Node; pnode = new Node; count1 = 0; head = pnode; getColor(); point_start = cvPoint(x,y); pnode->p.x = x; pnode->p.y = y; pnode->next = new Node; pnode = pnode->next; count1++; } flagmove = 1; flagstart = 0; break; case CV_EVENT_MOUSEMOVE: if (flagmove) { cvCopy(img_copy,img); point_end = cvPoint(x, y); cvLine(img, point_start, point_end, CV_RGB(r_rnd, g_rnd, b_rnd), 2); cvShowImage("test", img); } break; case CV_EVENT_LBUTTONUP: cvCopy( img,img_copy); point_start = cvPoint(x, y); flagmove = 0; pnode->p.x = x; pnode->p.y = y; pnode->next = new Node; pnode = pnode->next; count1++; break; //按下右键,画出多边形,以及清除功能 case CV_EVENT_RBUTTONDOWN: if (pnode == NULL) { cvZero(img); cvCopy(img, img_copy); } else { pnode->next = NULL; a[0] = count1; draw(); cvCopy(img, img_copy); flagstart = 1; } break; } //其余的操作响应 else switch (event) { //按下左键,记录点坐标到起始点point_start中,并将flagmove值1,代表鼠标移动有响应 case CV_EVENT_LBUTTONDOWN: cvCopy(img_copy, img); point_start = cvPoint(x, y); getColor(); flagmove = 1; break; //flagmove为1时,将鼠标坐标值入结束点point_end中,动态展现当前作图情况 case CV_EVENT_MOUSEMOVE: if (flagmove) { cvCopy(img_copy, img); point_end = cvPoint(x, y); draw(); cvShowImage("test", img); }break; //抬起左键,flagmove值0,鼠标移动相应结束 case CV_EVENT_LBUTTONUP: cvCopy(img, img_copy); flagmove = 0; break; //点击右键,图片清除 case CV_EVENT_RBUTTONDOWN: cvZero(img); cvZero(img_copy); break; }}int main(void) { //初始化造作 char c; cvNamedWindow("test"); cvZero(img); cvZero(img_copy); introduce(); setMouseCallback("test", on_my_mouse); while (1) { cvShowImage("test", img); c = cvWaitKey(30); //判断选择的操作情况 if (c == 'P' || c == 'p' || c == 'C' || c == 'c' || c == 'e' || c == 'E' || c == 'l' || c == 'L' || c == 'R' || c == 'r') flag = c; if ((int)(c) == 27) break; } return 0;}
画线:
画矩形:
画圆:
画椭圆:
画多边形:
大杂烩:
阅读全文
0 0
- 《学习OpenCV》第四章第5题
- 《学习OpenCV》第四章第6题
- 《学习OpenCV》练习题第四章第四题
- 学习OpenCV第四章第四题答案
- 《学习opencv》第四章第四题
- 《学习OpenCV》第四章课后题5-a
- 学习opencv ,第六章第四题
- 学习opencv第四章第三题
- 《学习OpenCV》练习题第二章第四题
- 《学习OpenCV》练习题第三章第四题
- 《学习OpenCV》练习题第四章第二题
- 《学习OpenCV》练习题第四章第六题
- 《学习OpenCV》练习题第三章第四题
- 学习OpenCV第四章第一题答案
- 学习OpenCV第四章第二题答案
- 学习OpenCV第四章第五题答案
- 《学习OpenCV》第四章课后题2
- 《学习OpenCV》第四章课后题4
- CRC校验
- 数据库优化——使用索引
- MATLAB数据矩阵单位化,归一化,标准化
- http服务器---nginx
- SVN
- 《学习OpenCV》第四章第5题
- Python学习二——变量和简单数据类型
- 基于四元数的姿态解算算法图解
- Spring源码分析
- Ubuntu下对文件的操作命令符
- 面试题 37: 两个链表的第一个公共结点
- Hdu 1711 Number Sequence ( KMP 模板题)
- 操作系统基础
- 求文件夹中最大文件