设为首页 加入收藏

TOP

Opencv实现的简易绘图工具(一)
2017-10-11 15:46:55 】 浏览:4814
Tags:Opencv 实现 简易 绘图 工具

第一次写博,还是个菜鸟。最近开始学习Opencv,试着写了个简易的绘图工具(目前只写了画线和橡皮擦部分,画其它图形还有待往里添加),也算是记录自己的学习之路。

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

#define SHAPE_LINE 1
#define SHAPE_ERASER 2

int g_style;
CvRect rect;

CvPoint g_StartPoint;   
CvPoint g_EndPoint;
CvPoint p_Start;       //记录鼠标位置左上方点
CvPoint p_End;			//记录鼠标位置右下方点
bool drawing=false;       //是否处于画图状态
bool erasering=false;    //是否处于擦除状态

void callback(int event,int x,int y,int flags,void* param);
void DrawLine(IplImage* img);
//简易绘图工具,实现了画线和橡皮擦功能,绘图功能还有待往里添加
int main(int argc,char** argv)
{
	IplImage* img=cvCreateImage(cvSize(512,512),IPL_DEPTH_8U,3);
	cvSet(img,cvScalar(255,255,255));

	IplImage* temp=cvCloneImage(img);
	cvCopy(img,temp);

	cvNamedWindow("简易绘图工具");

	cvSetMouseCallback("简易绘图工具",callback,img);
	printf("请键入要选择执行的操作:‘l’——”画线“,‘e’——”橡皮“\n");
	char select='l';

	while(1)
	{
		cvCopyImage(img,temp);      //始终在原图image上画结果(和鼠标事件绑定),先将image复制给temp,然后在临时图temp画出画图的过程(在main函数中画过程图形),然后用temp来显示图像
		switch(select)
		{
		case 'l':
			g_style=SHAPE_LINE;
			break;
		case 'e':
			g_style=SHAPE_ERASER;
			break;
		case 27:
			return 0;
		}
		if(g_style==SHAPE_LINE&&drawing)     //画鼠标在按住移动过程中画线
			cvDrawLine(temp,g_StartPoint,g_EndPoint,cvScalar(0,0,0));
		if(g_style==SHAPE_ERASER)   
		{
			cvRectangle(temp,p_Start,p_End,cvScalar(0,0,0));  //画出橡皮矩形边框
		}
		cvShowImage("简易绘图工具",temp);
		select=cvWaitKey(30);
	}
	cvReleaseImage(&img);
	cvReleaseImage(&temp);
	cvDestroyWindow("简易绘图工具");
	return 0;
}

void callback(int event,int x,int y,int flags,void* param)
{
	IplImage* img=(IplImage*)param;

	switch(event)
	{
	case CV_EVENT_LBUTTONDOWN:
		{
			if(SHAPE_LINE==g_style)   
			{
				drawing=true;
				g_StartPoint=cvPoint(x,y);
				g_EndPoint=g_StartPoint;   //此处将终点坐标设为同起始点避免记住前一条直线的终点坐标
			}
			if(SHAPE_ERASER==g_style)
			{
				erasering=true;
				//注意边界问题要适当修改ROI有效区域
				rect.x=x-20;  rect.y=y-20;		//注意坐标的计算,一般原点在窗口的左上角(这和操作系统等因素有关,IplImage结构中有个origin属性可以设置图像的原点)
				rect.width=40;  rect.height=40;
				p_Start.x=x-20; p_Start.y=y-20;
				p_End.x=x+20;   p_End.y=y+20;
				if(x>-20&&x<532&&y>-20&&y<532)
				{
					cvSetImageROI(img,rect);
					cvSet(img,cvScalar(255,255,255));
					cvResetImageROI(img);
				}
			}
		}
		break;
	case CV_EVENT_MOUSEMOVE:
		{
			p_Start.x=x-20; p_Start.y=y-20;      //随时定位鼠标位置画橡皮矩形
			p_End.x=x+20;   p_End.y=y+20;
			if(SHAPE_LINE==g_style)
			{
				if(drawing)
				{
					g_EndPoint=cvPoint(x,y);
				}
			}

			if(SHAPE_ERASER==g_style)
			{
				rect.x=x-20;  rect.y=y-20;    
				rect.width=40;  rect.height=40;
				if(erasering)
				{
					if(x>-20&&x<532&&y>-20&&y<532)
					{
						cvSetImageROI(img,rect);
						cvSet(img,cvScalar(255,255,255));
						cvResetImageROI(img);
					}
				}
			}

		}
		break;
	case CV_EVENT_LBUTTONUP:
		{
			if(SHAPE_LINE==g_style)
			{
				drawing=false;
	
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇[转载]为什么使用%lf读取double型.. 下一篇C中级 数据序列化简单使用和讨论 ..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目