gpt4 book ai didi

arrays - Opencv:将 RGB 矩阵转换为一维数组

转载 作者:太空宇宙 更新时间:2023-11-03 22:30:20 24 4
gpt4 key购买 nike

如何将 RGB 垫作为一维数组访问?我查看了文档,但找不到 3 channel 数据在这种情况下的布局方式。

我试图用 1 个 for 循环遍历每个像素,从 n=0n = img.rows*img.cols - 1,然后访问每个像素的 R、G 和 B 值。

如有任何帮助,我们将不胜感激。

最佳答案

我真的不明白为什么你真的只需要 1 个循环,所以我会向你推荐几个我根据经验知道效率高的选项(包括 1 或 2 个 for 循环)。

如果您真的想以一种安全的方式只用一个循环遍历所有值,您可以使用 cv::Mat reshape 矩阵并将 3 channel 2D 图像转换为 1 channel 1D 数组::reshape(...) ( doc ):

cv::Mat rgbMat = cv::imread(...); // Read original image

// As a 1D-1 channel, we have 1 channel and 3*the number of pixels samples
cv::Mat arrayFromRgb = rgbMat.reshape(1, rgbMat.channels()*rgbMat.size().area());

有两个注意事项:

  • reshape() 返回一个新的 cv::Mat 引用,因此它的输出需要分配给一个变量(它不会就地操作)
  • 您不能更改矩阵中元素的数量。

OpenCV 以行优先顺序存储矩阵数据。因此,另一种方法是通过获取指向每一行开始的指针来遍历行。这样,您就不会因为行末可能的填充数据而做任何不安全的事情:

cv::Mat rgbMat = cv::imread(...);

for (int y = 0; y < rgbMat.size().height; ++y) {

// Option 1: get a pointer to a 3-channel element
cv::Vec3b* pointerToRgbPixel = rgbMat.ptr<cv::Vec3b>(y);

for (int x = 0; x < rgbMat.size().width; ++x, ++pointerToRgbPixel) {

uint8_t blue = (*pointerToRgbPixel )[0];
uint8_t green = (*pointerToRgbPixel )[1];
uint8_t red = (*pointerToRgbPixel )[2];

DoSomething(red, green, blue);
}

// Option 2: get a pointer to the first sample and iterate
uint8_t* pointerToSample = rgbMat.ptr<uint8_t>(y);

for (int x = 0; x < rgbMat.channels()*rgbMat.size().width; ++x) {
DoSomething(*pointerToSample);
++pointerToSample;
}
}

为什么我喜欢对行进行迭代?因为很容易并联。如果您有一台多核计算机,您可以使用任何框架(例如 OpenMP 或 GCD)以安全的方式并行处理每一行。使用 OpenMP,就像在外层循环之前添加一个 #pragma parallel for 一样简单。

关于arrays - Opencv:将 RGB 矩阵转换为一维数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27114425/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com