Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. convert Eigen MatrixXd to QImage

convert Eigen MatrixXd to QImage

Scheduled Pinned Locked Moved Unsolved General and Desktop
20 Posts 5 Posters 1.9k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • H Offline
    H Offline
    hei6775
    wrote on last edited by
    #1

    I want to convert matrixXd of Eigen to QImage(format, grayscale)。Here is my code, but the result is wrong. I am newer in QT and Eigen.

    ObjWindow::ObjWindow(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::ObjWindow)
    {
        ui->setupUi(this);
        int height = 100;
        int width = 100;
    
        Eigen::MatrixXd doubleM(height, width);
    
        for (int i = 0;i<height; i++)
        {
            for (int k = 0; k<width; k++)
            {
                if (i>=50) {
                    doubleM(i, k) = 200;
                };
    
            };
        };
        QImage xx = Eigen2QImage(doubleM);
        ui->label->setPixmap(QPixmap::fromImage(xx));
    
    }
    
    QImage ObjWindow::Eigen2QImage(const MatrixXd &src)
    {
        double scale = 255.0;
        double max_value = src.maxCoeff();
        double min_value = src.minCoeff();
        QImage dest(src.cols(), src.rows(), QImage::Format_Grayscale8);
    
        for (int y = 0; y < src.rows(); ++y)
        {
            const double *src_row = src.row(y).data();
            uchar * destrow = dest.scanLine(y);
            for (int x = 0; x < src.cols() ; ++x)
            {
                uchar gray = (uchar)(src_row[x] / max_value * 255);
                destrow[x] = gray;
            }
        }
        return dest;
    }
    
    jsulmJ KroMignonK 2 Replies Last reply
    0
    • Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by Christian Ehrlicher
      #2

      @hei6775 said in convert Eigen MatrixXd to QImage:

      but the result is wrong.

      This is no valid error description.

      Apart from this - row is x (horizontal) in Qt (and maybe also in eigen I would guess)

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      1 Reply Last reply
      0
      • H Offline
        H Offline
        hei6775
        wrote on last edited by
        #3

        The Image become:de71c1ea-d4ca-4ffd-b959-456c1bc5509e-image.png

        1 Reply Last reply
        0
        • H hei6775

          I want to convert matrixXd of Eigen to QImage(format, grayscale)。Here is my code, but the result is wrong. I am newer in QT and Eigen.

          ObjWindow::ObjWindow(QWidget *parent) :
              QWidget(parent),
              ui(new Ui::ObjWindow)
          {
              ui->setupUi(this);
              int height = 100;
              int width = 100;
          
              Eigen::MatrixXd doubleM(height, width);
          
              for (int i = 0;i<height; i++)
              {
                  for (int k = 0; k<width; k++)
                  {
                      if (i>=50) {
                          doubleM(i, k) = 200;
                      };
          
                  };
              };
              QImage xx = Eigen2QImage(doubleM);
              ui->label->setPixmap(QPixmap::fromImage(xx));
          
          }
          
          QImage ObjWindow::Eigen2QImage(const MatrixXd &src)
          {
              double scale = 255.0;
              double max_value = src.maxCoeff();
              double min_value = src.minCoeff();
              QImage dest(src.cols(), src.rows(), QImage::Format_Grayscale8);
          
              for (int y = 0; y < src.rows(); ++y)
              {
                  const double *src_row = src.row(y).data();
                  uchar * destrow = dest.scanLine(y);
                  for (int x = 0; x < src.cols() ; ++x)
                  {
                      uchar gray = (uchar)(src_row[x] / max_value * 255);
                      destrow[x] = gray;
                  }
              }
              return dest;
          }
          
          jsulmJ Offline
          jsulmJ Offline
          jsulm
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @hei6775 said in convert Eigen MatrixXd to QImage:

          / max_value * 255);

          Shouldn't you do modulo here:

          uchar gray = (uchar)(src_row[x] / max_value % 255);
          

          ?

          https://forum.qt.io/topic/113070/qt-code-of-conduct

          H 1 Reply Last reply
          0
          • jsulmJ jsulm

            @hei6775 said in convert Eigen MatrixXd to QImage:

            / max_value * 255);

            Shouldn't you do modulo here:

            uchar gray = (uchar)(src_row[x] / max_value % 255);
            

            ?

            H Offline
            H Offline
            hei6775
            wrote on last edited by
            #5

            @jsulm error: invalid operands to binary expression ('double' and 'double'). modulo is invalid for double type.

            Christian EhrlicherC 1 Reply Last reply
            0
            • H hei6775

              @jsulm error: invalid operands to binary expression ('double' and 'double'). modulo is invalid for double type.

              Christian EhrlicherC Offline
              Christian EhrlicherC Offline
              Christian Ehrlicher
              Lifetime Qt Champion
              wrote on last edited by
              #6

              @hei6775 Then fix it... c basics

              What's the format of the eigen image? How must the gray value be interpreted / what's the range of it?

              Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
              Visit the Qt Academy at https://academy.qt.io/catalog

              H 1 Reply Last reply
              0
              • Christian EhrlicherC Christian Ehrlicher

                @hei6775 Then fix it... c basics

                What's the format of the eigen image? How must the gray value be interpreted / what's the range of it?

                H Offline
                H Offline
                hei6775
                wrote on last edited by
                #7

                @Christian-Ehrlicher double. Eigen::MatrixXd mean a matrix of dynamic size and double type.
                The problem(@jsulm mentioned) is wrong direction.
                I print the value of src_row[x], this is incorrect value.

                // the first pixel in the loop
                qDebug() << src_row[x];
                // output:
                // 1.05908e-319
                
                kshegunovK 1 Reply Last reply
                0
                • H hei6775

                  @Christian-Ehrlicher double. Eigen::MatrixXd mean a matrix of dynamic size and double type.
                  The problem(@jsulm mentioned) is wrong direction.
                  I print the value of src_row[x], this is incorrect value.

                  // the first pixel in the loop
                  qDebug() << src_row[x];
                  // output:
                  // 1.05908e-319
                  
                  kshegunovK Offline
                  kshegunovK Offline
                  kshegunov
                  Moderators
                  wrote on last edited by
                  #8

                  Eigen uses expression templates and lazy-evaluation. You're taking a pointer to data contained in an rvalue here src.row(y).data(). Anything can be there after the object goes out of scope.

                  Read and abide by the Qt Code of Conduct

                  1 Reply Last reply
                  4
                  • H hei6775

                    I want to convert matrixXd of Eigen to QImage(format, grayscale)。Here is my code, but the result is wrong. I am newer in QT and Eigen.

                    ObjWindow::ObjWindow(QWidget *parent) :
                        QWidget(parent),
                        ui(new Ui::ObjWindow)
                    {
                        ui->setupUi(this);
                        int height = 100;
                        int width = 100;
                    
                        Eigen::MatrixXd doubleM(height, width);
                    
                        for (int i = 0;i<height; i++)
                        {
                            for (int k = 0; k<width; k++)
                            {
                                if (i>=50) {
                                    doubleM(i, k) = 200;
                                };
                    
                            };
                        };
                        QImage xx = Eigen2QImage(doubleM);
                        ui->label->setPixmap(QPixmap::fromImage(xx));
                    
                    }
                    
                    QImage ObjWindow::Eigen2QImage(const MatrixXd &src)
                    {
                        double scale = 255.0;
                        double max_value = src.maxCoeff();
                        double min_value = src.minCoeff();
                        QImage dest(src.cols(), src.rows(), QImage::Format_Grayscale8);
                    
                        for (int y = 0; y < src.rows(); ++y)
                        {
                            const double *src_row = src.row(y).data();
                            uchar * destrow = dest.scanLine(y);
                            for (int x = 0; x < src.cols() ; ++x)
                            {
                                uchar gray = (uchar)(src_row[x] / max_value * 255);
                                destrow[x] = gray;
                            }
                        }
                        return dest;
                    }
                    
                    KroMignonK Offline
                    KroMignonK Offline
                    KroMignon
                    wrote on last edited by
                    #9

                    @hei6775 said in convert Eigen MatrixXd to QImage:

                    const double *src_row = src.row(y).data();

                    I think you should change this to:

                    const auto srcRow = src.row(y);
                    const double *src_row = srcRow.data();
                    

                    To not loose temporary container

                    It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                    kshegunovK H 2 Replies Last reply
                    1
                    • KroMignonK KroMignon

                      @hei6775 said in convert Eigen MatrixXd to QImage:

                      const double *src_row = src.row(y).data();

                      I think you should change this to:

                      const auto srcRow = src.row(y);
                      const double *src_row = srcRow.data();
                      

                      To not loose temporary container

                      kshegunovK Offline
                      kshegunovK Offline
                      kshegunov
                      Moderators
                      wrote on last edited by
                      #10

                      @KroMignon said in convert Eigen MatrixXd to QImage:

                      I think you should change this to:

                      Yes, in principle, but you must not use auto with Eigen.

                      Read and abide by the Qt Code of Conduct

                      KroMignonK 1 Reply Last reply
                      1
                      • KroMignonK KroMignon

                        @hei6775 said in convert Eigen MatrixXd to QImage:

                        const double *src_row = src.row(y).data();

                        I think you should change this to:

                        const auto srcRow = src.row(y);
                        const double *src_row = srcRow.data();
                        

                        To not loose temporary container

                        H Offline
                        H Offline
                        hei6775
                        wrote on last edited by
                        #11

                        @KroMignon said in convert Eigen MatrixXd to QImage:

                        const auto srcRow = src.row(y);
                        const double *src_row = srcRow.data();

                        This doesn't seem to work

                        1 Reply Last reply
                        0
                        • Christian EhrlicherC Offline
                          Christian EhrlicherC Offline
                          Christian Ehrlicher
                          Lifetime Qt Champion
                          wrote on last edited by
                          #12

                          @hei6775 said in convert Eigen MatrixXd to QImage:

                          This doesn't seem to work

                          @kshegunov

                          Yes, in principle, but you must not use auto with Eigen.

                          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                          Visit the Qt Academy at https://academy.qt.io/catalog

                          1 Reply Last reply
                          0
                          • kshegunovK kshegunov

                            @KroMignon said in convert Eigen MatrixXd to QImage:

                            I think you should change this to:

                            Yes, in principle, but you must not use auto with Eigen.

                            KroMignonK Offline
                            KroMignonK Offline
                            KroMignon
                            wrote on last edited by
                            #13

                            @kshegunov said in convert Eigen MatrixXd to QImage:

                            Yes, in principle, but you must not use auto with Eigen.

                            What is the problem with auto and Eigen?
                            Can you explain more, I don't know Eigen and always pleased to complete my knowledge about C++ :)

                            It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                            kshegunovK 1 Reply Last reply
                            0
                            • KroMignonK KroMignon

                              @kshegunov said in convert Eigen MatrixXd to QImage:

                              Yes, in principle, but you must not use auto with Eigen.

                              What is the problem with auto and Eigen?
                              Can you explain more, I don't know Eigen and always pleased to complete my knowledge about C++ :)

                              kshegunovK Offline
                              kshegunovK Offline
                              kshegunov
                              Moderators
                              wrote on last edited by kshegunov
                              #14

                              @KroMignon said in convert Eigen MatrixXd to QImage:

                              What is the problem with auto and Eigen?

                              I'm going to spare you my personal opinion on auto, but this is it:

                              @kshegunov said in convert Eigen MatrixXd to QImage:

                              Eigen uses expression templates and lazy-evaluation.

                              And here's a reference if you want to read even more: https://eigen.tuxfamily.org/dox/TopicPitfalls.html
                              In a nutshell Eigen builds up a sort of a parse tree from its methods and delays evaluation to the last possible moment. It has the advantage that it's really efficient to pack up complex expressions in a single pass, but doesn't play well with auto, because auto captures a type which isn't a real type, but rather an "evaluation step" type.

                              Read and abide by the Qt Code of Conduct

                              KroMignonK 1 Reply Last reply
                              2
                              • kshegunovK kshegunov

                                @KroMignon said in convert Eigen MatrixXd to QImage:

                                What is the problem with auto and Eigen?

                                I'm going to spare you my personal opinion on auto, but this is it:

                                @kshegunov said in convert Eigen MatrixXd to QImage:

                                Eigen uses expression templates and lazy-evaluation.

                                And here's a reference if you want to read even more: https://eigen.tuxfamily.org/dox/TopicPitfalls.html
                                In a nutshell Eigen builds up a sort of a parse tree from its methods and delays evaluation to the last possible moment. It has the advantage that it's really efficient to pack up complex expressions in a single pass, but doesn't play well with auto, because auto captures a type which isn't a real type, but rather an "evaluation step" type.

                                KroMignonK Offline
                                KroMignonK Offline
                                KroMignon
                                wrote on last edited by
                                #15

                                @kshegunov said in convert Eigen MatrixXd to QImage:

                                In a nutshell Eigen builds up a sort of a parse tree from its methods and delays evaluation to the last possible moment. It has the advantage that it's really efficient to pack up complex expressions in a single pass, but doesn't play well with auto, because auto captures a type which isn't a real type, or rather a "evaluation step" type.

                                Thanks for the link, so if I understand it right, there should be a call to eval() to ensure getting right type:
                                So this should then work?

                                const auto srcRow = src.row(y).eval();
                                const double *src_row = srcRow.data();
                                

                                It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                                kshegunovK 1 Reply Last reply
                                0
                                • KroMignonK KroMignon

                                  @kshegunov said in convert Eigen MatrixXd to QImage:

                                  In a nutshell Eigen builds up a sort of a parse tree from its methods and delays evaluation to the last possible moment. It has the advantage that it's really efficient to pack up complex expressions in a single pass, but doesn't play well with auto, because auto captures a type which isn't a real type, or rather a "evaluation step" type.

                                  Thanks for the link, so if I understand it right, there should be a call to eval() to ensure getting right type:
                                  So this should then work?

                                  const auto srcRow = src.row(y).eval();
                                  const double *src_row = srcRow.data();
                                  
                                  kshegunovK Offline
                                  kshegunovK Offline
                                  kshegunov
                                  Moderators
                                  wrote on last edited by
                                  #16

                                  @KroMignon said in convert Eigen MatrixXd to QImage:

                                  Thanks for the link, so if I understand it right, there should be a call to eval() to ensure getting right type:

                                  Not really. Instead of bending backwards to enforce compile-time type deduction, you just declare the type explicitly:

                                  Eigen::VectorXd row = src.row(y);
                                  

                                  Read and abide by the Qt Code of Conduct

                                  KroMignonK 1 Reply Last reply
                                  1
                                  • kshegunovK kshegunov

                                    @KroMignon said in convert Eigen MatrixXd to QImage:

                                    Thanks for the link, so if I understand it right, there should be a call to eval() to ensure getting right type:

                                    Not really. Instead of bending backwards to enforce compile-time type deduction, you just declare the type explicitly:

                                    Eigen::VectorXd row = src.row(y);
                                    
                                    KroMignonK Offline
                                    KroMignonK Offline
                                    KroMignon
                                    wrote on last edited by
                                    #17

                                    @kshegunov Thanks, for now I never used Eigen, but when I will have to use it I will try to remember this pitfall :)

                                    It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                                    H 1 Reply Last reply
                                    1
                                    • KroMignonK KroMignon

                                      @kshegunov Thanks, for now I never used Eigen, but when I will have to use it I will try to remember this pitfall :)

                                      H Offline
                                      H Offline
                                      hei6775
                                      wrote on last edited by
                                      #18

                                      @KroMignon when i use eval(). It work. Thanks

                                      KroMignonK 1 Reply Last reply
                                      0
                                      • H hei6775

                                        @KroMignon when i use eval(). It work. Thanks

                                        KroMignonK Offline
                                        KroMignonK Offline
                                        KroMignon
                                        wrote on last edited by
                                        #19

                                        @hei6775 said in convert Eigen MatrixXd to QImage:

                                        when i use eval(). It work. Thanks

                                        Yes it works, but as @kshegunov has written and as you can read it in documentation (https://eigen.tuxfamily.org/dox/TopicPitfalls.html), this not be the best way to do with Eigen.
                                        It would be better to not use auto but to specify right variable type like:

                                        const Eigen::VectorXd row = src.row(y);
                                        const double *src_row = srcRow.data();
                                        

                                        It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                                        H 1 Reply Last reply
                                        1
                                        • KroMignonK KroMignon

                                          @hei6775 said in convert Eigen MatrixXd to QImage:

                                          when i use eval(). It work. Thanks

                                          Yes it works, but as @kshegunov has written and as you can read it in documentation (https://eigen.tuxfamily.org/dox/TopicPitfalls.html), this not be the best way to do with Eigen.
                                          It would be better to not use auto but to specify right variable type like:

                                          const Eigen::VectorXd row = src.row(y);
                                          const double *src_row = srcRow.data();
                                          
                                          H Offline
                                          H Offline
                                          hei6775
                                          wrote on last edited by
                                          #20

                                          @KroMignon yes, you are right! Thanks.

                                          1 Reply Last reply
                                          0

                                          • Login

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt Extensions
                                          • Unsolved