【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)与图像编辑中非常有用。

相关推荐
Niuguangshuo28 分钟前
深入解析Stable Diffusion基石——潜在扩散模型(LDMs)
人工智能·计算机视觉·stable diffusion
迈火31 分钟前
SD - Latent - Interposer:解锁Stable Diffusion潜在空间的创意工具
人工智能·gpt·计算机视觉·stable diffusion·aigc·语音识别·midjourney
wfeqhfxz258878235 分钟前
YOLO13-C3k2-GhostDynamicConv烟雾检测算法实现与优化
人工智能·算法·计算机视觉
芝士爱知识a1 小时前
2026年AI面试软件推荐
人工智能·面试·职场和发展·大模型·ai教育·考公·智蛙面试
Li emily1 小时前
解决港股实时行情数据 API 接入难题
人工智能·python·fastapi
Aaron15881 小时前
基于RFSOC的数字射频存储技术应用分析
c语言·人工智能·驱动开发·算法·fpga开发·硬件工程·信号处理
J_Xiong01171 小时前
【Agents篇】04:Agent 的推理能力——思维链与自我反思
人工智能·ai agent·推理
星爷AG I2 小时前
9-26 主动视觉(AGI基础理论)
人工智能·计算机视觉·agi
爱吃泡芙的小白白2 小时前
CNN参数量计算全解析:从基础公式到前沿优化
人工智能·神经网络·cnn·参数量
拐爷2 小时前
vibe‑coding 九阳神功之喂:把链接喂成“本地知识”,AI 才能稳定干活(API / 设计 / 报道 / 截图)
人工智能