【opencv】示例-create_mask.cpp 通过鼠标交互产生掩膜图像(黑白图像)

cpp 复制代码
/*
* create_mask.cpp
*
* Author:
* Siddharth Kherada <siddharthkherada27[at]gmail[dot]com>
*
* 这个教程演示了如何制作掩膜图像(黑白图像)。
* 该程序将输入图像作为源图像,并输出对应的掩膜图像。
*/


#include "opencv2/imgproc.hpp"  // 导入OpenCV图像处理头文件
#include "opencv2/imgcodecs.hpp"  // 导入OpenCV图像编码解码头文件
#include "opencv2/highgui.hpp"  // 导入OpenCV高层图形用户界面头文件
#include <iostream>  // 导入输入输出流头文件


using namespace std;  // 使用std命名空间,避免每次都要加std::
using namespace cv;  // 使用cv命名空间,避免每次都要加cv::


Mat src, img1, mask, final;  // 定义Mat类对象src(源图像),img1(中间图像),mask(掩膜),final(最终结果)


Point point;  // 定义一个点变量
vector<Point> pts;  // 定义一个点的向量,用于存储多个点
int drag = 0;  // 定义一个整型变量drag表示是否在拖动,默认为0(不在拖动)
int var = 0;  // 定义一个整型变量var用来计数,初始化为0
int flag = 0;  // 定义一个整型变量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)
        {
            // 如果flag为0表明还未完成绘制
            if (var == 0)
                img1 = src.clone();  // 如果是第一个点,
            point = Point(x, y);  // 将点击的点位置保存到point中
            circle(img1, point, 2, Scalar(0, 0, 255), -1, 8, 0);  // 在img1上绘制点
            pts.push_back(point);  // 把点添加到向量pts中
            var++;  // 计数加1
            drag  = 1;  // 标记为拖动状态


            if (var > 1)
                line(img1,pts[var-2], point, Scalar(0, 0, 255), 2, 8, 0);  // 绘制线段


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


    if (event == EVENT_LBUTTONUP && drag)
    {
        // 左键释放且正处于拖动状态
        imshow("Source", img1);  // 显示img1
        drag = 0;  // 标记为非拖动状态
    }


    if (event == EVENT_RBUTTONDOWN)
    {
        // 右键按下
        flag = 1;  // 设置标记位
        img1 = src.clone();  // 重新克隆源图像到img1


        if (var != 0)
        {
            polylines( img1, pts, 1, Scalar(0,0,0), 2, 8, 0);  // 绘制多边形轮廓
        }


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


    if (event == EVENT_RBUTTONUP)
    {
        // 右键释放
        flag = var;  // 设置flag为var
        final = Mat::zeros(src.size(), CV_8UC3);  // 创建与src同等大小的Mat对象final,并初始化为0
        mask = Mat::zeros(src.size(), CV_8UC1);  // 创建与src同等大小的mask,并初始化为0


        fillPoly(mask, pts, Scalar(255, 255, 255), 8, 0);  // 使用多边形填充掩膜
        bitwise_and(src, src, final, mask);  // 计算src和mask的按位与,得到结果保存在final中
        imshow("Mask", mask);  // 显示掩膜mask
        imshow("Result", final);  // 显示最终结果final
        imshow("Source", img1);  // 显示img1
    }


    if (event == EVENT_MBUTTONDOWN)
    {
        // 中键按下
        pts.clear();  // 清除点向量
        var = 0;  // 将var重置为0
        drag = 0;  // 将drag重置为0
        flag = 0;  // 将flag重置为0
        imshow("Source", src);  // 显示源图src
    }
}


int main(int argc, char **argv)
{
    // 主函数,程序开始的地方
    CommandLineParser parser(argc, argv, "{@input | lena.jpg | input image}");  // 命令行解析器
    parser.about("This program demonstrates using mouse events\n");  // 关于程序的说明
    parser.printMessage();  // 打印消息
    cout << "\n\tleft mouse button - set a point to create mask shape\n"
        "\tright mouse button - create mask from points\n"
        "\tmiddle mouse button - reset\n";  // 提示用户如何使用鼠标按钮
    String input_image = parser.get<String>("@input");  // 从命令行获取输入图像


    src = imread(samples::findFile(input_image));  // 读取输入图像


    if (src.empty())
    {
        printf("Error opening image: %s\n", input_image.c_str());  // 如果图像为空,打印错误消息
        return 0;  // 退出程序
    }


    namedWindow("Source", WINDOW_AUTOSIZE);  // 创建一个名为"Source"的窗口
    setMouseCallback("Source", mouseHandler, NULL);  // 为"Source"窗口设置鼠标事件回调函数
    imshow("Source", src);  // 显示源图像
    waitKey(0);  // 等待用户按键


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

这段C++代码利用OpenCV库和标准输入输出流,实现了一个通过鼠标交互产生掩膜图像的工具。程序读取源图像文件,用户可以通过鼠标左键点击设置掩膜多边形的顶点,右键完成掩膜的创建,中键重置所有操作。最终,程序会展示原图、掩膜图以及掩膜后的结果图。这种功能在图像处理中,尤其是在对象分割(Object Segmentation)与图像编辑中非常有用。

相关推荐
wyw000021 分钟前
目标检测之SSD
人工智能·目标检测·计算机视觉
AKAMAI24 分钟前
圆满循环:Akamai 的演进如何为 AI 推理时代奠定基石
人工智能·云计算
幻云201034 分钟前
AI自动化编排:从入门到精通(基于Dify构建AI智能系统)
运维·人工智能·自动化
CoderJia程序员甲1 小时前
GitHub 热榜项目 - 日榜(2026-1-13)
人工智能·ai·大模型·github·ai教程
梦梦代码精1 小时前
《全栈开源智能体:终结企业AI拼图时代》
人工智能·后端·深度学习·小程序·前端框架·开源·语音识别
suyong_yq1 小时前
RUHMI & RA8P1 教程 Part4 - 使用 RUHMI 转换 AI 模型文件
人工智能·ai·嵌入式·arm
程序员欣宸1 小时前
LangChain4j实战之十三:函数调用,低级API版本
java·人工智能·ai·langchain4j
charlie1145141911 小时前
从 0 开始的机器学习——NumPy 线性代数部分
开发语言·人工智能·学习·线性代数·算法·机器学习·numpy
咚咚王者1 小时前
人工智能之核心基础 机器学习 第十二章 半监督学习
人工智能·学习·机器学习
人工智能训练1 小时前
UE5 如何显示蓝图运行流程
人工智能·ue5·ai编程·数字人·蓝图