OpenCV简单画板功能实现

2022-06-16 14:23:53 浏览数 (2)

画板功能主要包括:

  1. 右键切换橡皮擦
  2. 左键画圆,椭圆,矩形,直线
  3. 键盘输入进行图形的切换
  4. 其他功能自己可以自行添加

具体实现显示如下:

代码贴出:

代码语言:javascript复制
#include <iostream>
#include <opencv2/opencv.hpp>
#include <cmath>

using namespace std;
using namespace cv;
Rect box;
bool drawing_box = false;
Rect Eraser;
bool drawing_eraser = false;
int Eraser_Size = 5;

bool drawing_circle= false;

bool drawing_line =false;
bool drawing_ellipse=false;

//形状切换
bool mode_r = true;
bool mode_l = true;
bool mode_c = true;
bool mode_e = true;

void mouse_paint_callback(int event,
                          int x,
                          int y,
                          int flags,
                          void* param
                          );
//画矩形
void draw_box( Mat img, CvRect box)
{
    rectangle(img,
                Point(box.x,box.y),
                Point(box.x box.width,box.y box.height),
                Scalar(0,255,0) ,
                3   
                );

}

//画圆
void draw_circle( Mat img, CvRect box)
{
    circle(img,
                Point(box.x,box.y),
                sqrt(box.width*box.width box.height*box.height),
                Scalar(0,0,255)    
                );

}

//画直线
void draw_line(Mat img,CvRect box)
{
    line(img,Point(box.x,box.y),Point((box.x box.width),(box.y box.height)),cv::Scalar(255,0,0),3 );
}

//椭圆
void draw_ellipse(Mat img,CvRect box)
{
   cv::Point center(box.x,box.y); 
    cv::Size axes(20, 10);
    cv::ellipse(img, center, axes,0, 0, 360.0, cv::Scalar(20,0,100), 2);
}


void draw_Eraser( Mat img, CvRect Eraser)
{
    rectangle(img,
                Point(Eraser.x - Eraser_Size,Eraser.y - Eraser_Size),
                Point(Eraser.x   Eraser_Size,Eraser.y   Eraser_Size),
                Scalar(0xff,0xff,0xff),  
                CV_FILLED   
                );
}

void show_Eraser( Mat img, CvRect Eraser)
{
    rectangle(img,
                Point(Eraser.x - Eraser_Size,Eraser.y - Eraser_Size),
                Point(Eraser.x   Eraser_Size,Eraser.y   Eraser_Size),
                Scalar(255,255,255),  
                CV_FILLED
                );
}

void draw_draw(int x,int y,int flags)
{
    if((flags & CV_EVENT_FLAG_SHIFTKEY) == CV_EVENT_FLAG_SHIFTKEY)
         {  
             if (box.x>box.y)
                {
                      box.width = x - box.x;
                      box.height= (y - box.y > 0)?abs(y - box.y):-abs(y - box.y);
                 }
             else
                 {
                      box.width = (x - box.x > 0)?abs(x - box.x):-abs(x - box.x);
                      box.height= y - box.y;
                 }
        }
     else
        {
                box.width = x - box.x;
                box.height= y - box.y;   
       }
}

int main()
{
    box = Rect(-1, -1, 0, 0);
    Eraser = Rect(-1, -1, 0, 0);
    Mat srcImage(600, 800, CV_8UC3);
    srcImage.setTo(Scalar(255,255,255));  //设置背景色颜色为白色
    Mat tempImage;
    srcImage.copyTo(tempImage);

    namedWindow("drawing");
    
    setMouseCallback("drawing",mouse_paint_callback,(void*)&srcImage);

    while(1)
    {
        srcImage.copyTo(tempImage);
        if(drawing_circle) draw_circle(tempImage,box);
        if(drawing_box) draw_box(tempImage,box);
        if(drawing_line) draw_box(tempImage,box);
        if(drawing_ellipse) draw_box(tempImage,box);
        if(drawing_eraser) show_Eraser(tempImage,Eraser);

        imshow("drawing",tempImage);
        if (cvWaitKey(1)=='c') mode_r=false, mode_l=false,mode_e=false,mode_c=true;
        if (cvWaitKey(1)=='r') mode_r=true, mode_l=false,mode_e=false,mode_c=false;
        if (cvWaitKey(1)=='l') mode_r=false, mode_l=true,mode_e=false,mode_c=false;
        if (cvWaitKey(1)=='e') mode_r=false, mode_l=false,mode_e=true,mode_c=false;
        if(cvWaitKey(15) == 27) break;  

    }

    return 0;
}

void mouse_paint_callback(int event,
                          int x,
                          int y,
                          int flags,
                          void* param
                          )
{
     
    Mat& image = *(cv::Mat*)param;
   
       if ( event==CV_EVENT_MOUSEMOVE)
        {
         
            if(drawing_box)
            {
               draw_draw(x,y,flags);
            }
            
            if(drawing_circle)
            {
              draw_draw(x,y,flags);
            }
    
            if(drawing_line)
            {
              
             draw_draw(x,y,flags);
            }
            
            if(drawing_ellipse)
            {
              
             draw_draw(x,y,flags);
            }
            
            if(drawing_eraser)
            {
                Eraser = cvRect(x,y,0,0);
                Eraser = cvRect(x,y,0,0);
                draw_Eraser(image,Eraser);  //用黑色方块表示一个橡皮擦
            }
        
        }

       else if(  event==CV_EVENT_LBUTTONDOWN) //左键压下
        {
            if (mode_r == true)
            {   
                drawing_box = true;
                box = Rect(x,y,0,0);
            }
               
             if (mode_c == true)
            {
                drawing_circle = true;
                box = Rect(x,y,0,0);
            }

              if (mode_l == true)
            {
                drawing_line = true;
                box = Rect(x,y,0,0);
            }

              if (mode_e == true)
            {
                drawing_ellipse = true;
                box = Rect(x,y,0,0);
            } 
            
            
        }
        

        else if ( event==CV_EVENT_RBUTTONDOWN) //右键压下
        {
            drawing_eraser = true;
            Eraser = Rect(x,y,0,0);
            draw_Eraser(image,Eraser);
           
        }
       

        else if ( event==CV_EVENT_LBUTTONUP) //左键弹起
        {
             drawing_box = false;
             drawing_circle = false;
             drawing_line = false;
             drawing_ellipse = false;

            if(box.width<0)
            {
                box.x  = box.width;
                box.width *= -1;
            }
            if(box.height<0)
            {
                box.y  = box.height;
                box.height *= -1;
            }
            if (mode_r == true )
                draw_box(image,box);
            if (mode_c ==true )
                draw_circle(image,box);
             if (mode_l == true )
                draw_line(image,box);
            if (mode_e ==true )
                draw_ellipse(image,box);

        }
        

       else if (  event==CV_EVENT_RBUTTONUP)//右键弹起
        {
            drawing_eraser = false;
          
        }
       

}

博主:菜鸟程序员

初衷:学习资料,程序设计,图像处理,视觉算法,求职经验,工作心得

0 人点赞