OpenCV3实现橡皮擦功能[画板]

#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
Rect box;
bool drawing_box = false;
Rect Eraser;
bool drawing_eraser = false;
int Eraser_Size = 5;

/*
 *  opencv实现橡皮擦功能总结:在鼠标事件中用背景色覆盖矩形的颜色
 *  参考://https://blog.csdn.net/zhoufan900428/article/details/45890053
*/
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(0x00,0xff,0x00)    //绿色
                );

}

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(0x00,0x00,0x00),  //用背景色白色填充
                CV_FILLED
                );
}
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("Paint");

    setMouseCallback("Paint",
                          mouse_paint_callback,
                          (void*)&srcImage);
    while(1){
        srcImage.copyTo(tempImage);
        if(drawing_box) draw_box(tempImage,box);
        if(drawing_eraser) show_Eraser(tempImage,Eraser);
        imshow("Paint",tempImage);

        if(cvWaitKey(15) == 27) break;    //wait ESC key

    }

    return 0;
}

void mouse_paint_callback(int event,
                          int x,
                          int y,
                          int flags,
                          void* param)
{
    Mat& image = *(cv::Mat*)param;
    switch(event)
    {
        case CV_EVENT_MOUSEMOVE: //鼠标移动
        {
            if(drawing_box)
            {
               cout<< (flags & CV_EVENT_FLAG_SHIFTKEY) << ends << CV_EVENT_FLAG_SHIFTKEY << "\n";
              if((flags & CV_EVENT_FLAG_SHIFTKEY) == CV_EVENT_FLAG_SHIFTKEY)
              {  //SHIFT键被压下
                   if (box.x>box.y)
                   {
                      box.width = x - box.x;
                      box.height= (y - box.y > 0)?abs(x - box.x):-abs(x - box.x);
                   }
                   else
                   {
                      box.width = (x - box.x > 0)?abs(y - box.y):-abs(y - box.y);
                      box.height= y - box.y;
                   }
            }
            else
            {
                box.width = x - box.x;
                box.height= y - box.y;
            }
        }

            if(drawing_eraser)
            {
                Eraser = cvRect(x,y,0,0);
                draw_Eraser(image,Eraser);  //用黑色方块表示一个橡皮擦
            }
        }
        break;

        case CV_EVENT_LBUTTONDOWN: //左键压下
        {
            drawing_box = true;
            box = Rect(x,y,0,0);
        }
        break;

        case CV_EVENT_RBUTTONDOWN: //右键压下
        {
            drawing_eraser = true;
            Eraser = Rect(x,y,0,0);
            draw_Eraser(image,Eraser);
        }
        break;

        case CV_EVENT_LBUTTONUP: //左键弹起
        {
            drawing_box = false;
            if(box.width<0)
            {
                box.x += box.width;
                box.width *= -1;
            }
            if(box.height<0)
            {
                box.y += box.height;
                box.height *= -1;
            }
            draw_box(image,box);
        }
        break;
        case CV_EVENT_RBUTTONUP: //右键弹起
        {
            drawing_eraser = false;
        }
        break;
    }
}

 

转载于:https://my.oschina.net/u/3919756/blog/1941312

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值