diff --git a/app/Algorithms/DCT.h b/app/Algorithms/DCT.h index ad7d26296985b6e6c4dcb39ad1ec550980bfdac5..17b651307acaebaeaeda2b8a8b0c4ef38d98efa4 100644 --- a/app/Algorithms/DCT.h +++ b/app/Algorithms/DCT.h @@ -20,7 +20,6 @@ #ifndef DCT_H #define DCT_H -#include "DCT.h" #include <Image.h> #include <string> diff --git a/app/Algorithms/Pyramid.cpp b/app/Algorithms/Pyramid.cpp index 6dabc89c18d1514abd1ccfd73b73be416a9b7385..532862d63bd1a65c5ce1565dda5fbbbbcbcdf333 100644 --- a/app/Algorithms/Pyramid.cpp +++ b/app/Algorithms/Pyramid.cpp @@ -24,6 +24,7 @@ #include <cstring> #include <cstdlib> #include <cmath> +#include <Converter.h> using namespace std; using namespace imagein; using namespace Pyramid; @@ -133,7 +134,7 @@ void Filters::getDefault( Filtre &to_fill ) { } /*--------------------------------------------------------------------------- - Cration de l'tage suivant de la pyramide Gaussienne + Creation de l'étage suivant de la pyramide Gaussienne ---------------------------------------------------------------------------*/ void Pyramid::etage_suiv_g(const uint8_t *srcTab, uint8_t *dstTab, int srcWidth, int srcHeight, Filtre &utile) { @@ -157,11 +158,12 @@ void Pyramid::etage_suiv_g(const uint8_t *srcTab, uint8_t *dstTab, int srcWidth, // dstTab[i + j * dstWidth] = intermed[i + 2 * j * dstWidth]; } } - delete intermed; +// delete intermed; + delete[] intermed; } /*--------------------------------------------------------------------------- - Cration d'une pyramide Gaussienne jusqu'au nime tage + Creation d'une pyramide Gaussienne jusqu'au n-ième étage ---------------------------------------------------------------------------*/ void Pyramid::pyram_g_n(uint8_t *rep, int nStage, long nbc, long nbl, const uint8_t *itab, Filtre &utile) { @@ -185,7 +187,7 @@ void Pyramid::pyram_g_n(uint8_t *rep, int nStage, long nbc, long nbl, const uint } /*--------------------------------------------------------------------------- - Creation d'une pyramide Laplacienne jusqu'au nime tage + Creation d'une pyramide Laplacienne jusqu'au n-ième étage ---------------------------------------------------------------------------*/ void Pyramid::pyram_l_n (uint8_t *rep,int n, long nbc, long nbl, const uint8_t *itab, Filtre &utile) { @@ -228,19 +230,19 @@ void Pyramid::pyram_l_n (uint8_t *rep,int n, long nbc, long nbl, const uint8_t * /*--------------------------------------------------------------------------- - Cration d'une pyramide Gaussienne avec entre en conversationnel - des diffrentes proprits de cette pyramide + Creation d'une pyramide Gaussienne avec entrée en conversationnel + des diffrentes propriétés de cette pyramide ---------------------------------------------------------------------------*/ Image *Pyramid::pyram_g(const GrayscaleImage *im, int etage_f, Filtre &utile, string &to_print) { if(!( im != NULL )) { - throw "Error in Pyramid::pyram_g:\nim = NULL"; + throw "Error : Image is NULL"; } if(!( im->getWidth() == im->getHeight() )) { - throw "Error in Pyramid::pyram_g:\nim->getWidth() != im->getHeight()"; + throw "Error : Image has different width and height"; } if( !isPowerOf2(im->getWidth()) ) { - throw "Error in Pyramid::pyram_g:\nimage dimensions not a power of 2"; + throw "Error : Image dimension is not a power of 2"; } long nbl = im->getHeight(); long nbc = im->getWidth(); @@ -263,7 +265,7 @@ Image *Pyramid::pyram_g(const GrayscaleImage *im, int etage_f, Filtre &utile, st return resImg; } /*--------------------------------------------------------------------------- - Cration d'un tage de la pyramide Gaussienne + Creation d'un étage de la pyramide Gaussienne ---------------------------------------------------------------------------*/ Image *Pyramid::n_pyram_g(const Image *im, int etage_f, Filtre &utile, std::string &to_print) { @@ -309,8 +311,8 @@ Image *Pyramid::n_pyram_g(const Image *im, int etage_f, Filtre &utile, std::stri return resImg; } /*--------------------------------------------------------------------------- - Cration d'une pyramide Laplacienne avec entre en conversationnel - des diffrentes proprits de cette pyramide + Creation d'une pyramide Laplacienne avec entrée en conversationnel + des diffrentes propriétés de cette pyramide ---------------------------------------------------------------------------*/ Image *Pyramid::pyram_l (const Image *im, int etage_f, Filtre &utile, string &to_print) { @@ -342,7 +344,7 @@ Image *Pyramid::pyram_l (const Image *im, int etage_f, Filtre &utile, string &to } /*--------------------------------------------------------------------------- - Cration d'un tage de la pyramide Laplacienne + Creation d'un étage de la pyramide Laplacienne ---------------------------------------------------------------------------*/ Image *Pyramid::n_pyram_l(const Image *im, int etage_f, Filtre &utile, std::string &to_print) { @@ -666,85 +668,87 @@ Image *Pyramid::rebuild_interface( const Image *pyramid, int etage_f, int pyrami // etage_f = stage that the original image was built to char buffer[255]; if(!pyramid) { - throw "Error in TP6Pyramid::rebuild_interface:\npyramid = NULL"; + throw "Error : Pyramid = NULL"; } if(pyramid->getWidth() * 2 != pyramid->getHeight()) { - sprintf( buffer, "Error in TP6Pyramid::rebuild_interface:\npyramid->getWidth = %d, pyramid->getHeight = %d", pyramid->getWidth(), pyramid->getHeight() ); + sprintf( buffer, "Error : Unsuitable size - pyramid->getWidth = %d, pyramid->getHeight = %d", pyramid->getWidth(), pyramid->getHeight()); throw buffer; } if(!(isPowerOf2(pyramid->getWidth()))) { - throw "Error in TP6Pyramid::rebuild_interface:\npyramid->getWidth not a power of 2"; + throw "Error : Height and width are not multiples of 2"; } if( etage_f <= 0 || (1 << etage_f) > pyramid->getWidth() ) { - throw "Error in TP6Pyramid::rebuild_interface:\nInvalid etage_f specified"; + throw "Error : Invalid etage_f specified"; } if(pyramid_to < 0 || pyramid_to >= etage_f) { - throw "Error in TP6Pyramid::rebuild_interface:\nInvalid pyramid_to specified"; + throw "Error : Rebuild pyramid should at a higher level"; } - long nbc = pyramid->getWidth(); - long nbl = pyramid->getWidth(); - int i; - int j=0; - int taille_c=nbc; - int taille_l=nbl; - Image *returnval = NULL; - int taille; - int q=0; - int etage_rec; - const uint8_t *pyra1 = pyramid->begin(); - uint8_t* intermed = new uint8_t[nbc * nbc / 2 * 3]; - uint8_t* rep = new uint8_t[nbc * nbc / 2 * 3]; - - // Copy info into rep in a packed format - long current_offset = 0; - long current_rep_offset = 0; - for(int n = 0; n <= etage_f; ++n) { - for(int j=0; j< taille_l; j++ ) { - for(int i=0; i< taille_c; i++ ) { - rep[current_rep_offset + j * taille_c + i] = pyra1[current_offset + j * pyramid->getWidth() + i]; - } - } - current_offset = current_offset + taille_l * nbc; - current_rep_offset = current_rep_offset + taille_l * taille_c; - taille_l = taille_l / 2; - taille_c = taille_c / 2; - } - -/* reconstruction de l'image partir de sa pyramide laplacienne en s'arretant - un niveau etage_rec choisi par l'utilisateur - La pyramide est contenue dans la zone mmoire pointe par rep */ - etage_rec = pyramid_to; - taille=nbc; - for(i=0;i<etage_f;i++) - { - q=q+taille*taille; - taille=taille/2; - } - for(i=q;i<q+taille*taille;i++) - { - *(intermed+i)=*(rep+i); - } - for(i=etage_f;i>etage_rec;i--) - { - agrandir((intermed+q),(intermed+q-taille*taille*4),taille,taille,utile); - taille=taille*2; - q=q-taille*taille; - for(j=q;j<q+taille*taille;j++) - { - int value = rep[j]; - if(value > 128) value = value - 256; - value = value + intermed[j]; - if(value < 0) value = 0; - if(value > 255) value = 255; - intermed[j] = value; - } - } - //printf("Entrez le nom du fichier de l'image reconstruite :"); - //scanf("%s",nom); - //ecrire_image((intermed+q),nom,taille,taille); - returnval = new GrayscaleImage(taille, taille, intermed+q); - free(intermed); - free(rep); - return returnval; -} + /*The reconstructed image has the same length and width*/ + long nbc = pyramid->getWidth(); + long nbl = pyramid->getWidth(); + int i; + int j=0; + int taille_c=nbc; + int taille_l=nbl; + Image *returnval = NULL; + int taille; + int q=0; + int etage_rec; + const uint8_t *pyra1 = pyramid->begin(); + uint8_t* intermed = new uint8_t[nbc * nbc / 2 * 3]; + uint8_t* rep = new uint8_t[nbc * nbc / 2 * 3]; + + // Copy info into rep in a packed format + long current_offset = 0; + long current_rep_offset = 0; + for(int n = 0; n <= etage_f; ++n) { + for(int j=0; j< taille_l; j++ ) { + for(int i=0; i< taille_c; i++ ) { + rep[current_rep_offset + j * taille_c + i] = pyra1[current_offset + j * pyramid->getWidth() + i]; + } + } + current_offset = current_offset + taille_l * nbc; + current_rep_offset = current_rep_offset + taille_l * taille_c; + taille_l = taille_l / 2; + taille_c = taille_c / 2; + } + + /* reconstruction de l'image partir de sa pyramide laplacienne en s'arretant + un niveau etage_rec choisi par l'utilisateur + La pyramide est contenue dans la zone mmoire pointe par rep */ + etage_rec = pyramid_to; + taille=nbc; + + for(i=0;i<etage_f;i++) + { + q=q+taille*taille; + taille=taille/2; + } + for(i=q;i<q+taille*taille;i++) + { + *(intermed+i)=*(rep+i); + } + for(i=etage_f;i>etage_rec;i--) + { + agrandir((intermed+q),(intermed+q-taille*taille*4),taille,taille,utile); + taille=taille*2; + q=q-taille*taille; + for(j=q;j<q+taille*taille;j++) + { + int value = rep[j]; + if(value > 128) value = value - 256; + value = value + intermed[j]; + if(value < 0) value = 0; + if(value > 255) value = 255; + intermed[j] = value; + } + } + //printf("Entrez le nom du fichier de l'image reconstruite :"); + //scanf("%s",nom); + //ecrire_image((intermed+q),nom,taille,taille); + returnval = new GrayscaleImage(taille, taille, intermed+q); + free(intermed); + free(rep); + return returnval; + } diff --git a/app/Algorithms/Pyramid.h b/app/Algorithms/Pyramid.h index f62dfb519801e27c3782e291faae0de3f49a001c..0d9eaae46eb442275d5620f46ed9772e1c6f6e06 100644 --- a/app/Algorithms/Pyramid.h +++ b/app/Algorithms/Pyramid.h @@ -52,8 +52,8 @@ namespace Pyramid * Size is the maximum index to search for coefficient in the coeff_f[] */ struct Filtre { - char nom_f[30]; //!< Name of the filter - float coeff_f[10]; //!< Coefficient of the filter + char nom_f[30]; //!< Name of the filter + float coeff_f[10]; //!< Coefficient of the filter int taille_f; //!< Size of the filter }; @@ -61,7 +61,7 @@ namespace Pyramid * \Class Filters * \Brief A class used for pyramid operation * - * This class regroup all all the filters possible in a tab + * This class regroup all the filters possible in a tab */ class Filters { @@ -290,6 +290,16 @@ namespace Pyramid */ std::string n_entropie_p(const uint8_t *pyra, int etage_f,int nbc,int nbl); + /** + * @brief Return the image reconstructed from a single layer in pyramide + * + * @param to_rebuild pyramid layer to rebuild + * @param etage_f number of level in the pyramid + * @param to_rebuild_to level to reconstruct + * @param utile filter to use + * @return imagein::Image* the output reconstructed image + */ + imagein::Image* rebuild_basic(const imagein::Image *layer, int etage_f, int to_rebuild_to, Filtre &utile ); /** * @brief Return the image reconstructed from a pyramide diff --git a/app/Operations/ClassResultOp.cpp b/app/Operations/ClassResultOp.cpp index 3ddb502a3cdf3ba9616f33b5dbc724b899839f47..cb3767b5483128e39642f3305cb36d2bb3a5cf71 100644 --- a/app/Operations/ClassResultOp.cpp +++ b/app/Operations/ClassResultOp.cpp @@ -55,10 +55,11 @@ void ClassResultOp::operator()(const imagein::Image* img, const std::map<const i borderBox->setSuffix(" px"); innerBox->setValue(8); borderBox->setValue(2); -// formLayout->insertRow(0, qApp->translate("ClassResult", "Critère de zone intérieure : "), innerBox); -// formLayout->insertRow(1, qApp->translate("ClassResult", "Critère de zone frontière : "), borderBox); - formLayout->insertRow(0, qApp->translate("ClassResult", "Largeur de couronne pour conserver la zone centrale : "), innerBox); - formLayout->insertRow(1, qApp->translate("ClassResult", "Largeur de couronne pour conserver la zone extérieure : "), borderBox); + formLayout->insertRow(0, qApp->translate("ClassResult", "Critère de zone intérieure : "), innerBox); + formLayout->insertRow(1, qApp->translate("ClassResult", "Critère de zone frontière : "), borderBox); + innerBox->setWhatsThis(qApp->translate("ClassResult", "Largeur de couronne pour conserver la zone intérieure")); + borderBox->setWhatsThis(qApp->translate("ClassResult", "Largeur de couronne pour conserver la zone frontière")); + layout->addWidget(new QLabel(qApp->translate("ClassResult", "<b>Critère de zones (relatifs aux zones totales) : </b>"))); layout->addLayout(formLayout); layout->addWidget(new QLabel(qApp->translate("ClassResult", "<b>Select the image's classes zones : </b>"))); @@ -78,12 +79,15 @@ void ClassResultOp::operator()(const imagein::Image* img, const std::map<const i // int param2 = 8; /*The input parameters are not used*/ int param1 = borderBox->value(); + /*int paramBorderBox = borderBox->value();*/ int param2 = innerBox->value(); vector<Rectangle> selection = zoneSelector->getSelections(); int K = selection.size(); int* classes = new int[K]; + outText(qApp->translate("ClassResult", "------Largeur de couronne pour conserver la zone intérieure : %1 ------").arg(param1).toStdString()); + outText(qApp->translate("ClassResult", "------Largeur de couronne pour conserver la zone frontière : %1 ------\n").arg(param2).toStdString()); outText(qApp->translate("ClassResult", "Voici les résultats du classement : \n").toStdString()); - outText(qApp->translate("ClassResult", "\nNombre de classes = %1 ").arg(K).toStdString()); + outText(qApp->translate("ClassResult", "Nombre de classes = %1 ").arg(K).toStdString()); for(int i = 0; i < K; ++i) { Histogram histo = img->getHistogram(0, selection.at(i)); classes[i] = (uint8_t) (std::max_element(histo.begin(), histo.end()) - histo.begin()); diff --git a/app/Operations/FFTOp.cpp b/app/Operations/FFTOp.cpp index 644295580f9d33f65be4b0ae53e5bd4d6ee060b8..82236b7e33944493fe7e96cbb301adf1b7ec6db1 100644 --- a/app/Operations/FFTOp.cpp +++ b/app/Operations/FFTOp.cpp @@ -93,8 +93,9 @@ void FFTOp::operator()(const imagein::Image* image, const map<const imagein::Ima } } } - this->outDoubleImage(phaseImg, qApp->translate("FFTOp", "DFT (phase)").toStdString(), true, false); - this->outDoubleImage(magnitudeImg, qApp->translate("FFTOp", "DFT (magnitude)").toStdString(), true, true); + /*(imagein::ImageDouble* img, std::string title = "", bool norm=false, bool log=false, double logScale = 1., bool abs = false)*/ + this->outDoubleImage(phaseImg, qApp->translate("FFTOp", "DFT (Phase)").toStdString(), false, true); + this->outDoubleImage(magnitudeImg, qApp->translate("FFTOp", "DFT (Magnitude)").toStdString(), false, true); } else { Image_t<double>* realImg = new Image_t<double>(width, height, image->getNbChannels()); @@ -138,8 +139,11 @@ void FFTOp::operator()(const imagein::Image* image, const map<const imagein::Ima } } } - this->outDoubleImage(realImg, "FFT (real)", true, true); - this->outDoubleImage(imagImg, "FFT (imag)", true, true); +// this->outDoubleImage(realImg, "FFT (real)", true, true); +// this->outDoubleImage(imagImg, "FFT (imag)", true, true); + /*Offset disabled by default*/ + this->outDoubleImage(realImg, "FFT (Real part)", false, true); + this->outDoubleImage(imagImg, "FFT (Imaginary part)", false, true); } diff --git a/app/Operations/InversePyramidDialog.h b/app/Operations/InversePyramidDialog.h index 5280e8c3629bc6d363368ab07939739687e2c750..2dc7c9e762933d1ce1a9044ba092a0dd2074a551 100644 --- a/app/Operations/InversePyramidDialog.h +++ b/app/Operations/InversePyramidDialog.h @@ -38,7 +38,6 @@ public: int getNbStep() const; int getStep() const; - private: Ui::InversePyramidDialog *ui; }; diff --git a/app/Operations/InversePyramidDialog.ui b/app/Operations/InversePyramidDialog.ui index 22f4b2938106d0bcb12902621a059f42ad5c344d..7b0cbc3a59701c06cd446c0f5e20a33cf3a987c8 100644 --- a/app/Operations/InversePyramidDialog.ui +++ b/app/Operations/InversePyramidDialog.ui @@ -7,7 +7,7 @@ <x>0</x> <y>0</y> <width>245</width> - <height>225</height> + <height>230</height> </rect> </property> <property name="windowTitle"> diff --git a/app/Operations/InversePyramidOp.cpp b/app/Operations/InversePyramidOp.cpp index 36330a4512a451185c53cb2792d9a194c135457e..5c458c87186cc54b7b8814d8eb86d7d44e0df754 100644 --- a/app/Operations/InversePyramidOp.cpp +++ b/app/Operations/InversePyramidOp.cpp @@ -28,7 +28,7 @@ using namespace std; using namespace imagein; -InversePyramidOp::InversePyramidOp() : Operation(qApp->translate("Operations", "Pyramidal reconstruction").toStdString()) +InversePyramidOp::InversePyramidOp() : Operation(qApp->translate("Operations", "Laplacian pyramidal reconstruction").toStdString()) { } @@ -37,6 +37,7 @@ bool InversePyramidOp::needCurrentImg() const { } void InversePyramidOp::operator()(const imagein::Image* img, const std::map<const imagein::Image*, std::string>&) { + if(2 * img->getWidth() != img->getHeight()) { QMessageBox::warning(NULL, qApp->translate("Operations", "The operation can't be applied on this image"), qApp->translate("Operations", "The image width must be twice the image height.")); diff --git a/app/Operations/PointOp.cpp b/app/Operations/PointOp.cpp index 75a3f2503129b4b8e09edb5665065acc472d11f6..c5cb3954b6c871f50b4e7a2f22509ce757ac7899 100644 --- a/app/Operations/PointOp.cpp +++ b/app/Operations/PointOp.cpp @@ -50,11 +50,12 @@ PointOp::PixelOp* PointOp::PixelOp::fromString(QString op, QString expr) { if(op=="-") return new PixAdd(-expr.toInt(0,0)); if(op=="*") return new PixMul(expr.toDouble()); if(op=="/") return new PixMul(1/expr.toDouble()); - if(op=="&") return new PixAnd(expr.toUInt(0,0)); - if(op=="|") return new PixOr(expr.toUInt(0,0)); - if(op=="^") return new PixXor(expr.toUInt(0,0)); - if(op=="<<") return new PixLshift(expr.toUInt(0,0)); - if(op==">>") return new PixRshift(expr.toUInt(0,0)); + if(op=="&& (logical AND)") return new PixLogicalAnd(expr.toUInt(0,0)); + if(op=="|| (logical OR)") return new PixLogicalOr(expr.toUInt(0,0)); + if(op=="^^ (logical XOR)") return new PixLogicalXor(expr.toUInt(0,0)); + /*The operator of shift operations is considered as a double to simplify the structure*/ +// if(op=="<<") return new PixLshift(expr.toUInt(0,0)); +// if(op==">>") return new PixRshift(expr.toUInt(0,0)); if(op=="") return new PixIdent(); std::cout << "Unknown operator '" << op.toStdString() << "' !" << std::endl; return new PixIdent(); @@ -64,9 +65,11 @@ PointOp::DoublePixelOp* PointOp::DoublePixelOp::fromString(QString op, QString e if(op=="-") return new DoublePixAdd(-expr.toDouble()); if(op=="*") return new DoublePixMul(expr.toDouble()); if(op=="/") return new DoublePixMul(1/expr.toDouble()); - if(op=="&") return new DoublePixAnd(expr.toDouble()); - if(op=="|") return new DoublePixOr(expr.toDouble()); - if(op=="^") return new DoublePixXor(expr.toDouble()); + if(op=="&& (logical AND)") return new DoublePixLogicalAnd(expr.toDouble()); + if(op=="|| (logical OR)") return new DoublePixLogicalOr(expr.toDouble()); + if(op=="^^ (logical XOR)") return new DoublePixLogicalXor(expr.toDouble()); + if(op=="<<") return new PixLshift(expr.toDouble()); + if(op==">>") return new PixRshift(expr.toDouble()); if(op=="") return new DoublePixIdent(); std::cout << "Unknown operator '" << op.toStdString() << "' !" << std::endl; return new DoublePixIdent(); @@ -75,11 +78,12 @@ PointOp::DoublePixelOp* PointOp::DoublePixelOp::fromString(QString op, QString e PointOp::ImageOp* PointOp::ImageOp::fromString(QString op) { if(op=="+") return new ImgAdd(); if(op=="-") return new ImgSub(); - if(op=="&") return new ImgAnd(); if(op=="*") return new ImgMul(); if(op=="/") return new ImgDiv(); - if(op=="|") return new ImgOr(); - if(op=="^") return new ImgXor(); + if(op=="& (bit-wise AND)") return new ImgBitAnd(); + if(op=="! (bit-wise NOT)") return new ImgBitNot(); + if(op=="| (bit-wise OR)") return new ImgBitOr(); + if(op=="^ (bit-wise XOR)") return new ImgBitXor(); if(op=="") return new ImgIdent(); std::cout << "Unknown operator '" << op.toStdString() << "' !" << std::endl; return new ImgIdent(); @@ -90,9 +94,7 @@ PointOp::DoubleImageOp* PointOp::DoubleImageOp::fromString(QString op) { if(op=="-") return new DoubleImgSub(); if(op=="*") return new DoubleImgMul(); if(op=="/") return new DoubleImgDiv(); - if(op=="&") return new DoubleImgAnd(); - if(op=="|") return new DoubleImgOr(); - if(op=="^") return new DoubleImgXor(); + if(op=="! (bit-wise NOT)") return new DoubleImgBitNot(); if(op=="") return new DoubleImgIdent(); std::cout << "Unknown operator '" << op.toStdString() << "' !" << std::endl; return new DoubleImgIdent(); @@ -100,10 +102,12 @@ PointOp::DoubleImageOp* PointOp::DoubleImageOp::fromString(QString op) { void PointOp::operator()(const ImageWindow* currentWnd, const vector<const ImageWindow*>& wndList) { - QStringList pixOperators, imgOperators; + QStringList pixOperators, imgOperators, pixDoubleOperators; + + pixOperators << "" << "+" << "-" << "*" << "/" << "&& (logical AND)" << "|| (logical OR)" << "^^ (logical XOR)" << "<<" << ">>"; + pixDoubleOperators << "" << "+" << "-" << "*" << "/"; + imgOperators << "" << "+" << "-" << "*" << "/" << "& (bit-wise AND)" << "! (bit-wise NOT)" << "| (bit-wise OR)" << "^ (bit-wise XOR)"; - pixOperators << "" << "+" << "-" << "*" << "/" << "&" << "|" << "^" << "<<" << ">>"; - imgOperators << "" << "+" << "-" << "*" << "/" << "&" << "|" << "^"; QString currentImgName = currentWnd->windowTitle(); map<const Image*,string> stdImgList; map<const Image_t<double>*,string> dblImgList; @@ -125,19 +129,17 @@ void PointOp::operator()(const ImageWindow* currentWnd, const vector<const Image QVBoxLayout* layout = new QVBoxLayout(); dialog->setLayout(layout); - /*The generation order of the widgets does not match the layout, exchange their positions*/ QGroupBox* radioGroup = new QGroupBox(qApp->translate("PointOp", "Second operand"), dialog); -// QRadioButton* uCharButton = new QRadioButton(qApp->translate("PointOp", "UChar")); -// QRadioButton* doubleButton = new QRadioButton(qApp->translate("PointOp", "Double")); QRadioButton* valueButton = new QRadioButton(qApp->translate("PointOp", "Value")); + valueButton->setWhatsThis(qApp->translate("PointOp", "Enter a real number in the blank space below as the second operand")); QRadioButton* imageButton = new QRadioButton(qApp->translate("PointOp", "Image")); + imageButton->setWhatsThis(qApp->translate("PointOp", "Select an image as the second operand")); QGroupBox* radioGroup2 = new QGroupBox(qApp->translate("PointOp", "Output image"), dialog); -// QRadioButton* valueButton = new QRadioButton(qApp->translate("PointOp", "Value")); -// QRadioButton* imageButton = new QRadioButton(qApp->translate("PointOp", "Image")); QRadioButton* uCharButton = new QRadioButton(qApp->translate("PointOp", "UChar")); + uCharButton->setWhatsThis(qApp->translate("PointOp", "Output the result image in uchar format")); QRadioButton* doubleButton = new QRadioButton(qApp->translate("PointOp", "Double")); - + doubleButton->setWhatsThis(qApp->translate("PointOp", "Output the result image in double format")); QHBoxLayout* radioLayout = new QHBoxLayout(radioGroup); radioLayout->addWidget(valueButton); @@ -152,7 +154,6 @@ void PointOp::operator()(const ImageWindow* currentWnd, const vector<const Image valueButton->setChecked(true); uCharButton->setChecked(true); - //Si l'image est une image double le bouton est obligatoirement coché if(currentWnd->isDouble()){ doubleButton->setChecked(true); @@ -164,8 +165,11 @@ void PointOp::operator()(const ImageWindow* currentWnd, const vector<const Image QHBoxLayout* optLayout = new QHBoxLayout(); QGridLayout* gridLayout = new QGridLayout(); QCheckBox* offsetBox = new QCheckBox(qApp->translate("PointOp","Offset")); + offsetBox->setWhatsThis(qApp->translate("PointOp", "Add an offset of 127 to fit negative values")); QCheckBox* scalingBox = new QCheckBox(qApp->translate("PointOp","Scaling")); + scalingBox->setWhatsThis(qApp->translate("PointOp", "Map the value of each pixel to the range of 0-255 proportionally")); QCheckBox* colorBox = new QCheckBox(qApp->translate("PointOp", "Explode colors")); + colorBox->setWhatsThis(qApp->translate("PointOp", "Check this option to execute the manipulation by channel")); offsetBox->setAutoExclusive(false); scalingBox->setAutoExclusive(false); offsetBox->setEnabled(!doubleButton->isChecked()); @@ -193,8 +197,15 @@ void PointOp::operator()(const ImageWindow* currentWnd, const vector<const Image QWidget* pixelWidget = new QWidget(dialog); valueLayouts[0] = new QHBoxLayout(); pixOperatorBoxes[0] = new QComboBox(pixelWidget); + pixOperatorBoxes[0]->setWhatsThis(qApp->translate("PointOp", "Supported operations list which takes a value as operand: \n The input operand will be rounded down for shift operations")); imgOperatorBoxes[0] = new QComboBox(pixelWidget); - pixOperatorBoxes[0]->addItems(pixOperators); + imgOperatorBoxes[0]->setWhatsThis(qApp->translate("PointOp", "Supported operations list whick takes an image as operand: \n The bit-wise NOT operation will automatically ignore the second image")); + if(currentWnd->isStandard()){ + pixOperatorBoxes[0]->addItems(pixOperators); + } + if(currentWnd->isDouble()){ + pixOperatorBoxes[0]->addItems(pixDoubleOperators); + } imgOperatorBoxes[0]->addItems(imgOperators); exprEdits[0] = new QLineEdit(pixelWidget); exprEdits[0]->setFixedWidth(64); @@ -215,7 +226,13 @@ void PointOp::operator()(const ImageWindow* currentWnd, const vector<const Image valueLayouts[i] = new QHBoxLayout(); pixOperatorBoxes[i] = new QComboBox(colorWidget); imgOperatorBoxes[i] = new QComboBox(colorWidget); - pixOperatorBoxes[i]->addItems(pixOperators); + if(currentWnd->isStandard()){ + pixOperatorBoxes[i]->addItems(pixOperators); + } + if(currentWnd->isDouble()){ + pixOperatorBoxes[i]->addItems(pixDoubleOperators); + } + imgOperatorBoxes[i]->addItems(imgOperators); exprEdits[i] = new QLineEdit(colorWidget); exprEdits[i]->setFixedWidth(64); @@ -244,7 +261,7 @@ void PointOp::operator()(const ImageWindow* currentWnd, const vector<const Image QObject::connect(uCharButton, SIGNAL(toggled(bool)), scalingBox, SLOT(setEnabled(bool))); QObject::connect(doubleButton, SIGNAL(toggled(bool)), offsetBox, SLOT(setChecked(bool))); QObject::connect(doubleButton, SIGNAL(toggled(bool)), scalingBox, SLOT(setChecked(bool))); - + layout->setSizeConstraint(QLayout::SetFixedSize); QPushButton *okButton = new QPushButton(qApp->translate("Operations", "Validate"), dialog); diff --git a/app/Operations/PointOp.h b/app/Operations/PointOp.h index e78e5ff7ee3c819efee23a95c5b57b358e9c4d0a..c9b2a125aed683e9db3f388ff7a387bd1f531161 100644 --- a/app/Operations/PointOp.h +++ b/app/Operations/PointOp.h @@ -24,7 +24,6 @@ #include <map> #include <limits> #include <QCoreApplication> - #include "Operation.h" #include "Image.h" @@ -51,7 +50,6 @@ class PointOp : public GenericOperation { return static_cast<depth_t>(value); } - struct PixelOp { virtual depth_t operator()(depth_t pixel) { return normalize(this->op(pixel)); @@ -87,6 +85,7 @@ class PointOp : public GenericOperation { PixAdd(int value_) : PixOp_t<int>(value_) {} intmax_t op(depth_t pixel) { return pixel + value; } }; + struct DoublePixAdd : DoublePixelOp { DoublePixAdd(double value_) : DoublePixelOp(value_) {} double op(double pixel) { return pixel + value; } @@ -96,54 +95,72 @@ class PointOp : public GenericOperation { PixMul(double value_) : PixOp_t<double>(value_) {} intmax_t op(depth_t pixel) { return pixel * value + 0.5; } }; + struct DoublePixMul : DoublePixelOp { DoublePixMul(double value_) : DoublePixelOp(value_) {} double op(double pixel) { return pixel * value; } }; - struct PixAnd : PixOp_t<depth_t> { - PixAnd(depth_t value_) : PixOp_t<depth_t>(value_) {} - intmax_t op(depth_t pixel) { return pixel & value; } + struct PixLogicalAnd : PixOp_t<depth_t> { + PixLogicalAnd(depth_t value_) : PixOp_t<depth_t>(value_) {} + intmax_t op(depth_t pixel) { return pixel && value; } }; /*Return zero if the operands have zero*/ - struct DoublePixAnd : DoublePixelOp { - DoublePixAnd(double value_) : DoublePixelOp(value_) {} + struct DoublePixLogicalAnd : DoublePixelOp { + DoublePixLogicalAnd(double value_) : DoublePixelOp(value_) {} double op(double pixel) { return (pixel==0 or value==0) ? 0 : pixel; } }; - struct PixOr : PixOp_t<depth_t> { - PixOr(depth_t value_) : PixOp_t<depth_t>(value_) {} - intmax_t op(depth_t pixel) { return pixel | value; } + /*There's no not logic for double value*/ + struct PixNot : PixOp_t<depth_t> { + PixNot(depth_t value_) : PixOp_t<depth_t>(value_) {} + intmax_t op(depth_t pixel) { return 255 - pixel; } + }; + + struct PixLogicalOr : PixOp_t<depth_t> { + PixLogicalOr(depth_t value_) : PixOp_t<depth_t>(value_) {} + intmax_t op(depth_t pixel) { return pixel || value; } }; /*Return zero only if the operands are both zero*/ - struct DoublePixOr : DoublePixelOp { - DoublePixOr(double value_) : DoublePixelOp(value_) {} + struct DoublePixLogicalOr : DoublePixelOp { + DoublePixLogicalOr(double value_) : DoublePixelOp(value_) {} double op(double pixel) { return (pixel==0 and value==0) ? 0 : pixel; } }; - struct PixXor : PixOp_t<depth_t> { - PixXor(depth_t value_) : PixOp_t<depth_t>(value_) {} - intmax_t op(depth_t pixel) { return pixel ^ value; } + struct PixLogicalXor : PixOp_t<depth_t> { + PixLogicalXor(depth_t value_) : PixOp_t<depth_t>(value_) {} + intmax_t op(depth_t pixel) { return (pixel==value) ? 0 : pixel; } }; /*Return zero only if the operands have the same value*/ - struct DoublePixXor : DoublePixelOp { - DoublePixXor(double value_) : DoublePixelOp(value_) {} + struct DoublePixLogicalXor : DoublePixelOp { + DoublePixLogicalXor(double value_) : DoublePixelOp(value_) {} double op(double pixel) { return (pixel==value) ? 0 : pixel; } }; - struct PixLshift : PixOp_t<unsigned int> { - PixLshift(unsigned int value_) : PixOp_t<unsigned int>(value_) {} - intmax_t op(depth_t pixel) { return pixel << value; } - }; +// struct PixLshift : PixOp_t<depth_t> { +// PixLshift(depth_t value_) : PixOp_t<depth_t>(value_) {} +// intmax_t op(depth_t pixel) { return pixel << value; } +// }; - struct PixRshift : PixOp_t<unsigned int> { - PixRshift(unsigned int value_) : PixOp_t<unsigned int>(value_) {} - intmax_t op(depth_t pixel) { return pixel >> value; } +// struct PixRshift : PixOp_t<depth_t> { +// PixRshift(depth_t value_) : PixOp_t<depth_t>(value_) {} +// intmax_t op(depth_t pixel) { return (int)pixel >> (int)value; } +// }; + + struct PixLshift : DoublePixelOp { + PixLshift(depth_t value_) : DoublePixelOp(value_) {} + double op(double pixel) { return (int)pixel << (int)value; } }; + struct PixRshift : DoublePixelOp { + PixRshift(depth_t value_) : DoublePixelOp(value_) {} + double op(double pixel) { return (int)pixel >> (int)value; } + }; + + struct ImageOp { virtual depth_t operator()(depth_t pixel1, depth_t pixel2) { return normalize(this->op(pixel1, pixel2)); @@ -196,27 +213,38 @@ class PointOp : public GenericOperation { double op(double pix1, double pix2) { return pix1 / pix2; } }; - struct ImgAnd : ImageOp { + struct ImgBitAnd : ImageOp { intmax_t op(depth_t pix1, depth_t pix2) { return pix1 & pix2; } }; - struct DoubleImgAnd : DoubleImageOp { + struct DoubleImgBitAnd : DoubleImageOp { double op(double pix1, double pix2) { return (pix1==0 or pix2==0) ? 0 : pix1;} }; - - struct ImgOr : ImageOp { + + /*To keep the symmetry of the interface, BitNot was categorized as an image operation + But for the negation operation, the second operand is unnecessary*/ + struct ImgBitNot : ImageOp { + intmax_t op(depth_t pix1, depth_t pix2) { return 255 - pix1; } + }; + + /*DoubleImgBitNot is defined to reconcile two operators in different types*/ + struct DoubleImgBitNot : DoubleImageOp { + double op(double pix1, double pix2) { return 255 - pix1; } + }; + + struct ImgBitOr : ImageOp { intmax_t op(depth_t pix1, depth_t pix2) { return pix1 | pix2; } }; - struct DoubleImgOr : DoubleImageOp { + struct DoubleImgBitOr : DoubleImageOp { double op(double pix1, double pix2) { return (pix1==0 and pix2==0) ? 0 : pix1;} }; - struct ImgXor : ImageOp { + struct ImgBitXor : ImageOp { intmax_t op(depth_t pix1, depth_t pix2) { return pix1 ^ pix2; } }; - struct DoubleImgXor : DoubleImageOp { + struct DoubleImgBitXor : DoubleImageOp { double op(double pix1, double pix2) { return (pix1 == pix2) ? 0 : pix1; } }; diff --git a/app/Operations/PyramidDialog.cpp b/app/Operations/PyramidDialog.cpp index f7eb036907b31daf938738033c2806e1ef9eb5aa..d56e09919cd0c7aadeff74b1dc13af5cfb04e4b7 100644 --- a/app/Operations/PyramidDialog.cpp +++ b/app/Operations/PyramidDialog.cpp @@ -86,3 +86,9 @@ void PyramidDialog::setOneStepChecked(bool a){ void PyramidDialog::setOneStep(int a){ ui->onlyStepBox->setValue(a); } + +/*Update the maximum decomposition level according to the size of the input image*/ +void PyramidDialog::updateMaxLevel(int max) +{ + ui->stepBox->setMaximum(max); +} diff --git a/app/Operations/PyramidDialog.h b/app/Operations/PyramidDialog.h index e28a0a2ee70cb2da1e280b9cf2373a5479395ad9..a4a8ff98d2d0693aab50b0a58e830d7bb947d2da 100644 --- a/app/Operations/PyramidDialog.h +++ b/app/Operations/PyramidDialog.h @@ -45,6 +45,7 @@ public: void setFilter(int); void setOneStep(int); void setOneStepChecked(bool); + void updateMaxLevel(int); private: Ui::PyramidDialog *ui; diff --git a/app/Operations/PyramidDialog.ui b/app/Operations/PyramidDialog.ui index 2a1cccbb085ea381a7b606be6daba018d4db7823..fc1e4b2b3706e50d067446efae9f9b24e802b610 100644 --- a/app/Operations/PyramidDialog.ui +++ b/app/Operations/PyramidDialog.ui @@ -81,7 +81,7 @@ <item row="1" column="0"> <widget class="QLabel" name="nbStepLabel"> <property name="text"> - <string>Number of steps : </string> + <string>Number of levels : </string> </property> </widget> </item> @@ -102,7 +102,7 @@ <item> <widget class="QCheckBox" name="oneStepBox"> <property name="text"> - <string>Create only one step :</string> + <string>Create only one level :</string> </property> </widget> </item> diff --git a/app/Operations/PyramidOp.cpp b/app/Operations/PyramidOp.cpp index 5253d7aca01a7c6b75b89ce30f9b831fe8d9be0b..2bfbd3fbefe31a945aa5a7fa537c604c91fe848d 100644 --- a/app/Operations/PyramidOp.cpp +++ b/app/Operations/PyramidOp.cpp @@ -52,6 +52,8 @@ void PyramidOp::operator()(const imagein::Image* img, const std::map<const image } PyramidDialog* dialog = new PyramidDialog(QApplication::activeWindow()); + /*Update the maximum decomposition level according to the size of the input image*/ + dialog->updateMaxLevel(Pyramid::etage_max(img)); if(_test){ dialog->setFilter(_filter); @@ -94,7 +96,7 @@ void PyramidOp::operator()(const imagein::Image* img, const std::map<const image } } catch(const char*e) { - QMessageBox::critical(NULL, "Error", QString(e)); + QMessageBox::critical(NULL, "Error", QString("wtf")); return; } diff --git a/app/Operations/Transforms.cpp b/app/Operations/Transforms.cpp index ebf96447fc9d8f284558532b9e10ebc98b5a085b..b22dad8af2771834c4dee715a0f065ed4bcf8031 100644 --- a/app/Operations/Transforms.cpp +++ b/app/Operations/Transforms.cpp @@ -567,10 +567,10 @@ for(unsigned int c = 0; c < tmpImg->getNbChannels(); c++) { // size = nbc * nbl; // GrayscaleImage* tabout = new GrayscaleImage(im->getWidth(), im->getHeight()); // Image_t<double>* tmpImg = Converter<Image_t<double> >::convert(*image); -//// tabin = new double[ size ]; -//// for(i=0 ; i<nbl ; i++) -//// for(j=0 ; j<nbc ; j++) -//// tabin[i*nbc+j] = (double)im->getPixel( j, i ); +// tabin = new double[ size ]; +// for(i=0 ; i<nbl ; i++) +// for(j=0 ; j<nbc ; j++) +// tabin[i*nbc+j] = (double)im->getPixel( j, i ); ///*--------------------------------------------------------------------- //*