目录
- 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_NAMESPACE
using namespace cv;
class Widget : public QWidget
{
Q_OBJECT
public:
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