如何在 QTableView 上存储图像(Qt 和 openCV)
Posted
技术标签:
【中文标题】如何在 QTableView 上存储图像(Qt 和 openCV)【英文标题】:How to store images on QTableView (Qt and openCV) 【发布时间】:2018-07-18 08:28:51 【问题描述】:我有一个由 18 列的 QTableView 和一个 QGraphicsView 组成的 GUI,我在其中使用按钮上传图像。我可以在感兴趣的区域 (ROI) 上绘制一个框,只要我用鼠标右键单击它,我就会打开一个小对话框。此对话框由具有两个页面的 TabWidget 组成。第一页有一个小的 QGraphicsView,它带有前一个框绘制的裁剪图像(比如图像 A)。 TabWidget 的第二页还有另一个 QGraphicsView,我用它来上传我桌面上以前保存的 .jpg 图像(比如图像 B)。一旦我点击确定,此对话框上的信息将被传输到 QTableView 的第一行。图像 A 将被放在一列中(准确地说是第 17 列),而图像 B 也将放在另一列中(准确地说是第 18 列)。
我能够将裁剪后的图像 A(这是最困难的部分,因为我必须努力理解 Qt 和 openCV 之间的转换格式,反之亦然)存储在 QTableView 但不是图像 B(我处理得很简单我保存在桌面上的图像)。
我尝试了不同的选项:选项 1:我创建了一个函数,用于处理我在 TabWidget(图像 B)的第二页上上传的图像,选项 2: 我尝试调试以缩小问题范围,但编译器似乎没有看到我要存储的图像。
我附上了带有此错误的代码中最重要的部分:
在 clipscene.h 中是我声明我使用的最重要的变量和函数的方式:
class clipScene : public QDialog
Q_OBJECT
public:
explicit clipScene(QWidget *parent = 0);
~clipScene();
void setImage(QImage img);
void setClassifiedImage(QImage img);
SelectionData getData();
void setData(SelectionData newdata);
private:
SelectionData returnData;
Ui::clipScene *ui;
QImage simg;
QImage featureClassified;
;
在clipscene.cpp中这是我用来处理图像B的函数setClassifiedImage
void clipScene::setClassifiedImage(QImage img)
featureClassified = img;
QGraphicsPixmapItem* item = new QGraphicsPixmapItem(QPixmap::fromImage(featureClassified));
workingImageScene->addItem(item);
在clipscene.cpp中使用setImage
我成功处理了裁剪图像的Qt和openCV转换
void clipScene::setImage(QImage img)
simg = img;
QGraphicsPixmapItem* item = new QGraphicsPixmapItem(QPixmap::fromImage(simg));
scene->addItem(item);
ui->graphicsViewClipped->show();
cv::Mat input = cv::Mat(simg.height(), simg.width(), CV_16UC3, simg.bits(), simg.bytesPerLine());
// .....operations...
// .....operations...
在 clipscene.cpp 中,以下img1
代表裁剪后的图像 A,img2
代表图像 B(当前也未存储,也未通过)
void clipScene::on_acceptBtn_clicked()
// .....operations...
// This will save the cropped Image A successfully
QPixmap img1;
img1.convertFromImage(simg);
QByteArray img1Array;
QBuffer buffer1(&img1Array);
buffer1.open(QIODevice::WriteOnly);
img1.save(&buffer1, "PNG");
returnData.mSave = img1Array;
// This will save a different Image B
// But here the compiler says that no arguments are being passed
QPixmap img2;
QByteArray img2Array;
QBuffer buffer2(&img2Array);
buffer2.open(QIODevice::WriteOnly);
img2.save(&buffer2, "PNG");
returnData.mClassImg = img2Array;
最后,当所有信息都传递并存储在 QTableView 上时,我可以双击 QTableView 的一行,我之前用于手动存储数据的相同对话框将弹出,其中记录了所有信息和两个图像(图 A和图 B)。 在 MainWindow (以及连接错误的位置)上执行此操作的代码部分如下:
void MainWindow::onTableClick(const QModelIndex &index)
int row = index.row();
SelectionData currentData;
currentData.mName = index.sibling(row, 1).data().toString();
// ....additional data....
// ....additional data...
currentData.mSave = index.sibling(row, 17).data().toByteArray();
currentData.mClassImg = index.sibling(row, 18).data().toByteArray();
QPixmap iconPix;
if(!iconPix.loadFromData(index.sibling(row, 17).data().toByteArray()))
QPixmap iconPix2;
if(!iconPix2.loadFromData(index.sibling(row, 18).data().toByteArray()))
clipScene d(this);
d.setData(currentData);
d.setImage(iconPix.toImage());
d.setClassifiedImage(iconPix2.toImage());
// ....additional operations....
我已经为这个问题苦苦挣扎了几天,任何能对此有所了解或提供解决方案的人都会很棒。
【问题讨论】:
【参考方案1】:我不确定这对您是否仍然有用,但由于我遇到了同样的问题,这可能会有所帮助。我认为您永远不会将图像传递给目标表。你有没有加载图像?你有没有做过这样的事情:
clipscene.h
private:
QList<QGraphicsPixmapItem*> leftClipPix;
clipscene.cpp
void clipScene::load_classifiedImageFromDb(QImage image)
clasImg = image;
QGraphicsPixmapItem* item = new QGraphicsPixmapItem(QPixmap::fromImage(image));
leftClipPix.append(item);
workingImageScene->addItem(item);
ui->yourgraphicsView->show();
ui->yourgraphicsView->setSceneRect(QRectF(0, 0, image.width(), image.height()));
此外,如您所说,如果您尝试从桌面或数据库上传图像,那么执行以下操作可能会很有用:
void clipScene::load_classifiedImage()
QString dir = QFileDialog::getOpenFileName(this, tr("Open image directory"), "", tr("Images (*.tif *.jpg *.png *.jpeg *.bmp *.gif *.tiff)"));
QImage image;
if(QString::compare(dir, QString()) != 0)
image = QImage(dir);
QGraphicsPixmapItem* item = new QGraphicsPixmapItem(QPixmap::fromImage(image));
leftClipPix.append(item);
workingImageScene->addItem(item);
ui->yourgraphicsView->show();
ui->yourgraphicsView->setSceneRect(QRectF(0, 0, image.width(), image.height()));
clasImg = image;
并将load_classifiedImage()
函数传递给QPushButton
【讨论】:
感谢您的回答,但我已经解决了这个问题。我会将您的答案标记为正确,因为我是按照您建议的方式进行的。以上是关于如何在 QTableView 上存储图像(Qt 和 openCV)的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Qt 的 QTableview 中找到我的按钮的行号
pyqt qt4 QTableView 如何禁用某些列的排序?
如何强制调整 indexWidgets 的大小以适合 Qt5 QTableView 的单元格