前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >OpenCV简单画板功能实现

OpenCV简单画板功能实现

作者头像
用户9831583
发布2022-06-16 14:23:53
3820
发布2022-06-16 14:23:53
举报
文章被收录于专栏:码出名企路

画板功能主要包括:

  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;
          
        }
       

}

博主:菜鸟程序员

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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-01-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码出名企路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
图像处理
图像处理基于腾讯云深度学习等人工智能技术,提供综合性的图像优化处理服务,包括图像质量评估、图像清晰度增强、图像智能裁剪等。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档