图像处理OpenCv

【图像处理】OpenCV系列三十二 --- polylines、

2019-05-15  本文已影响34人  307656af5a04

一、polylines()函数详解

1、函数原型

// 原型一
void polylines(InputOutputArray img, 
    const Point* const* pts,
    const int* npts,
    int ncontours, 
    bool isClosed, 
    const Scalar& color,
    int thickness = 1, 
    int lineType = LINE_8, 
    int shift = 0);

// 原型二
void polylines(InputOutputArray img, 
    InputArrayOfArrays pts,
    bool isClosed, 
    const Scalar& color,
    int thickness = 1, 
    int lineType = LINE_8, 
    int shift = 0);

2、函数功能
绘制几条多边形曲线;

3、参数详解

二、ellipse2Poly()函数详解

1、函数原型

// 原型一
void ellipse2Poly(Point center, 
    Size axes, 
    int angle,
    int arcStart, 
    int arcEnd, 
    int delta,
    CV_OUT std::vector<Point>& pts);

// 原型二
void ellipse2Poly(Point2d center, 
    Size2d axes, 
    int angle,
    int arcStart, 
    int arcEnd, 
    int delta,
    CV_OUT std::vector<Point2d>& pts);

2、函数功能
计算近似指定椭圆弧的多边形的顶点;如果arcStart大于arcEnd,则交换它们;

3、参数详解

三、fillPoly()函数详解

1、函数原型

// 原型一
void fillPoly(InputOutputArray img, 
    const Point** pts,
    const int* npts, 
    int ncontours,
    const Scalar& color, 
    int lineType = LINE_8, 
    int shift = 0,
    Point offset = Point());

// 原型二
void fillPoly(InputOutputArray img, 
    InputArrayOfArrays pts,
    const Scalar& color, 
    int lineType = LINE_8, 
    int shift = 0,
    Point offset = Point());

2、函数功能
填充一个或多个多边形所包围的区域;

3、参数详解

四、fillConvexPoly ()函数详解

1、函数原型

// 原型一
void fillConvexPoly(InputOutputArray img, 
    const Point* pts, 
    int npts,
    const Scalar& color, 
    int lineType = LINE_8,
    int shift = 0);

// 原型二
void fillConvexPoly(InputOutputArray img, 
    InputArray points,
    const Scalar& color, 
    int lineType = LINE_8,
    int shift = 0);

2、函数功能
填充凸多边形;

3、参数详解

五、综合实例

1、实验实例

实现抠图

#include <opencv2/imgproc.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>

using namespace std;
using namespace cv;

Mat src, img1, mask, final;

Point point;

vector<Point> pts;

int drag = 0;
int var = 0;
int flag = 0;

void mouseHandler(int, int, int, int, void*);

void mouseHandler(int event, int x, int y, int, void*)
{
    // 左键按下
    if (event == EVENT_LBUTTONDOWN && !drag)
    {
        if (flag == 0)  // 标记是否生成掩码
        {
            // 第一次进入备份原图像
            if (var == 0) 
                img1 = src.clone();

            // 记录当前左键按下的点
            point = Point(x, y);

            // 在图像上将这个点用圆绘制出来,实心圆
            circle(img1, point, 2, Scalar(0, 0, 255), -1, 8, 0);
    
            // 点入vector
            pts.push_back(point);

            // 点的数量加1
            var++;

            // 表示已经有了一个点了
            drag = 1;  
            
            // 如果点的数量大于1,则绘制上一个点于当前点的直线
            if (var > 1)
                line(img1, pts[var - 2], point, Scalar(0, 0, 255), 2, 8, 0);

            // 刷新图像
            imshow("Source", img1);
        }
    }

    // 左键松起
    if (event == EVENT_LBUTTONUP && drag)
    {
        // 显示图像
        imshow("Source", img1);

        drag = 0;
    }
    // 右键按下
    if (event == EVENT_RBUTTONDOWN)
    {
        // 表示右键
        flag = 1;

        // 备份图像
        img1 = src.clone();

        // 如果左键点击的得到的点数不为0,则绘制多边形
        if (var != 0)
        {
            polylines(img1, pts, 1, Scalar(0, 0, 0), 2, 8, 0);
        }

        // 显示图像
        imshow("Source", img1);
    }

    // 右键松起
    if (event == EVENT_RBUTTONUP)
    {
        flag = var;

        // 创建全为0的彩色图像
        final = Mat::zeros(src.size(), CV_8UC3);

        // 创建掩码图像
        mask = Mat::zeros(src.size(), CV_8UC1);

        vector<vector<Point> > vpts;

        // 如果点集为孔,则什么都不做
        if (pts.size() == 0)
        {
            return;
        }
        vpts.push_back(pts);

        // 用白色填充多边形(掩码图像)
        fillPoly(mask, vpts, Scalar(255, 255, 255), 8, 0);

        // 对原图像每一个像素进行与操作,使用mask掩码
        bitwise_and(src, src, final, mask);

        // 显示掩码图像
        imshow("Mask", mask);

        // 显示结果图像
        imshow("Result", final);

        // 显示原图像
        imshow("Source", img1);
    }

    // 指示按下鼠标中间按钮,清除所有标记
    if (event == EVENT_MBUTTONDOWN)
    {
        pts.clear();
        var = 0;
        drag = 0;
        flag = 0;
        imshow("Source", src);
    }
}
int main(int argc, char **argv)
{
    // 载入图像
    src = imread("lena.png");

    // 图像是否为孔
    if (src.empty())
    {
        printf("Error open image !\n");
        return 0;
    }

    // 创建窗口
    namedWindow("Source", WINDOW_AUTOSIZE);

    // 调用鼠标回调函数
    setMouseCallback("Source", mouseHandler, NULL);

    // 显示图像
    imshow("Source", src);

    waitKey(0);
    return 0;
}

2、实验结果

左键绘制的点 右键得到的掩码图像 效果图

我是奕双,现在已经毕业将近两年了,从大学开始学编程,期间学习了C语言编程,C++语言编程,Win32编程,MFC编程,毕业之后进入一家图像处理相关领域的公司,掌握了用OpenCV对图像进行处理,如果大家对相关领域感兴趣的话,可以关注我,我这边会为大家进行解答哦!如果大家需要相关学习资料的话,可以私聊我哦!

上一篇下一篇

猜你喜欢

热点阅读