qt+opencv 获取图像灰度值并以QTableView展现

思路如下:

先用opencv方法打开并以灰度图像的方式读取一张图片,然后获取整张图所有像素点的灰度值,将这些值存入容器中。然后因为图像为8192*4096的尺寸,像素点灰度值数据量较大。因此采用QTableView加自定义QAbstractTableModel的方式去展示数据。每个单元格的文本值和背景色为对应像素点的灰度值。

效果如图:

相关代码如下:

cpp 复制代码
// 读取图片
 QString path;
 cv::Mat img;
 
 img = cv::imread(path.toStdString(), CV_8UC1);
 if (img.empty()) {
     cout << "读取不到加载的图片数据";
     return;
 }
cpp 复制代码
//获取图像像素点灰度值
void GetImgPixelGrayVal()
{
    //图像不为空且为单通道(即灰度图)
    if(img.empty() || img.channels()!=1){
        return;
    }
    
    QMap<int,QVector<uchar>> m_pixel;               // 像素点灰度值容器(行,列集合)
    QSize curImgSize;                   			// 当前图像尺寸

#if 1
    //获取像素点灰度值方法一(比方法二快)
    m_pixel.clear();
    for (int r = 0; r < curImgSize.height(); ++r) {
        uchar* data = img.ptr<uchar>(r); // 获取第r行像素数组的指针

        QVector<uchar> tmpVec;
        for (int c = 0; c < curImgSize.width(); ++c) {
            uchar pixelValue = data[c]; // 获取第r行第c列像素点的灰度值
            tmpVec.append(pixelValue);
        }
        m_pixel.insert(r,tmpVec);
    }
#else
    //获取像素点灰度值方法二
    for(int i=0; i<curImgSize.height(); i++){
        for(int j=0; j<curImgSize.width(); j++){
             int grayVal = (int)img.at<uchar>(i,j);
        }
    }
#endif

    QStringList list1, list2;
    for(int i=1; i<=curImgSize.width(); i++){
        list1 << QString("Column %1").arg(i);
    }
    for(int i=1; i<=curImgSize.height(); i++){
        list2 << QString("Row %1").arg(i);
    }

    m_tableModel->SetHorizontalHeadData(list1);
    m_tableModel->SetVerticalHeadData(list2);
    m_tableModel->SetData(m_pixel);
    m_tableView = new PixelTableView(this);    
    connect(m_tableView, &PixelTableView::sig_view_table_close, this, [=](){delete m_tableView; m_tableView=nullptr;}, Qt::QueuedConnection);
    m_tableView->setModel(m_tableModel);
    m_tableView->show();
}
cpp 复制代码
//自定义QTableView和QAbstractTableModel
#include <QObject>
#include <QAbstractTableModel>
#include <QTableView>
#include <QHeaderView>
#include <QStandardItemModel>

class PixelTableView : public QTableView
{
    Q_OBJECT

public:
    PixelTableView(QWidget *parent=nullptr);
    ~PixelTableView();

protected:
    void mousePressEvent(QMouseEvent *event);

    void closeEvent(QCloseEvent *event);

signals:
    void sig_view_table_close();
};



class PixelTableModel : public QAbstractTableModel
{
    Q_OBJECT

public:
    PixelTableModel(QObject *parent = nullptr);
    ~PixelTableModel();
    void SetHorizontalHeadData(const QStringList& list);  //设置表头数据
    void SetVerticalHeadData(const QStringList& list);
    void SetData(const QMap<int, QVector<uchar>>& map);   //设置表格数据
public:
    int rowCount(const QModelIndex& parent) const;  //返回行数
    int columnCount(const QModelIndex& parent) const;   //返回列数
    QVariant data(const QModelIndex& index, int role) const;
    QVariant headerData(int section, Qt::Orientation orientation, int role) const;  //返回指定表头数据


private:
    QStringList m_headData_h; //表头数据
    QStringList m_headData_v;
    QMap<int, QVector<uchar>> m_datas;    //显示的数据
};
cpp 复制代码
PixelTableView::PixelTableView(QWidget *parent)
    : QTableView(parent)
{

    //this->setStyleSheet("QTableView::item { background-color: #FFFFC9; }");
    this->setWindowTitle(tr("Pixel Viewer"));
    this->resize(1000,500);
    this->horizontalHeader()->setStyleSheet("QHeaderView::section { background-color: #FFFFC9; }");//#E1DAD9
    this->verticalHeader()->setStyleSheet("QHeaderView::section { background-color: #FFFFC9; }");
    this->horizontalHeader()->setSectionsClickable(false);
    this->verticalHeader()->setSectionsClickable(false);
    this->setCornerButtonEnabled(false);
    this->setWindowFlag(Qt::Window);
    this->setWindowModality(Qt::ApplicationModal);
    this->setAttribute(Qt::WA_QuitOnClose, false);
}


PixelTableView::~PixelTableView()
{

}


void PixelTableView::mousePressEvent(QMouseEvent *event)
{

}

void PixelTableView::closeEvent(QCloseEvent *event)
{
    emit sig_view_table_close();
    QTableView::closeEvent(event);
}



PixelTableModel::PixelTableModel(QObject *parent)
    : QAbstractTableModel(parent)
{
}

PixelTableModel::~PixelTableModel()
{
}

int PixelTableModel::rowCount(const QModelIndex& parent) const
{
    if (parent.isValid()) {
        return 0;
    } else {
        return m_headData_v.size();  //显示数据的大小
    }
}

int PixelTableModel::columnCount(const QModelIndex& parent) const
{
    if (parent.isValid()) {
        return 0;
    } else {
        return m_headData_h.size();   //表头的大小
    }
}

QVariant PixelTableModel::data(const QModelIndex& index, int role) const
{
    if (!index.isValid()) {
        return QVariant();
    }
    if (role == Qt::DisplayRole) {
        return (m_datas.begin() + index.row())->at(index.column()); //单元格中数据
    }
    if (role == Qt::TextAlignmentRole) {    //对其方式
        return Qt::AlignCenter; //对齐格式为居中
    }
    if (role == Qt::BackgroundColorRole) {  //单元格背景颜色和灰度值相同
        return QColor((m_datas.begin() + index.row())->at(index.column()),(m_datas.begin() + index.row())->at(index.column()),(m_datas.begin() + index.row())->at(index.column()));
    }
    if (role == Qt::TextColorRole) {
        return (m_datas.begin() + index.row())->at(index.column()) > 128 ? QColor(Qt::black) : QColor(Qt::white);
    }
    return QVariant();
}

QVariant PixelTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if (orientation == Qt::Horizontal) {    //水平表头
        if (role == Qt::DisplayRole) {  //角色为显示
            return m_headData_h.at(section);  //返回指定位置表头
        }
    }else{
        if(role == Qt::DisplayRole) {
            return m_headData_v.at(section);
        }
    }
    return QAbstractTableModel::headerData(section, orientation, role);
}

void PixelTableModel::SetHorizontalHeadData(const QStringList& list)
{
    m_headData_h = list;
}

void PixelTableModel::SetVerticalHeadData(const QStringList& list)
{
    m_headData_v = list;
}

void PixelTableModel::SetData(const QMap<int, QVector<uchar>>& map)
{
    beginResetModel();  //刷新表格
    m_datas = map;
    endResetModel();
}
相关推荐
m0_699659565 小时前
QT知识点复习
开发语言·qt
深蓝海拓7 小时前
基于深度学习的视觉检测小项目(十六) 用户管理界面的组态
人工智能·python·深度学习·qt·pyqt
弄不死的强仔9 小时前
可被electron等调用的Qt截图-录屏工具【源码开放】
前端·javascript·qt·electron·贴图·qt5
dreadp16 小时前
解锁豆瓣高清海报(二) 使用 OpenCV 拼接和压缩
图像处理·python·opencv·计算机视觉·数据分析
行十万里人生1 天前
Qt事件处理:理解处理器、过滤器与事件系统
开发语言·git·qt·华为od·华为·华为云·harmonyos
黑金IT1 天前
Python3 + Qt5:实现AJAX异步更新UI
qt·ui·ajax
人工智能教学实践1 天前
基于 yolov8_pyqt5 自适应界面设计的火灾检测系统 demo:毕业设计参考
qt·yolo·课程设计
扎量丙不要犟1 天前
跨平台的客户端gui到底是选“原生”还是web
前端·javascript·c++·qt·rust·electron·tauri
慕雪华年1 天前
【Linux】opencv在arm64上提示找不到libjasper-dev
linux·运维·opencv
墨绿色的摆渡人1 天前
python | OpenCV小记(一):cv2.imread(f) 读取图像操作(待更新)
开发语言·python·opencv