You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C++(OpenCV)中基于给定四点绘制不规则填充区域?

实现带填充的不规则形状轮廓绘制

嘿,这个需求在OpenCV里实现起来很简单,我给你拆解成几个关键步骤,再附上完整的代码示例:

核心思路

要绘制带填充的不规则形状,我们只需要先把离散的点组织成OpenCV要求的轮廓数据结构,然后用填充函数直接在空白Mat上绘制即可——你说要忽略圆角,那完全不用额外处理,直接用原始点就行。

具体步骤

  • 步骤1:整理轮廓点集
    OpenCV的填充函数(比如fillPoly或drawContours)要求轮廓数据是vector<vector<cv::Point>>类型,也就是“多个轮廓的集合,每个轮廓由一组点组成”。我们先把你的四个点放进这个结构里:

    // 定义你的四个原始点
    std::vector<cv::Point> contour_points = {
        cv::Point(3, 5),
        cv::Point(13, 9),
        cv::Point(1, 18),
        cv::Point(16, 22)
    };
    // 包装成轮廓集合(这里只有一个轮廓)
    std::vector<std::vector<cv::Point>> contours;
    contours.push_back(contour_points);
    
  • 步骤2:创建空白画布(Mat)
    你需要一个足够大的空白Mat来容纳这个形状。可以手动指定尺寸(比如比所有点的最大坐标大一点),也可以自动计算形状的边界框来确定尺寸,后者更灵活:

    // 自动计算轮廓的边界框,确定画布的最小尺寸
    cv::Rect bounding_rect = cv::boundingRect(contour_points);
    // 创建带边距的空白彩色Mat,背景设为黑色(Scalar(0,0,0))
    cv::Mat filled_shape = cv::Mat::zeros(bounding_rect.height + 10, bounding_rect.width + 10, CV_8UC3);
    
  • 步骤3:调整点坐标(可选但推荐)
    因为我们是基于边界框创建的画布,原始点的坐标是相对于原图像的,所以需要把点偏移到画布的有效区域内:

    // 给点加上边距偏移,避免形状贴到画布边缘
    for (auto& pt : contours[0]) {
        pt.x -= bounding_rect.x - 5;
        pt.y -= bounding_rect.y - 5;
    }
    
  • 步骤4:填充轮廓
    这里有两种常用方法,效果完全一致,选你顺手的就行:
    方法一:用fillPoly直接填充

    // 设置填充颜色,比如红色(OpenCV是BGR顺序,所以红色是Scalar(0,0,255))
    cv::fillPoly(filled_shape, contours, cv::Scalar(0, 0, 255));
    

    方法二:用drawContours填充(最后一个参数设为-1表示填充整个轮廓)

    cv::drawContours(filled_shape, contours, 0, cv::Scalar(0, 0, 255), -1);
    

完整可运行代码

把上面的步骤整合起来,完整代码如下:

#include <opencv2/opencv.hpp>
#include <vector>

int main() {
    // 1. 准备轮廓点
    std::vector<cv::Point> contour_points = {
        cv::Point(3, 5),
        cv::Point(13, 9),
        cv::Point(1, 18),
        cv::Point(16, 22)
    };
    std::vector<std::vector<cv::Point>> contours;
    contours.push_back(contour_points);

    // 2. 创建带边距的空白画布
    cv::Rect bounding_rect = cv::boundingRect(contour_points);
    cv::Mat filled_shape = cv::Mat::zeros(bounding_rect.height + 10, bounding_rect.width + 10, CV_8UC3);

    // 3. 调整点坐标到画布范围内
    for (auto& pt : contours[0]) {
        pt.x -= bounding_rect.x - 5;
        pt.y -= bounding_rect.y - 5;
    }

    // 4. 填充形状
    cv::fillPoly(filled_shape, contours, cv::Scalar(0, 0, 255));

    // 查看结果
    cv::imshow("Filled Irregular Shape", filled_shape);
    cv::waitKey(0);
    cv::destroyAllWindows();

    // 保存结果(可选)
    cv::imwrite("filled_shape.png", filled_shape);

    return 0;
}

小提示

  • 如果需要绘制灰度图,把Mat的类型改成CV_8UC1,填充颜色用Scalar(255)表示白色即可。
  • OpenCV会自动把轮廓的最后一个点和第一个点连接起来,你不需要手动闭合形状。

内容的提问来源于stack exchange,提问作者user9590073

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 07:40:41