【问题标题】:How to convert an int[] to an OpenCV Mat? (and vice-versa)如何将 int[] 转换为 OpenCV Mat? (反之亦然)
【发布时间】:2015-02-05 11:03:20
【问题描述】:

我正在从 PNG 中读取 bufferedImages,并使用 PixelGrabber 将它们转换为 int 数组。那么我的问题是:如何使用整数数组来制作相应的 OpenCV Mat?其中数组是一维的,每个值代表一个像素的组合 RGB 值。

我已经尝试过使用字节数组。

【问题讨论】:

  • 组合RGB值是什么意思?
  • 什么是“组合RGB”?您的意思是 int 的第一个字节是您的 R 值,第二个 G 和第三个字节是 B 值?最后一个字节的随机值是什么?您可以将每个 int 读取为 32 位 RGBA 值。
  • @Micka 从 pixelGrabber 读取像素时发生的任何事情,我都不完全确定存储在 int 中的数据。我所知道的是要获得红色 (rgbvalue >> 16) & 0xff;绿色 (rgbvalue >> 8) & 0xff;蓝色是 rgbvalue & 0xff;这有帮助吗?
  • 不幸的是,这对于 opencv 来说不是最优的,所以你必须转换你的数据......稍后我会给出一些代码。基本上您可以: 将数据加载为 BGRA。拆分渠道并重新解释渠道:B=>waste; G=>R; R=>G; A=>B 除非 ppencv 中存在 ARGB 颜色类型,否则它会更容易更快...
  • 啊好吧...不像我预期的那样,顺序是相反的,这很好。我会给你 C++ 代码,它应该对 java 工作非常相似

标签: java arrays image opencv bufferedimage


【解决方案1】:

只需将 32 位 int 值解释为 32 位 RGBA 值。我不知道为什么您不必更改通道的顺序,但是使用 int 数组作为cv::Mat 的输入,您会自动获得 BGRA 排序。然后,您只需在需要时移除 Alpha 通道。

int main()
{
    // the idea is that each int is 32 bit which is 4 channels of 8 bit color values instead of 3 channels, so assume a 4th channel.

    // first I create fake intArray which should be replaced by your input...
    const int imgWidth = 320;
    const int imgHeight = 210;
    int intArray[imgWidth*imgHeight]; // int array

    // fill the array with some test values:
    for(unsigned int pos = 0; pos < imgWidth*imgHeight; ++pos)
        intArray[pos] = 8453889; // 00000000 10000000 11111111 00000001 => R = 128, G = 255, B = 1
        //intArray[pos] = 65280;    // green
        //intArray[pos] = 16711680; // red
        //intArray[pos] = 255;  // blue

    // test:
    int firstVal = intArray[0];
    std::cout << "values: " << " int: " << firstVal << " R = " <<  ((firstVal >> 16) & 0xff) << " G = " << ((firstVal >> 8) & 0xff) << " B = " << (firstVal  & 0xff) << std::endl;

    // here you create the Mat and use your int array as input
    cv::Mat intMat_BGRA = cv::Mat(imgHeight,imgWidth,CV_8UC4, intArray); 
    // now you have a 4 channel mat with each pixel is one of your int, but with wrong order...
    std::cout << "BGRA ordering: " << intMat_BGRA.at<cv::Vec4b>(0,0) << std::endl;
    // this is in fact the BGRA ordering but you have to remove the alpha channel to get BGR values:
    // (unless you can live with BGRA values => you have to check whether there is garbage or 0s/255s in the byte area

    // so split the channels...
    std::vector<cv::Mat> BGRA_channels;
    cv::split(intMat_BGRA, BGRA_channels);

    // remove the alpha channel:
    BGRA_channels.pop_back();

    // and merge back to image:
    cv::Mat intMat_BGR;
    cv::merge(BGRA_channels, intMat_BGR);

    std::cout << "BGR ordering: " << intMat_BGR.at<cv::Vec3b>(0,0) << std::endl;

    cv::imshow("ordereed", intMat_BGR);

    cv::waitKey(0);
    return 0;
}

给我输出:

values:  int: 8453889 R = 128 G = 255 B = 1
BGRA ordering: [1, 255, 128, 0]
BGR ordering: [1, 255, 128]

【讨论】:

  • 非常感谢;它需要成为openCV的一部分的BGR,还是因为我定义int []的方式?我的意思是,几乎没有任何东西(我遇到过)使用 BGR 而不是 RGB...
  • Afaik BGR 字节顺序是大多数图像库(例如directX)中RGB图像的标准。例如,在显示图像时,OpenCV 假定 bgr 排序
猜你喜欢
  • 2016-08-16
  • 2015-06-28
  • 1970-01-01
  • 2021-06-10
  • 1970-01-01
  • 1970-01-01
  • 2020-03-01
  • 1970-01-01
  • 2020-10-24
相关资源
最近更新 更多