39 const double ImageViewerWidget::kZoomFactor = 1.20;
42 setSceneRect(0, 0, 0, 0);
43 image_pixmap_item_ = addPixmap(QPixmap::fromImage(QImage()));
44 image_pixmap_item_->setZValue(-1);
48 return image_pixmap_item_;
52 setWindowFlags(Qt::Window | Qt::WindowTitleHint |
53 Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint |
54 Qt::WindowCloseButtonHint);
56 resize(parent->width() - 20, parent->height() - 20);
59 font.setPointSize(10);
65 graphics_view_ =
new QGraphicsView();
66 graphics_view_->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
68 graphics_view_->setScene(&graphics_scene_);
69 graphics_view_->setAlignment(Qt::AlignLeft | Qt::AlignTop);
75 QPushButton* zoom_in_button =
new QPushButton(
"+",
this);
76 zoom_in_button->setFont(font);
77 zoom_in_button->setFixedWidth(50);
79 connect(zoom_in_button, &QPushButton::released,
this,
82 QPushButton* zoom_out_button =
new QPushButton(
"-",
this);
83 zoom_out_button->setFont(font);
84 zoom_out_button->setFixedWidth(50);
86 connect(zoom_out_button, &QPushButton::released,
this,
89 QPushButton* save_button =
new QPushButton(
"Save image",
this);
90 save_button->setFont(font);
98 QWidget::resizeEvent(
event);
100 graphics_view_->fitInView(graphics_scene_.sceneRect(), Qt::KeepAspectRatio);
113 graphics_scene_.setSceneRect(pixmap.rect());
116 graphics_view_->fitInView(graphics_scene_.sceneRect(), Qt::KeepAspectRatio);
124 std::cerr <<
"ERROR: Cannot read image at path " <<
path <<
std::endl;
131 graphics_view_->scale(kZoomFactor, kZoomFactor);
135 graphics_view_->scale(1.0 / kZoomFactor, 1.0 / kZoomFactor);
139 QString filter(
"PNG (*.png)");
140 const QString save_path =
141 QFileDialog::getSaveFileName(
this, tr(
"Select destination..."),
"",
142 "PNG (*.png);;JPEG (*.jpg);;BMP (*.bmp)",
148 if (save_path ==
"") {
156 QWidget* parent,
const std::string& switch_text)
159 switch_text_(switch_text) {
169 const std::vector<char>& tri_mask) {
172 std::cerr <<
"ERROR: Cannot read image at path " <<
path <<
std::endl;
178 const size_t num_tri_keypoints = std::count_if(
179 tri_mask.begin(), tri_mask.end(), [](
const bool tri) { return tri; });
184 size_t i_not_tri = 0;
185 for (
size_t i = 0; i < tri_mask.size(); ++i) {
187 keypoints_tri[i_tri] = keypoints[i];
190 keypoints_not_tri[i_not_tri] = keypoints[i];
206 const std::string& path1,
const std::string& path2,
211 if (!bitmap1.
Read(path1,
true) || !bitmap2.
Read(path2,
true)) {
212 std::cerr <<
"ERROR: Cannot read images at paths " << path1 <<
" and "
246 model_viewer_widget_(model_viewer_widget),
248 setWindowTitle(
"Image information");
250 table_widget_ =
new QTableWidget(
this);
251 table_widget_->setColumnCount(2);
252 table_widget_->setRowCount(11);
255 font.setPointSize(10);
256 table_widget_->setFont(font);
260 table_widget_->setEditTriggers(QAbstractItemView::NoEditTriggers);
261 table_widget_->setSelectionMode(QAbstractItemView::SingleSelection);
262 table_widget_->setShowGrid(
true);
264 table_widget_->horizontalHeader()->setStretchLastSection(
true);
265 table_widget_->horizontalHeader()->setVisible(
false);
266 table_widget_->verticalHeader()->setVisible(
false);
267 table_widget_->verticalHeader()->setDefaultSectionSize(18);
271 table_widget_->setItem(table_row, 0,
new QTableWidgetItem(
"image_id"));
272 image_id_item_ =
new QTableWidgetItem();
273 table_widget_->setItem(table_row, 1, image_id_item_);
276 table_widget_->setItem(table_row, 0,
new QTableWidgetItem(
"camera_id"));
277 camera_id_item_ =
new QTableWidgetItem();
278 table_widget_->setItem(table_row, 1, camera_id_item_);
281 table_widget_->setItem(table_row, 0,
new QTableWidgetItem(
"camera_model"));
282 camera_model_item_ =
new QTableWidgetItem();
283 table_widget_->setItem(table_row, 1, camera_model_item_);
286 table_widget_->setItem(table_row, 0,
new QTableWidgetItem(
"camera_params"));
287 camera_params_item_ =
new QTableWidgetItem();
288 table_widget_->setItem(table_row, 1, camera_params_item_);
291 table_widget_->setItem(table_row, 0,
new QTableWidgetItem(
"qw, qx, qy, qz"));
292 qvec_item_ =
new QTableWidgetItem();
293 table_widget_->setItem(table_row, 1, qvec_item_);
296 table_widget_->setItem(table_row, 0,
new QTableWidgetItem(
"tx, ty, tz"));
297 tvec_item_ =
new QTableWidgetItem();
298 table_widget_->setItem(table_row, 1, tvec_item_);
301 table_widget_->setItem(table_row, 0,
new QTableWidgetItem(
"dims"));
302 dimensions_item_ =
new QTableWidgetItem();
303 table_widget_->setItem(table_row, 1, dimensions_item_);
306 table_widget_->setItem(table_row, 0,
new QTableWidgetItem(
"num_points2D"));
307 num_points2D_item_ =
new QTableWidgetItem();
308 num_points2D_item_->setForeground(
Qt::red);
309 table_widget_->setItem(table_row, 1, num_points2D_item_);
312 table_widget_->setItem(table_row, 0,
new QTableWidgetItem(
"num_points3D"));
313 num_points3D_item_ =
new QTableWidgetItem();
315 table_widget_->setItem(table_row, 1, num_points3D_item_);
318 table_widget_->setItem(table_row, 0,
319 new QTableWidgetItem(
"num_observations"));
320 num_obs_item_ =
new QTableWidgetItem();
321 table_widget_->setItem(table_row, 1, num_obs_item_);
324 table_widget_->setItem(table_row, 0,
new QTableWidgetItem(
"name"));
325 name_item_ =
new QTableWidgetItem();
326 table_widget_->setItem(table_row, 1, name_item_);
331 delete_button_ =
new QPushButton(tr(
"Delete"),
this);
332 delete_button_->setFont(font);
334 connect(delete_button_, &QPushButton::released,
this,
335 &DatabaseImageViewerWidget::DeleteImage);
339 if (model_viewer_widget_->
images.count(image_id) == 0) {
343 image_id_ = image_id;
348 image_id_item_->setText(QString::number(image_id));
349 camera_id_item_->setText(QString::number(
image.CameraId()));
350 camera_model_item_->setText(QString::fromStdString(camera.
ModelName()));
351 camera_params_item_->setText(QString::fromStdString(camera.
ParamsToString()));
352 qvec_item_->setText(QString::number(
image.Qvec(0)) +
", " +
353 QString::number(
image.Qvec(1)) +
", " +
354 QString::number(
image.Qvec(2)) +
", " +
355 QString::number(
image.Qvec(3)));
356 tvec_item_->setText(QString::number(
image.Tvec(0)) +
", " +
357 QString::number(
image.Tvec(1)) +
", " +
358 QString::number(
image.Tvec(2)));
359 dimensions_item_->setText(QString::number(camera.
Width()) +
"x" +
360 QString::number(camera.
Height()));
361 num_points2D_item_->setText(QString::number(
image.NumPoints2D()));
363 std::vector<char> tri_mask(
image.NumPoints2D());
364 for (
size_t i = 0; i <
image.NumPoints2D(); ++i) {
365 tri_mask[i] =
image.Point2D(i).HasPoint3D();
368 num_points3D_item_->setText(QString::number(
image.NumPoints3D()));
369 num_obs_item_->setText(QString::number(
image.NumObservations()));
370 name_item_->setText(QString::fromStdString(
image.Name()));
376 keypoints[i].x =
static_cast<float>(
image.Point2D(i).X());
377 keypoints[i].y =
static_cast<float>(
image.Point2D(i).Y());
384 void DatabaseImageViewerWidget::ResizeTable() {
386 table_widget_->resizeColumnsToContents();
387 int height = table_widget_->horizontalHeader()->height() +
388 2 * table_widget_->frameWidth();
389 for (
int i = 0; i < table_widget_->rowCount(); i++) {
390 height += table_widget_->rowHeight(i);
392 table_widget_->setFixedHeight(
height);
395 void DatabaseImageViewerWidget::DeleteImage() {
396 QMessageBox::StandardButton reply = QMessageBox::question(
397 this,
"", tr(
"Do you really want to delete this image?"),
398 QMessageBox::Yes | QMessageBox::No);
399 if (reply == QMessageBox::Yes) {
std::shared_ptr< core::Tensor > image
bool Read(const std::string &path, const bool as_rgb=true)
std::string ModelName() const
std::string ParamsToString() const
ImageViewerGraphicsScene()
QGraphicsPixmapItem * ImagePixmapItem() const
std::shared_ptr< std::string > image_path
void DeRegisterImage(const image_t image_id)
bool ExistsImage(const image_t image_id) const
QTextStream & endl(QTextStream &stream)
Tensor Minimum(const Tensor &input, const Tensor &other)
Computes the element-wise minimum of input and other. The tensors must have same data type and device...
static const std::string path
QPixmap DrawMatches(const QPixmap &image1, const QPixmap &image2, const FeatureKeypoints &points1, const FeatureKeypoints &points2, const FeatureMatches &matches, const QColor &keypoints_color)
QImage BitmapToQImageRGB(const Bitmap &bitmap)
void DrawKeypoints(QPixmap *pixmap, const FeatureKeypoints &points, const QColor &color)
std::string JoinPaths(T const &... paths)
std::vector< FeatureKeypoint > FeatureKeypoints
std::vector< FeatureMatch > FeatureMatches
QPixmap ShowImagesSideBySide(const QPixmap &image1, const QPixmap &image2)
constexpr Rgb magenta(MAX, 0, MAX)
constexpr Rgb red(MAX, 0, 0)