【问题标题】:Are 16 bit images supported by Caffe? If not, how to implement support?Caffe 支持 16 位图像吗?如果没有,如何实施支持?
【发布时间】:2016-07-06 20:23:07
【问题描述】:

背景信息:我需要加载一些 16 位灰度 PNG。

Caffe 是否支持通过ImageDataLayer 加载 16 位图像?

经过一番谷歌搜索,答案似乎并非如此。 ImageDataLayer 依赖于 this io routine

cv::Mat ReadImageToCVMat(const string& filename,
    const int height, const int width, const bool is_color) {
  cv::Mat cv_img;
  int cv_read_flag = (is_color ? CV_LOAD_IMAGE_COLOR :
    CV_LOAD_IMAGE_GRAYSCALE);
  cv::Mat cv_img_origin = cv::imread(filename, cv_read_flag);
  if (!cv_img_origin.data) {
    LOG(ERROR) << "Could not open or find file " << filename;
    return cv_img_origin;
  }
  if (height > 0 && width > 0) {
    cv::resize(cv_img_origin, cv_img, cv::Size(width, height));
  } else {
    cv_img = cv_img_origin;
  }
  return cv_img;
}

使用opencv的cv::imread函数。除非设置了适当的标志,否则此函数会将输入读取为 8 位

CV_LOAD_IMAGE_ANYDEPTH - 如果设置,则返回 16 位/32 位图像,当 输入有对应的深度,否则转换为8位。

仅仅添加适当的标志是行不通的,因为稍后在代码 [io.cpp] 中他们检查 8 位深度:

void CVMatToDatum(const cv::Mat& cv_img, Datum* datum) {
  CHECK(cv_img.depth() == CV_8U) << "Image data type must be unsigned byte";
... }

我可以删除支票,但我担心它的存在是有原因的,并且可能会发生不可预知的结果。 任何人都可以阐明这个问题吗?

【问题讨论】:

    标签: image-processing machine-learning neural-network deep-learning caffe


    【解决方案1】:

    Caffe 默认使用float32 变量。图像通常表示为C-by-H-by-W blob,其中C=3 表示三个颜色通道。因此,使用float32 类型的三个通道可以让您处理uint16 中的图像,前提是您正确转换为float32

    我没有使用"ImageData" 层的个人经验,因此我无法评论您如何可以或不能使用该层加载uint16 图像数据。

    不过,您可能会发现"HDF5Data" 层很有用:您可以从外部读取图像并将其转换为hdf5 数据格式(支持float32),然后将转换后的数据提供给caffe通过"HDF5Data"层。

    您可以在"HDF5Data"herehere 找到更多信息。

    【讨论】:

    • HDF5Data 显然是一种可能性,但图像具有优势,imo,因为您实际上可以更好地可视化正在发生的事情。我也在使用 Nvidia 数字,它具有一些不错的额外可视化功能。我能做的是创建一个新的图层类型,它返回 float32 数据......任何提示从哪里开始做这个?
    • 恕我直言,如果你实现了一个新层,那么在可视化和 DIGITS 提供的额外功能方面你又回到了原点,那么为什么不使用你不需要实现的 HDF5Data 层呢?
    • 嗯,你是对的。要么我修改原始图层,要么完全使用另一种格式。比 LMBD 更喜欢 HDF5 的任何具体原因?
    • @Shai:Caffe 是否支持超过 3 个通道作为输入的图像?我的意思是我可以使用超过 3 个通道的输入矩阵(例如 20 个!)?还是我坚持使用 1d 和 3d 通道图像作为输入?
    • @Shai:非常感谢。顺便说一句,你为什么不创建一些 caffe 教程?你似乎对它了如指掌,而且 youtube 上甚至没有一个关于 caffe 的视频教程。如果你有时间,这将帮助很多人。无论如何,我真的很感激谢谢
    【解决方案2】:

    您可以像这样修补 ImageDataLayer 以读取 16 位图像:

    1. 添加您提到的适当标志 (io.cpp):

    之后

    int cv_read_flag = (is_color ? CV_LOAD_IMAGE_COLOR :
        CV_LOAD_IMAGE_GRAYSCALE);
    

    添加

    cv_read_flag |= CV_LOAD_IMAGE_ANYDEPTH;
    
    1. 修改你提到的检查(data_transformer.cpp):

    这个

    CHECK(cv_img.depth() == CV_8U) << "Image data type must be unsigned byte";
    

    变成

    CHECK(cv_img.depth() == CV_8U || cv_img.depth() == CV_16U) << "Image data type must be uint8 or uint16";
    bool is16bit = cv_img.depth() == CV_16U;
    
    1. 像这样修改 DataTransformer 读取 cv::Mat 的方式(下面的函数相同):

    将uint16_t类型的指针添加到:

    const uchar* ptr = cv_cropped_img.ptr<uchar>(h);
    

    喜欢这个

    const uint16_t* ptr_16 = cv_cropped_img.ptr<uint16_t>(h);
    

    然后使用适当的指针读取:

    Dtype pixel = static_cast<Dtype>(ptr[img_index++]);
    

    变成

    Dtype pixel;
    if(is16bit)
        pixel = static_cast<Dtype>(ptr_16[img_index++]);
    else
        pixel = static_cast<Dtype>(ptr[img_index++]);
    

    【讨论】:

      猜你喜欢
      • 2020-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-20
      • 2013-07-15
      • 2011-10-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多