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.
  • 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