目录
- 1、介绍
- 2、效果展示
- 3、实现过程
- 3.1 图像的加载和显示
- 3.2 设置鼠标跟踪事件激活
- 3.3 实现代码
- 4、源码展示
1、介绍
上一篇介绍了使用OpenCV的setMouseCallback回调函数实现获取鼠标点击点的图像坐标和像素值,本篇使用鼠标事件mouseMoveEvent函数来实现实时获取鼠标的坐标和对应图像点的像素值,并将结果实时显示在label控件上。
2、效果展示
3、实现过程
3.1 图像的加载和显示
这里加载图像并在QLabel控件上显示,我这里使用OpenCV的imread函数加载了图像,然后把图像转换成QPixmap显示在QLabel上。
img = imread("lena.png");cvtColor(img, img, COLOR_BGR2RGB);QImage disImage = QImage((const unsigned char*)(img.data), img.cols, img.rows, QImage::Format_RGB888);QPixmap pix = QPixmap::fromImage(disImage);pix.scaled(ui->lbl_pic->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);ui->lbl_pic->setPixmap(pix); // label 显示图像
这里也可以直接用QPixmap的load函数加载图像和显示,然后在mouseMoveEvent函数中要通过OpenCV获取图像的像素值时,将QPixmap格式再转换成Mat类型。
3.2 设置鼠标跟踪事件激活
激活控件内鼠标跟随属性,调用setMouseTracking(true)激活后在鼠标点击控件内区域进入mouseMoveEvent函数实现鼠标跟随。
如果想不点击鼠标在控件内移动触发mouseMoveEvent函数,就需要同时设置控件和窗口的setMouseTracking(true),这样鼠标在控件内移动时可以实时跟踪鼠标事件。
/*激活控件鼠标跟随属性,激活后在点击鼠标后进入mouseMoveEvent函数*//*如果不点击鼠标时想要在控件上触发mouseMoveEvent函数,就需要同时激活控件和窗口*/ui->lbl_pic->setMouseTracking(true);setMouseTracking(true);
void Widget::mouseMoveEvent(QMouseEvent *event)
{QPoint pt = event->pos();QRect rect = ui->lbl_pic->geometry();if(rect.contains(pt)){QPoint PicPoint = QPoint(pt.x()-rect.x(), pt.y()- rect.y());QString str = QString("(x:%1,y:%2)").arg(PicPoint.x()).arg(PicPoint.y());ui->lbl_pos->setText(str);if(img.channels() == 1){int grayValue;switch (img.type()){case 0:grayValue = static_cast<int>(img.at<uchar>(Point(PicPoint.x(), PicPoint.y())));break;case 1:grayValue = static_cast<int>(img.at<char>(Point(PicPoint.x(), PicPoint.y())));break;case 2:grayValue = static_cast<int>(img.at<ushort>(Point(PicPoint.x(), PicPoint.y())));break;case 3:grayValue = static_cast<int>(img.at<short>(Point(PicPoint.x(), PicPoint.y())));break;case 4:grayValue = static_cast<int>(img.at<int>(Point(PicPoint.x(), PicPoint.y())));break;case 5:grayValue = static_cast<int>(img.at<float>(Point(PicPoint.x(), PicPoint.y())));break;case 6:grayValue = static_cast<int>(img.at<double>(Point(PicPoint.x(), PicPoint.y())));break;}}else{int value_B = static_cast<int>(img.at<Vec3b>(Point(PicPoint.x(), PicPoint.y()))[0]);int value_G = static_cast<int>(img.at<Vec3b>(Point(PicPoint.x(), PicPoint.y()))[1]);int value_R = static_cast<int>(img.at<Vec3b>(Point(PicPoint.x(), PicPoint.y()))[2]);QString str = QString("B:%1, G:%2, R:%3").arg(value_B).arg(value_G).arg(value_R);ui->lbl_pix->setText(str);}}
}
3.3 实现代码
widget.h
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QMouseEvent>
#include "opencv2/opencv.hpp"QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEusing namespace cv;
class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();protected:void mouseMoveEvent(QMouseEvent *event);
private:Ui::Widget *ui;Mat img;
};
#endif // WIDGET_H
widget.cpp
#pragma execution_character_set("utf-8")
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);this->setWindowTitle("坐标像素实时监控");img = imread("lena.png");cvtColor(img, img, COLOR_BGR2RGB);QImage disImage = QImage((const unsigned char*)(img.data), img.cols, img.rows, QImage::Format_RGB888);QPixmap pix = QPixmap::fromImage(disImage);pix.scaled(ui->lbl_pic->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);// label 显示图像ui->lbl_pic->setPixmap(pix);/*激活控件鼠标跟随属性,激活后在点击鼠标后进入mouseMoveEvent函数*//*如果不点击鼠标时想要在控件上触发mouseMoveEvent函数,就需要同时激活控件和窗口*/ui->lbl_pic->setMouseTracking(true);setMouseTracking(true);
}Widget::~Widget()
{delete ui;
}void Widget::mouseMoveEvent(QMouseEvent *event)
{QPoint pt = event->pos();QRect rect = ui->lbl_pic->geometry();if(rect.contains(pt)){QPoint PicPoint = QPoint(pt.x()-rect.x(), pt.y()- rect.y());QString str = QString("(x:%1,y:%2)").arg(PicPoint.x()).arg(PicPoint.y());ui->lbl_pos->setText(str);if(img.channels() == 1){ //单通道图像int grayValue;switch (img.type()){case 0:grayValue = static_cast<int>(img.at<uchar>(Point(PicPoint.x(), PicPoint.y())));break;case 1:grayValue = static_cast<int>(img.at<char>(Point(PicPoint.x(), PicPoint.y())));break;case 2:grayValue = static_cast<int>(img.at<ushort>(Point(PicPoint.x(), PicPoint.y())));break;case 3:grayValue = static_cast<int>(img.at<short>(Point(PicPoint.x(), PicPoint.y())));break;case 4:grayValue = static_cast<int>(img.at<int>(Point(PicPoint.x(), PicPoint.y())));break;case 5:grayValue = static_cast<int>(img.at<float>(Point(PicPoint.x(), PicPoint.y())));break;case 6:grayValue = static_cast<int>(img.at<double>(Point(PicPoint.x(), PicPoint.y())));break;}QString str = QString("Gray Value:%1").arg(grayValue);ui->lbl_pix->setText(str);}else //多通道图像{int value_B = static_cast<int>(img.at<Vec3b>(Point(PicPoint.x(), PicPoint.y()))[0]);int value_G = static_cast<int>(img.at<Vec3b>(Point(PicPoint.x(), PicPoint.y()))[1]);int value_R = static_cast<int>(img.at<Vec3b>(Point(PicPoint.x(), PicPoint.y()))[2]);QString str = QString("B:%1, G:%2, R:%3").arg(value_B).arg(value_G).arg(value_R);ui->lbl_pix->setText(str);}}
}
4、源码展示
本小例程的代码放到我的开源gitte项目里,欢迎一起学习,也希望能收获你的小星星。
项目源码PixelPos_MouseFollow