Upgrades :

- The dialog won't let the user create an image if its size doesn't match the file's
- the offset is counted in the images's size
- the fields of the dialog have tooltips
- If the raw_image has a WK_FLOAT, the image is automatically detected as gray-level
- Images can be saved in .inr.gz

Remaining : convert images to the right format to be meshed when asked to.
This commit is contained in:
Maxime Gimeno 2016-10-06 09:27:32 +02:00
parent f4a29597e4
commit 2f7ccf76eb
6 changed files with 272 additions and 151 deletions

View File

@ -856,7 +856,6 @@ _image* _readNonInterlacedImage(const char *name) {
on stdout */
CGAL_INLINE_FUNCTION
int _writeImage(_image *im, const char *name_to_be_written ) {
int r = ImageIO_NO_ERROR;
std::size_t length = 0;
char *name = NULL;

View File

@ -164,11 +164,16 @@ public:
const double vx = 1,
const double vy = 1,
const double vz = 1,
const unsigned int offset = 0)
const unsigned int offset = 0,
std::size_t wdim=1,
WORD_KIND wk = WK_FIXED,
SIGN sign = SGN_UNSIGNED
)
{
return private_read(::_readImage_raw(file,
rx,ry,rz,
vx,vy,vz,offset));
vx,vy,vz,offset,
wdim, wk, sign));
}
public:

View File

@ -12,6 +12,7 @@
#include "ui_Image_res_dialog.h"
#include <CGAL/Image_3.h>
#include <CGAL/ImageIO.h>
#include <CGAL/Three/Polyhedron_demo_plugin_helper.h>
#include <CGAL/Three/Polyhedron_demo_plugin_interface.h>
#include <CGAL/Three/Scene_interface.h>
@ -34,6 +35,7 @@
#include <QString>
#include <QFontMetrics>
#include <QFileDialog>
#include <QPushButton>
#include <cassert>
#include <iostream>
@ -210,6 +212,7 @@ public:
this->message_interface = mi;
this->scene = scene_interface;
this->mw = mainWindow;
this->is_gray = false;
x_control = NULL;
y_control = NULL;
z_control = NULL;
@ -274,7 +277,12 @@ public:
CGAL::Three::Scene_item* load(QFileInfo fileinfo);
bool canSave(const CGAL::Three::Scene_item*);
bool save(const CGAL::Three::Scene_item*, QFileInfo) { return false; }
bool save(const CGAL::Three::Scene_item* item, QFileInfo fi) {
const Scene_image_item* im_item = qobject_cast<const Scene_image_item*>(item);
point_image p_im = *im_item->image()->image();
return _writeImage(&p_im, fi.filePath().toUtf8()) == 0;
}
QString name() const { return "segmented images"; }
@ -439,6 +447,7 @@ private:
vtkDemandDrivenPipeline* executive;
vtkImageGaussianSmooth* smoother;
#endif // CGAL_USE_VTK
bool is_gray;
Messages_interface* message_interface;
QMessageBox msgBox;
QAction* planeSwitch;
@ -816,17 +825,24 @@ Io_image_plugin::load(QFileInfo fileinfo) {
if(qmb.exec() == QMessageBox::Yes) {
Raw_image_dialog raw_dialog;
raw_dialog.label_file_size->setText(QString("%1 B").arg(fileinfo.size()));
raw_dialog.buttonBox->button(QDialogButtonBox::Open)->setEnabled(false);
if( raw_dialog.exec() ){
QApplication::setOverrideCursor(Qt::WaitCursor);
if(image->read_raw(fileinfo.filePath().toUtf8(),
raw_dialog.dim_x->value(),
raw_dialog.dim_y->value(),
raw_dialog.dim_z->value(),
raw_dialog.spacing_x->value(),
raw_dialog.spacing_y->value(),
raw_dialog.spacing_z->value(),
raw_dialog.offset->value())){
raw_dialog.dim_x->value(),
raw_dialog.dim_y->value(),
raw_dialog.dim_z->value(),
raw_dialog.spacing_x->value(),
raw_dialog.spacing_y->value(),
raw_dialog.spacing_z->value(),
raw_dialog.offset->value(),
raw_dialog.image_word_size(),
raw_dialog.image_word_kind(),
raw_dialog.image_sign())
){
is_gray = (raw_dialog.image_word_kind() == WK_FLOAT);
QSettings settings;
settings.beginGroup(QUrl::toPercentEncoding(fileinfo.absoluteFilePath()));
settings.setValue("is_raw", true);
@ -837,6 +853,9 @@ Io_image_plugin::load(QFileInfo fileinfo) {
settings.setValue("spacing_y", raw_dialog.spacing_y->value());
settings.setValue("spacing_z", raw_dialog.spacing_z->value());
settings.setValue("offset", raw_dialog.offset->value());
settings.setValue("wdim", QVariant::fromValue(raw_dialog.image_word_size()));
settings.setValue("wk", raw_dialog.image_word_kind());
settings.setValue("sign", raw_dialog.image_sign());
settings.endGroup();
}else {
success = false;
@ -845,7 +864,7 @@ Io_image_plugin::load(QFileInfo fileinfo) {
success = false;
}
}else {
success = false;
success = false;
}
if(!success){
delete image;
@ -855,13 +874,13 @@ Io_image_plugin::load(QFileInfo fileinfo) {
// Get display precision
QDialog dialog;
ui.setupUi(&dialog);
connect(ui.buttonBox, SIGNAL(accepted()), &dialog, SLOT(accept()));
connect(ui.buttonBox, SIGNAL(rejected()), &dialog, SLOT(reject()));
connect(ui.imageType, SIGNAL(currentIndexChanged(int)),
this, SLOT(on_imageType_changed(int)));
dialog.setWindowFlags(Qt::Dialog|Qt::CustomizeWindowHint|Qt::WindowCloseButtonHint);
// Add precision values to the dialog
for ( int i=1 ; i<9 ; ++i )
{
@ -873,22 +892,29 @@ Io_image_plugin::load(QFileInfo fileinfo) {
ui.imageType->addItem(QString("Segmented image"));
ui.imageType->addItem(QString("Gray-level image"));
QString type;
int voxel_scale;
// Open window
QApplication::restoreOverrideCursor();
int return_code = dialog.exec();
if(return_code != QDialog::Accepted)
if(!is_gray)
{
delete image;
return NULL;
}
QApplication::setOverrideCursor(Qt::WaitCursor);
// Get selected precision
int voxel_scale = ui.precisionList->currentIndex() + 1;
int return_code = dialog.exec();
if(return_code != QDialog::Accepted)
{
delete image;
return NULL;
}
// Get selected precision
voxel_scale = ui.precisionList->currentIndex() + 1;
//Get the image type
type = ui.imageType->currentText();
}
else
type = "Gray-level image";
QApplication::setOverrideCursor(Qt::WaitCursor);
//Get the image type
QString type = ui.imageType->currentText();
Scene_image_item* image_item;
if(type == "Gray-level image")
{
@ -907,9 +933,9 @@ Io_image_plugin::load(QFileInfo fileinfo) {
return image_item;
}
bool Io_image_plugin::canSave(const CGAL::Three::Scene_item*)
bool Io_image_plugin::canSave(const CGAL::Three::Scene_item* item)
{
return false;
return qobject_cast<const Scene_image_item*>(item);
}
bool Io_image_plugin::loadDCM(QString dirname)

View File

@ -1,19 +1,27 @@
#include "Raw_image_dialog.h"
#include <QPushButton>
Raw_image_dialog::Raw_image_dialog(QWidget* parent)
: QDialog(parent)
: QDialog(parent)
{
setupUi(this);
}
void Raw_image_dialog::update_image_size() {
label_image_size->setNum((int)image_word_size() *
dim_x->value() *
dim_y->value() *
dim_z->value());
int size = (int)image_word_size() *
dim_x->value() *
dim_y->value() *
dim_z->value() +
offset->value();
label_image_size->setText(QString("%1 B").arg(size));
if(label_image_size->text() == label_file_size->text())
buttonBox->button(QDialogButtonBox::Open)->setEnabled(true);
else
buttonBox->button(QDialogButtonBox::Open)->setEnabled(false);
}
unsigned int Raw_image_dialog::image_word_size() const {
std::size_t Raw_image_dialog::image_word_size() const {
if(short_bt->isChecked())
return 2;
if(int_bt->isChecked())
@ -26,3 +34,18 @@ unsigned int Raw_image_dialog::image_word_size() const {
return 1;
}
WORD_KIND Raw_image_dialog::image_word_kind() const
{
if(float_bt->isChecked() ||
double_bt->isChecked())
return WK_FLOAT;
else
return WK_FIXED;
}
SIGN Raw_image_dialog::image_sign() const
{
if(signed_bt->isChecked())
return SGN_SIGNED;
else
return SGN_UNSIGNED;
}

View File

@ -2,6 +2,7 @@
#define RAW_IMAGE_DIALOG_H
#include "ui_raw_image.h"
#include <CGAL/ImageIO.h>
class Raw_image_dialog : public QDialog, public Ui::Raw_image_dialog
{
@ -10,7 +11,9 @@ class Raw_image_dialog : public QDialog, public Ui::Raw_image_dialog
public:
Raw_image_dialog(QWidget* parent = 0);
unsigned int image_word_size() const;
std::size_t image_word_size() const;
WORD_KIND image_word_kind() const;
SIGN image_sign() const;
private Q_SLOTS:
void update_image_size();

View File

@ -1,7 +1,8 @@
<ui version="4.0" >
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Raw_image_dialog</class>
<widget class="QDialog" name="Raw_image_dialog" >
<property name="geometry" >
<widget class="QDialog" name="Raw_image_dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
@ -9,54 +10,72 @@
<height>342</height>
</rect>
</property>
<property name="windowTitle" >
<property name="windowTitle">
<string>Open raw image</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout" >
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBox_2" >
<property name="title" >
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Image &amp;value type</string>
</property>
<layout class="QGridLayout" name="gridLayout" >
<item row="2" column="0" >
<widget class="QRadioButton" name="short_bt" >
<property name="text" >
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="0">
<widget class="QRadioButton" name="short_bt">
<property name="toolTip">
<string>Word kind of the image : short int.</string>
</property>
<property name="text">
<string>Short (16 bits)</string>
</property>
</widget>
</item>
<item row="3" column="0" >
<widget class="QRadioButton" name="float_bt" >
<property name="text" >
<item row="3" column="0">
<widget class="QRadioButton" name="float_bt">
<property name="toolTip">
<string>Word kind of the image : float.</string>
</property>
<property name="text">
<string>Float</string>
</property>
</widget>
</item>
<item row="0" column="1" >
<widget class="QRadioButton" name="int_bt" >
<property name="text" >
<item row="0" column="1">
<widget class="QRadioButton" name="int_bt">
<property name="toolTip">
<string>Word kind of the image : integer.</string>
</property>
<property name="text">
<string>Int (32 bits)</string>
</property>
</widget>
</item>
<item row="3" column="1" >
<widget class="QRadioButton" name="double_bt" >
<property name="text" >
<item row="3" column="1">
<widget class="QRadioButton" name="double_bt">
<property name="toolTip">
<string>Word kind of the image : double.</string>
</property>
<property name="text">
<string>Double</string>
</property>
</widget>
</item>
<item row="2" column="1" >
<widget class="QCheckBox" name="signed_bt" >
<property name="text" >
<item row="2" column="1">
<widget class="QCheckBox" name="signed_bt">
<property name="toolTip">
<string>Specifies if the image's word kind is signed.</string>
</property>
<property name="text">
<string>Signed</string>
</property>
</widget>
</item>
<item row="0" column="0" >
<widget class="QRadioButton" name="char_bt" >
<property name="text" >
<item row="0" column="0">
<widget class="QRadioButton" name="char_bt">
<property name="toolTip">
<string>Word kind of the image : unsigned byte.</string>
</property>
<property name="text">
<string>char (8 bits)</string>
</property>
</widget>
@ -65,161 +84,191 @@
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox" >
<property name="title" >
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Image dimensions</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2" >
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QGridLayout" >
<item row="0" column="0" >
<widget class="QLabel" name="label_dim" >
<property name="text" >
<layout class="QGridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_dim">
<property name="toolTip">
<string>Number of voxel along the axis.</string>
</property>
<property name="text">
<string>&amp;Dimensions:</string>
</property>
<property name="alignment" >
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy" >
<property name="buddy">
<cstring>dim_x</cstring>
</property>
</widget>
</item>
<item row="2" column="0" >
<widget class="QLabel" name="label_spacing" >
<property name="text" >
<item row="2" column="0">
<widget class="QLabel" name="label_spacing">
<property name="toolTip">
<string>Changing those values will scale the image according to the proportions between vx, vy and vz.</string>
</property>
<property name="text">
<string>&amp;Spacing:</string>
</property>
<property name="alignment" >
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy" >
<property name="buddy">
<cstring>spacing_x</cstring>
</property>
</widget>
</item>
<item row="0" column="1" >
<widget class="QSpinBox" name="dim_x" >
<property name="prefix" >
<item row="0" column="1">
<widget class="QSpinBox" name="dim_x">
<property name="toolTip">
<string>Number of voxels along the X axis.</string>
</property>
<property name="prefix">
<string>x: </string>
</property>
<property name="maximum" >
<property name="maximum">
<number>100000000</number>
</property>
</widget>
</item>
<item row="0" column="2" >
<widget class="QSpinBox" name="dim_y" >
<property name="prefix" >
<item row="0" column="2">
<widget class="QSpinBox" name="dim_y">
<property name="toolTip">
<string>Number of voxels along the Y axis.</string>
</property>
<property name="prefix">
<string>y: </string>
</property>
<property name="maximum" >
<property name="maximum">
<number>100000000</number>
</property>
</widget>
</item>
<item row="0" column="3" >
<widget class="QSpinBox" name="dim_z" >
<property name="prefix" >
<item row="0" column="3">
<widget class="QSpinBox" name="dim_z">
<property name="toolTip">
<string>Number of voxels along the Z axis.</string>
</property>
<property name="prefix">
<string>z: </string>
</property>
<property name="maximum" >
<property name="maximum">
<number>100000000</number>
</property>
</widget>
</item>
<item row="2" column="1" >
<widget class="QDoubleSpinBox" name="spacing_x" >
<property name="prefix" >
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="spacing_x">
<property name="toolTip">
<string>Voxel size in x.</string>
</property>
<property name="prefix">
<string>vx: </string>
</property>
<property name="decimals" >
<property name="decimals">
<number>5</number>
</property>
<property name="value" >
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="2" column="2" >
<widget class="QDoubleSpinBox" name="spacing_y" >
<property name="prefix" >
<item row="2" column="2">
<widget class="QDoubleSpinBox" name="spacing_y">
<property name="toolTip">
<string>Voxel size in y.</string>
</property>
<property name="prefix">
<string>vy: </string>
</property>
<property name="decimals" >
<property name="decimals">
<number>5</number>
</property>
<property name="value" >
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="2" column="3" >
<widget class="QDoubleSpinBox" name="spacing_z" >
<property name="prefix" >
<item row="2" column="3">
<widget class="QDoubleSpinBox" name="spacing_z">
<property name="toolTip">
<string>Voxel size in z.</string>
</property>
<property name="prefix">
<string>vz: </string>
</property>
<property name="decimals" >
<property name="decimals">
<number>5</number>
</property>
<property name="value" >
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="3" column="0" >
<widget class="QLabel" name="offset_label" >
<property name="text" >
<item row="3" column="0">
<widget class="QLabel" name="offset_label">
<property name="toolTip">
<string>Specifies how many bytes must be skipped before reading the data. (Use it to skip unhandled headers fo example)</string>
</property>
<property name="text">
<string>&amp;Offset:</string>
</property>
<property name="alignment" >
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy" >
<property name="buddy">
<cstring>offset</cstring>
</property>
</widget>
</item>
<item row="3" column="1" >
<widget class="QSpinBox" name="offset" >
<property name="suffix" >
<item row="3" column="1">
<widget class="QSpinBox" name="offset">
<property name="toolTip">
<string>Specifies how many bytes must be skipped before reading the data. (Use it to skip unhandled headers fo example)</string>
</property>
<property name="suffix">
<string> bytes</string>
</property>
<property name="maximum" >
<property name="maximum">
<number>999999999</number>
</property>
</widget>
</item>
<item row="1" column="0" >
<widget class="QLabel" name="imagesize_budy" >
<property name="text" >
<item row="1" column="0">
<widget class="QLabel" name="imagesize_budy">
<property name="text">
<string>Image size:</string>
</property>
<property name="alignment" >
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="1" >
<widget class="QLabel" name="label_image_size" >
<property name="text" >
<item row="1" column="1">
<widget class="QLabel" name="label_image_size">
<property name="text">
<string>0</string>
</property>
</widget>
</item>
<item row="1" column="2" >
<widget class="QLabel" name="filesize_budy" >
<property name="text" >
<item row="1" column="2">
<widget class="QLabel" name="filesize_budy">
<property name="text">
<string>File size:</string>
</property>
<property name="alignment" >
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="3" >
<widget class="QLabel" name="label_file_size" >
<property name="text" >
<item row="1" column="3">
<widget class="QLabel" name="label_file_size">
<property name="text">
<string>0</string>
</property>
</widget>
@ -230,8 +279,8 @@
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox" >
<property name="standardButtons" >
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Open</set>
</property>
</widget>
@ -261,11 +310,11 @@
<receiver>signed_bt</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<hint type="sourcelabel">
<x>47</x>
<y>112</y>
</hint>
<hint type="destinationlabel" >
<hint type="destinationlabel">
<x>553</x>
<y>94</y>
</hint>
@ -277,11 +326,11 @@
<receiver>signed_bt</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<hint type="sourcelabel">
<x>564</x>
<y>127</y>
</hint>
<hint type="destinationlabel" >
<hint type="destinationlabel">
<x>564</x>
<y>94</y>
</hint>
@ -293,11 +342,11 @@
<receiver>Raw_image_dialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel" >
<hint type="sourcelabel">
<x>191</x>
<y>316</y>
</hint>
<hint type="destinationlabel" >
<hint type="destinationlabel">
<x>183</x>
<y>313</y>
</hint>
@ -309,11 +358,11 @@
<receiver>Raw_image_dialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel" >
<hint type="sourcelabel">
<x>253</x>
<y>319</y>
</hint>
<hint type="destinationlabel" >
<hint type="destinationlabel">
<x>252</x>
<y>312</y>
</hint>
@ -325,11 +374,11 @@
<receiver>Raw_image_dialog</receiver>
<slot>update_image_size()</slot>
<hints>
<hint type="sourcelabel" >
<hint type="sourcelabel">
<x>178</x>
<y>187</y>
</hint>
<hint type="destinationlabel" >
<hint type="destinationlabel">
<x>99</x>
<y>141</y>
</hint>
@ -341,11 +390,11 @@
<receiver>Raw_image_dialog</receiver>
<slot>update_image_size()</slot>
<hints>
<hint type="sourcelabel" >
<hint type="sourcelabel">
<x>473</x>
<y>178</y>
</hint>
<hint type="destinationlabel" >
<hint type="destinationlabel">
<x>441</x>
<y>142</y>
</hint>
@ -357,11 +406,11 @@
<receiver>Raw_image_dialog</receiver>
<slot>update_image_size()</slot>
<hints>
<hint type="sourcelabel" >
<hint type="sourcelabel">
<x>71</x>
<y>52</y>
</hint>
<hint type="destinationlabel" >
<hint type="destinationlabel">
<x>137</x>
<y>3</y>
</hint>
@ -373,11 +422,11 @@
<receiver>Raw_image_dialog</receiver>
<slot>update_image_size()</slot>
<hints>
<hint type="sourcelabel" >
<hint type="sourcelabel">
<x>117</x>
<y>81</y>
</hint>
<hint type="destinationlabel" >
<hint type="destinationlabel">
<x>49</x>
<y>6</y>
</hint>
@ -389,11 +438,11 @@
<receiver>Raw_image_dialog</receiver>
<slot>update_image_size()</slot>
<hints>
<hint type="sourcelabel" >
<hint type="sourcelabel">
<x>137</x>
<y>111</y>
</hint>
<hint type="destinationlabel" >
<hint type="destinationlabel">
<x>67</x>
<y>-5</y>
</hint>
@ -405,11 +454,11 @@
<receiver>Raw_image_dialog</receiver>
<slot>update_image_size()</slot>
<hints>
<hint type="sourcelabel" >
<hint type="sourcelabel">
<x>358</x>
<y>49</y>
</hint>
<hint type="destinationlabel" >
<hint type="destinationlabel">
<x>584</x>
<y>52</y>
</hint>
@ -421,11 +470,11 @@
<receiver>Raw_image_dialog</receiver>
<slot>update_image_size()</slot>
<hints>
<hint type="sourcelabel" >
<hint type="sourcelabel">
<x>332</x>
<y>186</y>
</hint>
<hint type="destinationlabel" >
<hint type="destinationlabel">
<x>271</x>
<y>142</y>
</hint>
@ -437,16 +486,32 @@
<receiver>Raw_image_dialog</receiver>
<slot>update_image_size()</slot>
<hints>
<hint type="sourcelabel" >
<hint type="sourcelabel">
<x>514</x>
<y>119</y>
</hint>
<hint type="destinationlabel" >
<hint type="destinationlabel">
<x>581</x>
<y>116</y>
</hint>
</hints>
</connection>
<connection>
<sender>offset</sender>
<signal>valueChanged(int)</signal>
<receiver>Raw_image_dialog</receiver>
<slot>update_image_size()</slot>
<hints>
<hint type="sourcelabel">
<x>225</x>
<y>278</y>
</hint>
<hint type="destinationlabel">
<x>292</x>
<y>170</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>update_image_size()</slot>