ROI多区域选择

摘要:
学习图像处理时,为了快速验证处理效果,经常需要手动选取ROI区域。//鼠标交互相应voidpolygonCallback{//获取窗口显示图像Matimg=*userdata;Matdst;img.copyTo;//获取坐标Pointpos(x,y);switch{//鼠标左键点击确认角点caseCV_EVENT_LBUTTONDOWN:{mousePoints.push_back;//绘制点以反馈circle;size_tend=mousePoints.size();if{//将轮廓的最后两个点进行连线line;line;}break;}//鼠标滑动时可以进行预估caseCV_EVENT_MOUSEMOVE:{size_tend=mousePoints.size();if{//当前位置点和轮廓始末点的连线line;line;}}}//展示dst,而img不含预估线imshow;}掩码获取这个步骤主要是用一个二维的vector存储多个历史轮廓,然后使用OpenCV函数drawContours绘制掩码区域:voidcv::drawContours具体函数如下://ROI多边形区域选择voidselectPolygon{if{std::cerr˂˂"srcMatisempty!

学习图像处理时,为了快速验证处理效果,经常需要手动选取ROI区域。其中,多边形区域是最具普适性的,而有时候我们可能还有一次性提取多个区域的需求。本文实现了该过程,先上效果图。

ROI多区域选择第1张

鼠标交互

鼠标交互使用OpenCV函数setMouseCallback:

void cv::setMouseCallback(const cv::String &winname, cv::MouseCallback onMouse, void *userdata = (void *)0)

主要实现的就是回调函数onMouse,以下是我实现的回调,用于监听鼠标滑动和左键点击事件。在左键点击后在图上绘制出该角点以及末两点的连线;在鼠标滑动时绘制当前位置点和轮廓始末点的两条连线,作为效果预估。

//鼠标交互相应
void polygonCallback(int EVENT, int x, int y, int flags, void*userdata)
{
    //获取窗口显示图像
    Mat img = *(Mat*) userdata;
    Mat dst;
    img.copyTo(dst);
    //获取坐标
Point pos(x,y);
    switch(EVENT)
    {
        //鼠标左键点击确认角点
        caseCV_EVENT_LBUTTONDOWN:
        {
            mousePoints.push_back(pos);
            //绘制点以反馈
            circle(img, pos, 4, Scalar(255, 0, 0), -1);
            size_t end =mousePoints.size();
            if (end > 1)
            {
                //将轮廓的最后两个点进行连线
                line(img, mousePoints[end - 2], mousePoints[end - 1], Scalar(255, 0, 0));
                line(dst, mousePoints[end - 2], mousePoints[end - 1], Scalar(255, 0, 0));
            }
            break;
        }
        //鼠标滑动时可以进行预估
        caseCV_EVENT_MOUSEMOVE:
        {
            size_t end =mousePoints.size();
            if (end > 1)
            {
                //当前位置点和轮廓始末点的连线
                line(dst, mousePoints[end - 1], pos, Scalar(255, 0, 0));
                line(dst, mousePoints[0], pos, Scalar(255, 0, 0));
            }
        }

    }
    //展示dst,而img不含预估线
imshow(windowName, dst);
}
掩码获取

这个步骤主要是用一个二维的vector存储多个历史轮廓,然后使用OpenCV函数drawContours绘制掩码区域:

void cv::drawContours(cv::InputOutputArray image, cv::InputArrayOfArrays contours, int contourIdx, const cv::Scalar &color, int thickness = 1, int lineType = 8, cv::InputArray hierarchy = noArray(), int maxLevel = 2147483647, cv::Point offset = cv::Point())

具体函数如下:

//ROI多边形区域选择
void selectPolygon(const Mat &srcMat, Mat &dstMat)
{
    if(srcMat.empty())
    {
        std::cerr << "srcMat is empty!" <<std::endl;
        return;
    }

    imshow(windowName, srcMat);
    Mat selectMat;
    charkey;
    srcMat.copyTo(selectMat);
    std::vector<std::vector<Point>>contours;
    do{
        //鼠标左键选择角点,任意非q按键新建选区,q按键退出ROI选择
        setMouseCallback(windowName, polygonCallback, &selectMat);
        key = waitKey(0);
        //判断是否能构成多边形,不能则忽略本次选择
        if (mousePoints.size() < 3)
        {
            std::cout << "points are too little!:" <<std::endl;
            mousePoints.clear();
        }
        else{
            //补出轮廓始末点连线
            line(selectMat, mousePoints[0], mousePoints[mousePoints.size() - 1], Scalar(255, 0, 0));
            //存储边界
contours.push_back(mousePoints);
            //清空本次轮廓点,准备接收下一个区域
mousePoints.clear();
        }
    }while (key != 'q');

    destroyAllWindows();

    //实心roi掩码
    //掩码图像
    Mat mask(srcMat.rows, srcMat.cols, CV_8UC1, Scalar(0));
    for (size_t i = 0; i < contours.size(); i++)
    {
        drawContours(mask, contours, i, Scalar(255), -1);
    }
    mask.copyTo(dstMat);
    mousePoints.clear();
}

免责声明:文章转载自《ROI多区域选择》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇【UE】常用的UltraEdit使用技巧android自定义圆角实线边框,圆角虚线边框,直实线,虚实线,半圆角边框下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

OpenWrt上搭建纯L2TP服务器[ZT]

转移自:http://www.openwrt.pro/post-389.html纯L2TP(L2TP+ppp,无IPSec)首先安装xl2tpd软件包opkgupdateopkginstallxl2tpd edit/etc/xl2tpd/xl2tpd。conf,并配置l2tp服务器[global]port=1701authfile=/etc/xl2tpd/x...

前端项目里常见的十种报错及其解决办法

错误6:未标记引用错误:$isnotdefinedUncaughtReferenceError:$isnotfinedUnaughtReferenceError,如果将其更改为jsp页面,则无法找到路径。此时,它变成了一个幻影。png格式。此时,您只需将以下代码添加到文件:Picture。png解决方案:在和˂Base href=“”˃错误8:未捕获类型错误...

Lynx浏览器简明使用指南(转)

Lynx可以运行在很多种操作系统下,如VMS,UNIX,Windows95,WindowsNT等,当然也包括Linux。由于没有漂亮的图形界面,所以Lynx占用资源极少,而且速度很快。另外Lynx还是唯一能在字符终端下运行的WWW浏览器。Lynx的主页地址是:http://lynx.browser.org,另外http://www.cc.ukans.edu/...

如何在jenkins上新建一个项目及其简单配置

单击[新建]进入选择页面,您可以在此页面上配置项目(包括拉取源代码、修改连续构建时间以及在打包和部署之前修改配置文件)3。在General中,您可以设置要构建的版本,如下图5所示。在源代码管理模块中,您可以设置源代码地址(我们公司常用的Git)6。如果是自动构建,您可以将自动构建时间(即构建频率)设置为7。以下是构建中的一些设置。您可以使用shell修改源代...

等保2.0四级安全要求

平等保护2.0四级安全要求四级安全保护能力:应能够在统一的安全战略下,防止恶意攻击、严重自然灾害和来自国家一级、敌对组织和资源丰富的威胁源的其他严重危害造成的资源损害。它应该能够及时检测和监控攻击和安全事件,所有功能都可以快速恢复。以下粗体字段是平等保护的第4级和第3级之间的差异,应予以更多注意。...

Java 读取ANSI文件中文乱码问题解决方式[转]

Filefile=newFile(路径);InputStreamin=newjava.io.FileInputStream(文件);BufferedReader读取器=新的BufferedReader(读取);FileInputStreamin=newFileInputStream(文件);byte[]b=新字节[3];内容如下(b);...