C++ 如何在CImg中获得作为矩阵/向量的像素数据?

C++ 如何在CImg中获得作为矩阵/向量的像素数据?,c++,matrix,pixel,cimg,C++,Matrix,Pixel,Cimg,我需要读取灰度png图像,以便像素值(0-255)存储在无符号字符的2D矩阵中。 目前,我在C++中使用CImg,它成功地读取了图像,但我无法理解如何将像素数据从CIMG容器中取出。 我可以这样做: CImg<unsigned char> image("img1.png"); unsigned char* img1 = image.data(); CImg图像(“img1.png”); 无符号字符*img1=image.data(); 但它给了我一个char*,根据文档,它是“指

我需要读取灰度png图像,以便像素值(0-255)存储在无符号字符的2D矩阵中。 目前,我在C++中使用CImg,它成功地读取了图像,但我无法理解如何将像素数据从CIMG容器中取出。 我可以这样做:

CImg<unsigned char> image("img1.png");
unsigned char* img1 = image.data();
CImg图像(“img1.png”);
无符号字符*img1=image.data();
但它给了我一个char*,根据文档,它是“指向图像第一个值的指针”,但我不知道如何处理它,或者如何访问其他值

有什么建议吗

谢谢,,
大卫

这样做的可能性确实很多

  • 您可以使用当前方法,只需在原始像素数组中迭代:

    CImg<unsigned char> image("img1.png");
    unsigned char* img1 = image.data();
    for(int i=0; i < image.size(); i++) {
        logger_->info("*img1 value: {}", *(img1+i));
    }
    
    CImg图像(“img1.png”);
    无符号字符*img1=image.data();
    对于(int i=0;i信息(“*img1值:{}”,*(img1+i));
    }
    
  • 根据报告:

    Size()返回width()*height()*depth()*spectrum(),即图像实例的像素缓冲区中类型T的值的总数

    因此,您也可以直接使用这些尺寸标注:

  • 像这样:

    CImg<unsigned char> image("img1.png");
    unsigned char* img1 = image.data();
    for(int i=0; i < image.width()*image.height()*image.depth()*image.spectrum(); i++) {
        logger_->info("*img1 value: {}", *(img1+i));
    }
    
    CImg图像(“img1.png”);
    无符号字符*img1=image.data();
    对于(int i=0;i信息(“*img1值:{}”,*(img1+i));
    }
    
    当然,这允许您分别编写遍历每个维度的嵌套循环

  • 如果不喜欢遍历原始数组,可以使用迭代器:

    CImg<unsigned char> image("img1.png");
    unsigned char* img1 = image.data();
    for (CImg<unsigned char>::iterator it = image.begin(); it < image.end(); ++it) {
        logger_->info("it value: {}", *it);
    }
    
    CImg图像(“img1.png”);
    无符号字符*img1=image.data();
    for(CImg::iterator it=image.begin();it信息(“it值:{}”,*it);
    }
    

  • 或者,如果您想尝试其他方法,请查阅文档,我提供的示例并不详尽。

    不确定为什么要将CImg结构/类中的所有数据复制到另一个2D数组中,而您仍然可以访问它。因此,如果希望像素位于位置[x,y],只需使用:

    img(x,y)
    
    下面是一个完整的程序,用于转储图像-访问内部循环中的各个像素:

    #include <iostream>
    #include <cstdlib>
    
    #define cimg_display 0
    #include "CImg.h"
    
    using namespace cimg_library;
    using namespace std;
    
    int main() {
        CImg<unsigned char> img("test.pgm");
    
        // Get width, height, number of channels
        int w=img.width();
        int h=img.height();
        int c=img.spectrum();
        cout << "Dimensions: " << w << "x" << h << " " << c << " channels" <<endl;
    
        // Dump all pixels
        for(int y=0;y<h;y++){
           for(int x=0;x<w;x++){
              cout << y << "," << x << " " << (int)img(x,y) << endl;
           }
        }
    }
    
    以下是输出,您可以看到它与图像匹配:

    Dimensions: 5x3 1 channels
    0,0 0
    0,1 1
    0,2 2
    0,3 3
    0,4 4
    1,0 10
    1,1 11
    1,2 12
    1,3 13
    1,4 14
    2,0 100
    2,1 101
    2,2 102
    2,3 103
    2,4 104
    

    好了,现在我明白了。我尝试了建议的两种方法,但它们的速度非常慢,只有~10MP的图像。最初我想将它移动到另一个数组以加快速度,但由于无法直接复制该数组,因此每次迭代时遍历和更改向量大小的速度要慢得多。。。所以我将坚持使用img(x,y)访问方法当然有一种方法可以将数据复制到另一个数组:
    std::memcpy(dest,source,size)。我只是不知道复印件后你该如何加快速度。
    
    Dimensions: 5x3 1 channels
    0,0 0
    0,1 1
    0,2 2
    0,3 3
    0,4 4
    1,0 10
    1,1 11
    1,2 12
    1,3 13
    1,4 14
    2,0 100
    2,1 101
    2,2 102
    2,3 103
    2,4 104