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
Forum Updated to NodeBB v4.3 + New Features

convert Eigen MatrixXd to QImage

Scheduled Pinned Locked Moved Unsolved General and Desktop
20 Posts 5 Posters 1.7k 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 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