Caffe支持16位图像吗?如果没有,如何实施支持?

时间:2016-03-20 09:40:07

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

背景信息:我需要加载一些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";
... }

我可以删除支票,但我担心它有一个原因,可能会发生不可预测的结果。 任何人都可以对这个问题有所了解吗?

2 个答案:

答案 0 :(得分:2)

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

  1. 按照您提到的(io.cpp)添加适当的标志:
  2. 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):
    2. 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的方式(下面相同的功能):
      2. 将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++]);
        

答案 1 :(得分:1)

默认情况下,Caffe使用float32个变量。图像通常表示为C - by - H - by - W blob,其中C=3表示三个颜色通道。因此,如果您正确转换为float32,则使用uint16类型的三个频道可以处理float32中的图片。

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

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

您可以在"HDF5Data"图层herehere上找到更多相关信息。