こばや小林 2024-02-12 13:14 采纳率: 85.2%
浏览 3
已结题

C++OpenCV利用鼠标事件框选图像

请问如何利用鼠标事件实现框选ROI?同时拖动过程中返回鼠标像素点RGB值和坐标?

  • 写回答

4条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-02-12 13:17
    关注

    引自免费微信小程序:皆我百晓生

    在OpenCV中,你可以通过监听鼠标事件来实现图像的框选以及实时获取鼠标像素点的RGB值和坐标。以下是一个基于C++和OpenCV的示例代码,它展示了如何实现这一功能:

    #include <opencv2/opencv.hpp>
    
    using namespace cv;
    using namespace std;
    
    // 全局变量用于记录选择框的起始点和当前点
    Point startPt, endPt;
    bool selectingROI = false;
    
    // 鼠标回调函数
    static void onMouse(int event, int x, int y, int flags, void* userdata) {
        Mat& img = *(Mat*)userdata; // 获取图像数据
    
        if (event == EVENT_LBUTTONDOWN) {
            selectingROI = true;
            startPt = Point(x, y);
        } else if (event == EVENT_MOUSEMOVE && selectingROI) {
            endPt = Point(x, y);
    
            // 画出选择框
            rectangle(img, startPt, endPt, Scalar(0, 255, 0), 2);
    
            // 获取并打印鼠标位置的像素RGB值
            Vec3b pixelColor = img.at<Vec3b>(y, x);
            cout << "Pixel RGB at (" << x << ", " << y << ") is: BGR(" 
                 << (int)pixelColor[0] << ", " << (int)pixelColor[1] << ", " << (int)pixelColor[2] << ")" << endl;
        } else if (event == EVENT_LBUTTONUP) {
            selectingROI = false;
            endPt = Point(x, y);
    
            // 确保选择框左上角坐标小于右下角坐标
            if (startPt.x > endPt.x) swap(startPt.x, endPt.x);
            if (startPt.y > endPt.y) swap(startPt.y, endPt.y);
    
            rectangle(img, startPt, endPt, Scalar(0, 255, 0), 2); // 最后一次绘制选择框
        }
    }
    
    int main() {
        Mat srcImage = imread("your_image_path.jpg"); // 读取你的图片
        if (srcImage.empty()) {
            cerr << "Error: Could not open or find the image" << endl;
            return -1;
        }
    
        namedWindow("Image", WINDOW_NORMAL);
        setMouseCallback("Image", onMouse, &srcImage); // 设置鼠标回调函数
    
        while (true) {
            imshow("Image", srcImage);
            char key = (char)waitKey(1);
            if (key == 'q' || key == 27) break; // 按q或ESC键退出
        }
    
        destroyAllWindows();
        return 0;
    }
    
    

    这段代码首先定义了一个全局布尔变量selectingROI来判断是否正在框选区域,并使用了两个全局Point变量startPtendPt分别存储选择框的起点和终点。

    鼠标回调函数onMouse会根据不同的鼠标事件(按下、移动、释放)进行相应的处理。当按下鼠标左键时开始记录选择框起点,移动鼠标时不断更新选择框终点并在图像上显示矩形框,同时输出当前鼠标位置的像素RGB值;当释放鼠标左键时结束选择框的绘制。

    将上述代码编译运行后,在显示图像的窗口中,用户可以通过鼠标左键拖拽来选择感兴趣的区域,并在控制台看到对应像素点的颜色信息。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 2月20日
  • 已采纳回答 2月12日
  • 创建了问题 2月12日

悬赏问题

  • ¥15 CPLEX用OPL编写的混合整数线性优化问题。
  • ¥15 可以用EasyConnect连接实验室内网,但无法连接内网才能访问的服务器,为什么?
  • ¥15 前端预览docx文件,文件从后端传送过来。
  • ¥15 层次聚类和蛋白质相似度
  • ¥25 主成分分析中的第一第二主成分分别代表哪些参数
  • ¥15 oracle数据库查询语句问题
  • ¥15 有没有c++绘制算法的佬们吗救孩一下
  • ¥15 android 蓝牙闪退
  • ¥15 绝缘子污秽comsol仿真参数
  • ¥15 labelme生成的json有乱码?