【问题标题】:how to read only one channel of image color from disk in opencv with C++如何使用C ++从opencv中的磁盘仅读取一个图像颜色通道
【发布时间】:2017-12-13 08:10:48
【问题描述】:

我需要读取大量具有高速要求的图像,并且只需要处理彩色图像的蓝色通道。 如果我用cv::imread(imgName, CV_LOAD_IMAGE_COLOR); 读取图像会很长时间,所以我只想读取一个彩色图像通道。怎么做 ???非常感谢!!

【问题讨论】:

  • 请添加您的代码示例。
  • 如果你知道图像数据是如何存储的,那么你就不会问这样的问题了。
  • 要加载图像,大多数都需要在获得像素值之前进行解码......但即使它是原始的,使用opencv也是不可能的......也许你可以做到这一点一个 SSD 驱动器可以更快地完成它....

标签: c++ opencv


【解决方案1】:

OpenCV 不提供任何仅加载特定通道的方法。但是,您有几个选择。


加载为彩色图像并提取您需要的通道

cv::Mat3b img("path/to/image", cv::IMREAD_COLOR);
cv::Mat1b blue;
cv::extractChannel(img, blue, 0);

这比使用split 方法快一点,但您仍然需要加载彩色图像。


在预处理阶段,加载所有图像(您可以使用glob 将所有图像检索到文件夹中),提取蓝色通道并将其存储为灰度。然后您可以将图像加载为灰度。

// Preprocessing

cv::String folder = "your_folder_with_images/*.jpg";
std::vector<cv::String> filenames;
cv::glob(folder, filenames);

for (size_t i = 0; i < std::filenames.size(); ++i)
{
    cv::Mat3b img = cv::imread(filenames[i], cv::IMREAD_COLOR);
    cv::Mat1b blue;
    cv::extractChannel(img, blue, 0);
    cv::imwrite("some/other/name", blue);
}

// Processing

cv::Mat1b blue = imread("path/to/image", cv::IMREAD_UNCHANGED);

您可以通过saving / loading the image in binary format提高速度:

// Preprocessing
...
matwrite("some/other/name", blue);

// Processing
cv::Mat1b blue = matread("path/to/image");

【讨论】:

    【解决方案2】:

    我认为你不能这样做,至少在 OpenCV 中是这样。如果您查看cv::imread 的文档,您会发现没有选项只能读取一个颜色通道:

    • IMREAD_UNCHANGED:如果设置,则按原样返回加载的图像(使用 alpha 通道,否则会被裁剪)。
    • IMREAD_GRAYSCALE:如果设置,则始终将图像转换为单通道灰度图像。
    • IMREAD_COLOR:如果设置,则始终将图像转换为 3 通道 BGR 彩色图像。
    • IMREAD_ANYDEPTH:如果设置,则在输入具有相应深度时返回 16 位/32 位图像,否则将其转换为 8 位。
    • IMREAD_ANYCOLOR:如果设置,则以任何可能的颜色格式读取图像。
    • IMREAD_LOAD_GDAL:如果设置,则使用 gdal 驱动程序加载图像。
    • IMREAD_REDUCED_GRAYSCALE_2:如果设置,则始终将图像转换为单通道灰度图像,图像尺寸缩小 1/2。
    • IMREAD_REDUCED_COLOR_2:如果设置,则始终将图像转换为 3 通道 BGR 彩色图像,并且图像尺寸缩小 1/2。
    • IMREAD_REDUCED_GRAYSCALE_4:如果设置,则始终将图像转换为单通道灰度图像,图像尺寸缩小 1/4。
    • IMREAD_REDUCED_COLOR_4:如果设置,则始终将图像转换为 3 通道 BGR 彩色图像,并且图像尺寸缩小 1/4。
    • IMREAD_REDUCED_GRAYSCALE_8:如果设置,则始终将图像转换为单通道灰度图像,图像尺寸缩小 1/8。
    • IMREAD_REDUCED_COLOR_8:如果设置,则始终将图像转换为 3 通道 BGR 彩色图像,并且图像尺寸缩小 1/8。
    • IMREAD_IGNORE_ORIENTATION:如果设置,则不要根据 EXIF 的方向标志旋转图像。

    如果你愿意,你可以在加载矩阵后使用Mat::split分割通道:

    Mat src = imread("img.png",CV_LOAD_IMAGE_COLOR); //load  image
    
    Mat bgr[3];   //destination array
    split(src,bgr);//split source  
    
    //Note: OpenCV uses BGR color order
    imwrite("blue.png",bgr[0]); //blue channel
    imwrite("green.png",bgr[1]); //green channel
    imwrite("red.png",bgr[2]); //red channel
    

    【讨论】:

    • 是的,我知道 mat::split。但我需要读取具有高速要求的图像。
    • 这样你就可以解释如何进行 CV_LOAD_IMAGE_GRAYSCALE 动作了。如果我用 CV_LOAD_IMAGE_GRAYSCALE 读取图像,速度会提高很多。但我需要蓝色通道颜色来处理图像,
    • 恐怕我的回答不能比这更进一步,这是我所拥有的知识。我刚刚发布了这个信息,因为你没有提到你已经知道了。如果这里没有人回答您的问题,您也可以在OpenCV forum 中尝试。
    • 可能您还有另一个选择,那就是挖掘cv::imread 的源代码并尝试查看如何更改它并仅加载您需要的内容。
    • 我相信这回答了 Q-“我只能在一个频道中阅读”A-否
    猜你喜欢
    • 1970-01-01
    • 2012-02-21
    • 1970-01-01
    • 2019-04-30
    • 2017-01-23
    • 2013-09-19
    • 2023-03-19
    • 1970-01-01
    • 2017-02-15
    相关资源
    最近更新 更多