【opencv】示例-contours2.cpp 使用 findContours 和drawContours函数来查找和绘制轮廓

cpp 复制代码
// 包含OpenCV图像处理头文件
#include "opencv2/imgproc.hpp"
// 包含OpenCV高级用户界面头文件
#include "opencv2/highgui.hpp"
// 化学数学函数库头文件
#include <math.h>
// 包含输入输出流头文件
#include <iostream>


// 使用cv和std命名空间中定义的所有内容
using namespace cv;
using namespace std;


// 帮助函数的声明和实现
static void help(char** argv)
{
    // 输出帮助信息
    cout
        << "\nThis program illustrates the use of findContours and drawContours\n"
        << "The original image is put up along with the image of drawn contours\n"
        << "Usage:\n";
    // 输出程序使用方法
    cout
        << argv[0]
        << "\nA trackbar is put up which controls the contour level from -3 to 3\n"
        << endl;
}


// 定义图像宽度为500
const int w = 500;
// 定义轮廓等级变量,初始值为3
int levels = 3;


// 定义存放轮廓的向量
vector<vector<Point> > contours;
// 定义层次结构的向量
vector<Vec4i> hierarchy;


// 滑块回调函数,当滑块值改变时调用
static void on_trackbar(int, void*)
{
    // 创建一个黑色的图像
    Mat cnt_img = Mat::zeros(w, w, CV_8UC3);
    // 计算轮廓等级
    int _levels = levels - 3;
    // 根据轮廓等级绘制轮廓
    drawContours( cnt_img, contours, _levels <= 0 ? 3 : -1, Scalar(128,255,255),
                  3, LINE_AA, hierarchy, std::abs(_levels) );


    // 显示轮廓图像
    imshow("contours", cnt_img);
}


// 主函数
int main( int argc, char** argv)
{
    // 解析命令行参数
    cv::CommandLineParser parser(argc, argv, "{help h||}");
    // 如果有help参数,则显示帮助信息
    if (parser.has("help"))
    {
        help(argv);
        return 0;
    }
    // 创建一个黑色的背景图
    Mat img = Mat::zeros(w, w, CV_8UC1);
    // 绘制6个面孔
    for( int i = 0; i < 6; i++ )
    {
        // 根据面孔索引计算偏移量
        int dx = (i%2)*250 - 30;
        int dy = (i/2)*150;
        // 定义白色和黑色
        const Scalar white = Scalar(255);
        const Scalar black = Scalar(0);


        // 如果是第一个面孔,绘制眼睛里的光芒
        if( i == 0 )
        {
            for( int j = 0; j <= 10; j++ )
            {
                double angle = (j+5)*CV_PI/21;
                line(img, Point(cvRound(dx+100+j*10-80*cos(angle)),
                    cvRound(dy+100-90*sin(angle))),
                    Point(cvRound(dx+100+j*10-30*cos(angle)),
                    cvRound(dy+100-30*sin(angle))), white, 1, 8, 0);
            }
        }
        
        // 绘制面孔的其他部分
        ellipse( img, Point(dx+150, dy+100), Size(100,70), 0, 0, 360, white, -1, 8, 0 );
        ellipse( img, Point(dx+115, dy+70), Size(30,20), 0, 0, 360, black, -1, 8, 0 );
        ellipse( img, Point(dx+185, dy+70), Size(30,20), 0, 0, 360, black, -1, 8, 0 );
        ellipse( img, Point(dx+115, dy+70), Size(15,15), 0, 0, 360, white, -1, 8, 0 );
        ellipse( img, Point(dx+185, dy+70), Size(15,15), 0, 0, 360, white, -1, 8, 0 );
        ellipse( img, Point(dx+115, dy+70), Size(5,5), 0, 0, 360, black, -1, 8, 0 );
        ellipse( img, Point(dx+185, dy+70), Size(5,5), 0, 0, 360, black, -1, 8, 0 );
        // 绘制一个椭圆,表示鼻子
        ellipse( img, Point(dx+150, dy+100), Size(10,5), 0, 0, 360, black, -1, 8, 0 );
        // 绘制一个椭圆,表示嘴巴
        ellipse( img, Point(dx+150, dy+150), Size(40,10), 0, 0, 360, black, -1, 8, 0 );
        // 绘制两个椭圆表示耳朵
        ellipse( img, Point(dx+27, dy+100), Size(20,35), 0, 0, 360, white, -1, 8, 0 );
        ellipse( img, Point(dx+273, dy+100), Size(20,35), 0, 0, 360, white, -1, 8, 0 );
    }
    // 显示带有面孔的图像
    namedWindow( "image", 1 );
    imshow( "image", img );
    // 提取轮廓
    vector<vector<Point> > contours0;
    findContours( img, contours0, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE);


    // 将提取的轮廓近似为多边形
    contours.resize(contours0.size());
    for( size_t k = 0; k < contours0.size(); k++ )
        approxPolyDP(Mat(contours0[k]), contours[k], 3, true);


    // 创建一个新窗口来显示轮廓
    namedWindow( "contours", 1 );
    // 创建滑块,用于控制轮廓等级
    createTrackbar( "levels+3", "contours", &levels, 7, on_trackbar );


    // 初始调用滑块回调函数
    on_trackbar(0,0);
    // 等待用户按键事件
    waitKey();


    // 程序正常退出
    return 0;
}

代码的功能是演示如何使用 findContoursdrawContours 函数来查找和绘制轮廓。首先,程序创建了一个黑色的背景图,在上面绘制了六个有趣的面孔。然后,它提取这些面孔的轮廓,并使用轨迹条控制器来调整显示的轮廓等级。这是一个使用OpenCV进行图像处理和用户界面交云的演示程序,演示了轮廓绘制的基本概念。

go 复制代码
findContours( img, contours0, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE);
css 复制代码
approxPolyDP(Mat(contours0[k]), contours[k], 3, true);
cpp 复制代码
drawContours( cnt_img, contours, _levels <= 0 ? 3 : -1, Scalar(128,255,255),
              3, LINE_AA, hierarchy, std::abs(_levels) );

The End

相关推荐
超龄超能程序猿9 分钟前
(三)PS识别:基于噪声分析PS识别的技术实现
图像处理·人工智能·计算机视觉
要努力啊啊啊10 分钟前
YOLOv3-SPP Auto-Anchor 聚类调试指南!
人工智能·深度学习·yolo·目标检测·目标跟踪·数据挖掘
好开心啊没烦恼13 分钟前
Python 数据分析:numpy,说人话,说说数组维度。听故事学知识点怎么这么容易?
开发语言·人工智能·python·数据挖掘·数据分析·numpy
生态遥感监测笔记20 分钟前
GEE利用已有土地利用数据选取样本点并进行分类
人工智能·算法·机器学习·分类·数据挖掘
天天扭码1 小时前
从图片到语音:我是如何用两大模型API打造沉浸式英语学习工具的
前端·人工智能·github
Tony沈哲1 小时前
macOS 上为 Compose Desktop 构建跨架构图像处理 dylib:OpenCV + libraw + libheif 实践指南
opencv·算法
张彦峰ZYF1 小时前
从检索到生成:RAG 如何重构大模型的知识边界?
人工智能·ai·aigc
刘海东刘海东1 小时前
结构型智能科技的关键可行性——信息型智能向结构型智能的转变(修改提纲)
人工智能·算法·机器学习
**梯度已爆炸**2 小时前
NLP文本预处理
人工智能·深度学习·nlp
uncle_ll2 小时前
李宏毅NLP-8-语音模型
人工智能·自然语言处理·语音识别·语音模型·lm