【opencv学习之十八】基本绘图工具line circle rectangle ellipse等

本文介绍使用OpenCV进行基本绘图操作的方法,包括直线、圆形、矩形等,并展示了如何利用OpenCV实现鼠标点击绘制图形的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这里介绍opencv基本绘图工具,包括直线line(),圆形circle(),矩形recangle(),椭圆ellipse(),多边形fillPoly(),添加文字putText()等,然后后面还有opencv鼠标操作的一些方法,详见示例代码:

1.基本绘图工具:

void  drawTool()//1.基本绘图工具
{
    Mat img(600, 600, CV_8UC3, Scalar(0, 0, 0));
    //画线
    line(img, Point(10, 10), Point(10, 200), Scalar(0, 255, 255),//黄色
         10,//线宽
         8);  //线型
    //画圆
    circle(img, Point(120, 200), 100, Scalar(255, 255, 0),//青色
           -1, //线宽为-1,向内填充
           8);
    //画矩形
    rectangle(  img, Point(400, 100), //左上点
                Point(240, 200),//右下点
                Scalar(0, 0, 255), 2, 8
                );
    rectangle(   img,
                Rect(150, 500,//左上坐标
                     100, 150),//宽高
                Scalar(0, 0, 255), -1, 8); //线宽为-1,向内填充
    //画椭圆
    ellipse(img, Point(500, 300), Size(100, 50), //size类型,长轴和短轴
            45,//旋转角度
            0,//起始角度
            360, Scalar(0, 255, 255), -1, 8);
    ellipse(img, RotatedRect(Point(400, 150),//旋转矩形的中心坐标
                             Size(100, 50),//旋转矩形的大小
                             0), //旋转矩形的角度
            Scalar(0,255,0), 2, 8);//颜色线宽
    //画多边形
    //定义Point类型数组,按顺序存放六边形的点,其实就多条line连接
    Point ppt[] = {Point(120, 50), Point(180, 50), Point(210, 100), Point(180, 150), Point(120, 150), Point(90, 100)};
    const Point* pts[] = {ppt};//ppt类型为Point*,pts类型为Point**,需定义成const类型
    int npt[] ={6};  //npt的类型即为int*
    //填充多边形
    fillPoly(img, pts, npt, 1,//绘制多边形的个数,1个
             Scalar(0, 255, 255), 8); //画填充多边形
    //非填充多边形
    polylines(img, pts, npt, 1, true, //是否闭合,改为false则不闭合
              Scalar(0, 154, 209), 2, //它不能改为-1来进行填充
              8);
    //添加文字
    putText(img,  "opencv", Point(10, 400),//起始点
            CV_FONT_HERSHEY_COMPLEX, //字体
            2, //字体大小
            Scalar(0, 255, 255), 2, 8);
    imshow("img", img); //显示图片
    waitKey(0);
}
效果如下:


2.鼠标点击绘制圆形(下面两个函数要加载到main前声明):

////////////2鼠标点击基本绘图工具
void OnMouse(int event, int x, int y, int flags, void* param) //10.鼠标绘图
{
    Mat img = *(Mat*)param;
    if(event == CV_EVENT_LBUTTONDOWN)
        {
        cout<<"Mouse down"<<endl;
        circle(img, Point(x, y), 20, Scalar(0, 255, 0), 2, 8);
    }
}
void  drawTool2()//.基本绘图工具
{
    Mat img(500, 500, CV_8UC3, Scalar(255, 255, 255));
    namedWindow("Mouse", CV_WINDOW_AUTOSIZE);
    setMouseCallback("Mouse", OnMouse, &img);
    while(1) //为了不断循环地imshow(),使图像刷新.
    {
        imshow("Mouse", img);
        if(27==waitKey(10))  //按下Esc跳出
            break;  }
}
效果如下:

3.鼠标绘制矩形,下面这个代码绘制时候鼠标起点和末尾点结束后才会显示所画矩形:

void  drawTool3()//3.基本绘图工具-矩形
{
    Mat img(500, 500, CV_8UC3, Scalar(255, 255, 255));
    namedWindow("Mouse", CV_WINDOW_AUTOSIZE);
    setMouseCallback("Mouse", OnMouse2, &img);
    while(1) //为了不断imshow(),使图像刷新
    {
        imshow("Mouse", img);
        if(27==waitKey(10))  //按下Esc跳出
            break; }
}
void OnMouse2(int event, int x, int y, int flags, void* param)  //11.鼠标事件
{
    Mat img = *(Mat*)param;
    switch(event)
    { case CV_EVENT_LBUTTONDOWN:
        pt.x = x;
        pt.y = y;
        break;
    case CV_EVENT_LBUTTONUP:
        rectangle(img, pt, Point(x, y), Scalar(0, 0, 255), 2, 8);
        break;
    default:
        break;}
}
效果如下:



4.绘制矩形,改进上面的代码,使得鼠标绘制时一直可以看到矩形大小,效果同上:

void  drawTool4()//4.基本绘图工具,双缓冲绘画
{
    Mat img5(500, 500, CV_8UC3, Scalar(255, 255, 255));
    img4=img5.clone();
    namedWindow("Mouse", CV_WINDOW_AUTOSIZE);
    setMouseCallback("Mouse", OnMouse4, &img4);
    while(1) //为了不断imshow(),使图像刷新
    {
        imshow("Mouse", img4);
        if(27==waitKey(10))  //按下Esc跳出
            break;}
}
void OnMouse4(int event, int x, int y, int flags, void* param)  //11.鼠标事件
{
//    Mat img4 = *(Mat*)param;
    switch(event)
    {
    case CV_EVENT_LBUTTONDOWN:
        flag = true;//flag标记置为真,触发鼠标移动画矩形
        pt4.x = x;
        pt4.y = y;
        break;
    case CV_EVENT_MOUSEMOVE:   //鼠标移动
        //cout<<"mouse move"<<endl;
        if(flag)
        {
            temp4=img4.clone();
            rectangle(temp4, pt4, Point(x, y), Scalar(0, 0,255), 2, 8);//画矩形
            imshow("Mouse", temp4);
        }
        break;
    case CV_EVENT_LBUTTONUP:
        rectangle(img4, pt4, Point(x, y), Scalar(0, 0, 255), 2, 8);
        imshow("Mouse", img4);
        flag = false;//flag标记置为假,关闭鼠标移动画矩形
        break;
    default:
        break;
    }
}


5.用鼠标绘制矩形选择感兴趣的ROI区域:

Mat img_mouse = imread("D:/2.jpg",CV_LOAD_IMAGE_COLOR);
Mat temp = img_mouse.clone(); //Mat类型变量temp深拷贝原图
Mat ROI;//设置感兴趣区域ROI
Point pt2;//记录鼠标左键按下时的坐标
bool flag = false;////flag用来标记鼠标移动是否画矩形
//上面的全局变量要提前加载
void drawROI()//鼠标选ROI
{
    namedWindow("Mouse", CV_WINDOW_AUTOSIZE);
    setMouseCallback("Mouse", OnMouse3, 0);   //设置鼠标回调函数
    while(1)
    {
        imshow("Mouse", img_mouse); //每10ms刷新一次图像,不在onMouse()里显示图像,因为太快会有拖动重影
        if(27 == waitKey(10))  //Esc跳出循环
            break;
    }
}

void OnMouse3(int event, int x, int y, int flags, void* param)
{
    switch(event)
    {
        case CV_EVENT_LBUTTONDOWN:  //鼠标左键按下
            //cout<<"left button down"<<endl;
            flag = true;//flag标记置为真,触发鼠标移动画矩形
            pt2.x = x; //记录当前点坐标
            pt2.y = y;
            break;
        case CV_EVENT_MOUSEMOVE:   //鼠标移动
            //cout<<"mouse move"<<endl;
            if(flag)
            {
                temp.copyTo(img_mouse);//通过temp将img更新为原图
                rectangle(img_mouse, pt2, Point(x, y), Scalar(0, 255, 0), 2, 8);//画矩形
            }
            break;
        case CV_EVENT_LBUTTONUP:   //鼠标左键弹起
            //cout<<"left button up"<<endl;
            flag = false;//flag标记置为假,关闭鼠标移动画矩形
            ROI = temp(Rect(pt2.x, pt2.y, x-pt2.x, y-pt2.y));  //确定ROI区域
            imshow("ROI", ROI); //显示ROI
            imwrite("ROI.bmp", ROI);//保存ROI
            break;
        default:
            break;
    }
}


效果如下:





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值