【问题标题】:How to fill an array of Vec3b如何填充 Vec3b 数组
【发布时间】:2012-06-15 02:13:38
【问题描述】:

我正在使用 OpenCV 处理 C++ 中的图像。

我使用二维 uchar 数组编写代码,我可以在其中读取图像的像素值,并使用 .at< uchar>(i,j) 以灰度方式上传 imread。

但是我想对彩色图像做同样的事情。因为我知道要访问我现在需要.at< Vec3b>(i,j)[0].at< Vec3b>(i,j)[1].at< Vec3b>(i,j)[2] 的像素值,所以我制作了一个类似的Vec3b 二维数组。

但我不知道如何用像素值填充这个数组。它必须是一个二维数组。

我试过了:

array[width][height].val[0]=img.at< Vec3b>(i,j)[0]

但这没有用。

在 OpenCV 文档或此处均未找到答案。

有人有想法吗?

我已经包含了我的一些代码。我需要一个数组,因为我已经让我的整个算法工作,使用一个数组,用于只有一个通道的灰度图像。

灰度代码是这样的:

for(int i=0;i<height;i++){
    for(int j=0;j<width;j++){
        image_data[i*width+j]=all_images[nb_image-1].at< uchar>(i,j);
    }
}

我从哪里读到的:

std::vector< cv::Mat> all_images

每个图像(我有一个长序列),检索uchar数组image_data中的像素值,并处理它们。

我现在想对 RGB 图像做同样的事情,但我无法读取每个通道的数据像素并将它们放入数组中。

这次 image_data 是一个 Vec3b 数组,我正在尝试的代码如下所示:

for(int i=0;i<height;i++){
    for(int j=0;j<width;j++){
        image_data[0][i*width+j]=all_images[nb_image-1].at<cv::Vec3b>(i,j)[2];
        image_data[1][i*width+j]=all_images[nb_image-1].at<cv::Vec3b>(i,j)[1];
        image_data[2][i*width+j]=all_images[nb_image-1].at<cv::Vec3b>(i,j)[0];
    }
}

但这不起作用,所以我现在不知所措我不知道如何成功地用所有三个通道的值填充image_data 数组,而不改变代码结构,因为然后使用这个数组关于我的图像处理算法。

【问题讨论】:

    标签: c++ image opencv colors


    【解决方案1】:

    在您编辑的第一条消息中,这一行很奇怪:

    image_data[0][i*width+j]=all_images[nb_image-1].at<cv::Vec3b>(i,j)[2];
    

    如果图像数据是你的彩色图像,那么它应该这样写:

    image_data[i][j] = all_images[nb_image-1].at<cv::Vec3b>(i,j);
    

    【讨论】:

    • 不知何故这不起作用,我还没有弄清楚问题出在哪里,但似乎更多来自我的内存分配部分,当 is 和 js 太高时它会崩溃但否则有效。现在它让我感到困惑,因为我有相同的代码和相同的分配,当只有一个通道时可以正常工作。我正在努力,如果我不能很快解决它,我想我会采取另一种方法。就像三个数组,类似于我用于灰度的数组,每个通道 1 个。不过,这听起来很重很麻烦。 &我想我也不是很清楚.. 抱歉尝试一下&thx
    【解决方案2】:

    这是我刚刚测试的代码,它可以工作。

    #include <iostream>
    #include <cstdlib>
    #include <opencv/cv.h>
    #include <opencv/highgui.h>
    
    int main(int argc, char**argv){
    
      cv::Mat img = cv::imread("image.jpg",1);
      cv::imshow("image",img);
      cv::waitKey(0);
      cv::Vec3b firstline[img.cols];
      for(int i=0;i<img.cols;i++){
        // access to matrix
        cv::Vec3b tmp = img.at<cv::Vec3b>(0,i);
        std::cout << (int)tmp(0) << " " << (int)tmp(1) << " " << (int)tmp(2) << std::endl;
        // access to my array
        firstline[i] = tmp;
        std::cout << (int)firstline[i](0) << " " << (int)firstline[i](0) << " " << (int)firstline[i](0) << std::endl;
      }
      return EXIT_SUCCESS;
    }
    

    【讨论】:

    • Erf,不幸的是,由于某种原因它不适用于我的代码。我不太愿意在这里完整地发布它,所以我会通过另一种方式解决我的问题。不过感谢您的帮助,您的解决方案确实有效,因此我将对其进行验证。
    • 虽然我发现它应该是 (int)tmp[0] 而不是 (int)tmp(0) (等等)
    • 在opencv官方文档中,对行矩阵cv::Matx实现了operator(int)。 cv::Vec3b 源自 cv::Matx。
    【解决方案3】:

    我不明白你到底想做什么。 您可以直接读取彩色图像:

    cv::Mat img = cv::imread("image.jpeg",1);

    您的矩阵 (img) 类型将为 CV_8UC3,然后您可以像您所说的那样访问每个像素:

    img.at&lt;cv::Vec3b&gt;(row,col)[channel].

    如果您有一个二维数组 Vec3bVec3b myArray[n][m]; 您可以访问这样的值:

    myArray[i][j](k) 其中 k={1,2,3} 因为 Vec3b 是行矩阵。

    【讨论】:

    • 是的,我想做的是您的最后一个建议,但是此代码不起作用。 myArray[i][j][k] 也不知道怎么弄!
    • 您能否发布您的整个代码,以便我们调试它。否则,为什么你绝对需要一个数组,因为 cv::Mat 可以访问 T* 数据。
    • 我用更清晰的解释和代码片段编辑了我的第一篇文章,它太长了,不适合在这里发表评论。
    • 找了几次,使用方法是:Vec3b强度= img.at(y, x); uchar blue = 强度.val[0]; uchar 绿色 = 强度.val[1]; uchar red = 强度.val[2];但是考虑到我有一个 Vec3b 数组,我不知道如何使用,因为这不起作用: Vec3b intensity[size_array];强度[i] = img.at(y, x);
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-12
    • 2013-09-15
    • 2021-11-25
    • 1970-01-01
    • 1970-01-01
    • 2019-01-31
    相关资源
    最近更新 更多