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 2.1k 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.
  • Christian EhrlicherC Online
    Christian EhrlicherC Online
    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 Online
            Christian EhrlicherC Online
            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 Online
                        Christian EhrlicherC Online
                        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