学习OpenCV课后题4.5(有点糙)

#include <cv.h>
#include <cvcam.h>
#include <cxcore.h>
#include <highgui.h>
#include <stdio.h>

#pragma comment(lib,"cv.lib")
#pragma comment(lib,"cvcam.lib")
#pragma comment(lib,"cxcore.lib")
#pragma comment(lib,"highgui.lib")

#define SHAPE_NONE 0
#define SHAPE_LINE 1
#define SHAPE_RECT 2
#define SHAPE_CIRCLE 3
#define SHAPE_ESLIPSE 4
#define SHAPE_PLYGON 5
#define SHAPE_ERASER 6

//用来记录在全局范围内用户要画的图像类型
int g_ShapeStyle;

//画直线所需要的两个点
CvPoint g_StartPoint;
CvPoint g_EndPoint;

//画矩形椭圆所需要的CRect类型变量
CvRect g_rect;

 

//确定当前程序是否处于画图状态
bool g_IsDraw=false;

//用来将图像还原
void ResetImage(IplImage *src_image,IplImage *dst_image);

//在图像上画直线
void DrawLine(IplImage *image,CvPoint startpoint,CvPoint endpoint);

//在图像上画矩形
void DrawRect(IplImage *image,CvRect rect);

//在图像上画一个简易的椭圆
void DrawEllipse(IplImage *image,CvRect rect);

//在图像上画一个圆形
void DrawCircle(IplImage *image,CvRect rect);

//类型橡皮擦的功能
void EraseImage(IplImage *image,CvPoint startpoint,CvPoint endpoint);


//鼠标事件的回调函数
void my_callback(int event, int x, int y, int flags, void* param);


       

void main()
{
 printf("…………………………………………(N)创建一个图像/n/n");
 printf("…………………………………………(L)画线/n/n");
 printf("…………………………………………(S)画方/n/n");
 printf("…………………………………………(C)画圆/n/n");
 printf("…………………………………………(E)画椭圆/n/n");
 printf("…………………………………………(P)画多边形/n/n");
 printf("…………………………………………(R)橡皮擦/n/n");
 
 //载入图像
 IplImage *image=cvCreateImage(cvSize(500,500),IPL_DEPTH_8U,3);
 assert(image!=NULL);

 //临时图像
 IplImage *temp_image=cvCloneImage(image);

 //创建窗口
 cvNamedWindow("Show");
 cvShowImage("Show",image);

 //创建窗口回调函数
 cvSetMouseCallback("Show",my_callback,temp_image);

 //用来记录用户所输入的字符型变量
 char select='n';

 while (1)
 {
  switch (select)
  {
  case 'n':
   //新建图像
   g_ShapeStyle=SHAPE_LINE;
   ResetImage(image,temp_image);
   printf("新建图像/n/n");
   break;
   //画直线
  case 'l':
   g_ShapeStyle=SHAPE_LINE;
   break;
   // 画方形
  case 's':
   g_ShapeStyle=SHAPE_RECT;
   break;
   //画椭圆
  case 'e':
   g_ShapeStyle=SHAPE_ESLIPSE;
   break;
   //画圆
  case 'c':
   g_ShapeStyle=SHAPE_CIRCLE;
   break;
  case 'r':
   g_ShapeStyle=SHAPE_ERASER;
   break;
   //画多边形
  case 'p':
   g_ShapeStyle=SHAPE_PLYGON ;
   break;
  case 27:
   return ;
  }
  cvShowImage("Show",temp_image);
  select=cvWaitKey(30);

 }
}

 


//Show窗口的回调函数

void my_callback(int event, int x, int y, int flags, void* param)
{
 IplImage *image=(IplImage*)(param);
 
 switch (event)
 {
 //当鼠标左键被按下
 case CV_EVENT_LBUTTONDOWN:
  {
   //如果是画线
   if (SHAPE_LINE==g_ShapeStyle || SHAPE_ERASER==g_ShapeStyle)
   {
    g_IsDraw=true;
    g_StartPoint.x=x;
    g_StartPoint.y=y;
   }
   //如果是画矩形|椭圆|圆
   if (SHAPE_RECT==g_ShapeStyle ||SHAPE_ESLIPSE==g_ShapeStyle ||SHAPE_CIRCLE==g_ShapeStyle)
   {
    g_IsDraw=true;
    g_rect.x=x;
    g_rect.y=y;
    g_rect.width=0;
    g_rect.height=0;
   }

  }
 break;
 //当鼠标左键在移动过程中
 case CV_EVENT_MOUSEMOVE:
  {
   //如果是画线
   if (SHAPE_LINE==g_ShapeStyle||SHAPE_ERASER==g_ShapeStyle)
   {
    if (true==g_IsDraw)
    {
     g_EndPoint.x=x;
     g_EndPoint.y=y;
    }
    
   }
   //如果是画矩形|椭圆|圆

   if (SHAPE_RECT==g_ShapeStyle ||SHAPE_ESLIPSE==g_ShapeStyle ||SHAPE_CIRCLE==g_ShapeStyle)
   {
    if (true==g_IsDraw)
    {
     g_rect.width=x-g_rect.x;
     g_rect.height=y-g_rect.y;
    }
   }
 break;
  }

 //当鼠标左键被释放后
 case CV_EVENT_LBUTTONUP:
  {
   //如果是画线
   if (SHAPE_LINE==g_ShapeStyle)
   {
    g_IsDraw=false;
    DrawLine(image,g_StartPoint,g_EndPoint);
   }

   //如果是画矩形
   if (SHAPE_RECT==g_ShapeStyle)
   {
    g_IsDraw=false;
    if (g_rect.width<0)
    {
     g_rect.x+=g_rect.width;
     g_rect.width*=-1;
    }
    if (g_rect.height<0)
    {
     g_rect.y+=g_rect.height;
     g_rect.height*=-1;
    }

    DrawRect(image,g_rect);
   }

   //如果是画椭圆形

   if (SHAPE_ESLIPSE==g_ShapeStyle)
   {
    g_IsDraw=false;
    if (g_rect.width<0)
    {
     g_rect.x+=g_rect.width;
     g_rect.width*=-1;
    }
    if (g_rect.height<0)
    {
     g_rect.y+=g_rect.height;
     g_rect.height*=-1;
    }
    
    DrawEllipse(image,g_rect);
   }
   
   //如果是画圆
   if (SHAPE_CIRCLE==g_ShapeStyle)
   {
    g_IsDraw=false;
    if (g_rect.width<0)
    {
     g_rect.x+=g_rect.width;
     g_rect.width*=-1;
    }
    if (g_rect.height<0)
    {
     g_rect.y+=g_rect.height;
     g_rect.height*=-1;
    }
    
    DrawCircle(image,g_rect);
   }

   //如果是橡皮擦
   if (SHAPE_ERASER==g_ShapeStyle)
   {
    
    g_IsDraw=false;
    EraseImage(image,g_StartPoint,g_EndPoint);
   }

  }
 break;
 }
 }

 


//还原图像
void ResetImage(IplImage *src_image,IplImage *dst_image)        
{
 cvCopyImage(src_image,dst_image);
}

//在图像上画直线
void DrawLine(IplImage *image,CvPoint startpoint,CvPoint endpoint)
{
 assert(image!=NULL);
 
 cvDrawLine(
  image,
  startpoint,
  endpoint,
  CV_RGB(255,0,0),
  1
  );
}

//在图像上画方
void DrawRect(IplImage *image,CvRect rect)
{
 assert(image!=NULL);

 cvRectangle(
   image,
   cvPoint(rect.x,rect.y),
   cvPoint(rect.x+rect.width,rect.y+rect.height),
   CV_RGB(255,0,0),
   1
   );

}

//在图像上画椭圆
void DrawEllipse(IplImage *image,CvRect rect)

 assert(image!=NULL);

 //获得所属矩形大小
 CvSize size=cvSize(rect.width/2,rect.height/2);

 //获得矩形的中心点
 CvPoint center=cvPoint((rect.x+rect.width)/2,(rect.y+rect.height)/2);

 //角度
 double angle=0;

 //起点夹角
 double start_angle=0;

 //终点夹角
 double end_angle=360;

 cvEllipse(image,center,size,angle,start_angle,end_angle,CV_RGB(255,0,0));

}

//在图像上画一个圆
void DrawCircle(IplImage *image,CvRect rect)
{
 assert(image!=NULL);
 
 if (rect.width!=rect.height)
 {
  rect.width=rect.height;
 }
 //圆的半径
 int radis=rect.height/2;

 CvPoint center=cvPoint((rect.x+rect.width)/2,(rect.y+rect.height)/2);

 cvCircle(image,center,radis,CV_RGB(255,0,0),1);
}


//用黑色画笔实现貌似橡皮擦的功能
void EraseImage(IplImage *image,CvPoint startpoint,CvPoint endpoint)
{
 assert(image!=NULL);
 
 cvDrawLine(
  image,
  startpoint,
  endpoint,
  CV_RGB(0,0,0),
  20
  );
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值