图片在使用前,如果获取渠道无法保证图片的可用性, 完整性,则需要提前过滤一遍. 否则, 如果是深度模型训练到一半出现错误,比较浪费时间,还需要再重新处理。

破损图片在 opencv 等读取时可能会出现类似错误:

Premature end of JPEG file

采用 Caffe 生成 LDMB 训练数据集的格式, 会有自动的图片筛选滤除:

    status = ReadImageToDatum(root_folder + lines[line_id].first,
        lines[line_id].second, resize_height, resize_width, is_color,
        enc, &datum); // status 判断 opencv 是否正确读取
    if (status == false) 
        continue;
bool ReadImageToDatum(const string& filename, const int label,
    const int height, const int width, const bool is_color,
    const std::string & encoding, Datum* datum) {
  cv::Mat cv_img = ReadImageToCVMat(filename, height, width, is_color); //
  if (cv_img.data) {
    if (encoding.size()) {
      if ( (cv_img.channels() == 3) == is_color && !height && !width &&
          matchExt(filename, encoding) )
        return ReadFileToDatum(filename, label, datum);
      std::vector<uchar> buf;
      cv::imencode("."+encoding, cv_img, buf);
      datum->set_data(std::string(reinterpret_cast<char*>(&buf[0]),
                      buf.size()));
      datum->set_label(label);
      datum->set_encoded(true);
      return true;
    }
    CVMatToDatum(cv_img, datum);
    datum->set_label(label);
    return true;
  } else {
    return false;
  }
}

但如果是其它方式, 还是建议过滤一遍图片:
如, 基于 Python,

import skimage
import skimage.io
datas = open('images_list.txt').readlines()
f = open('images_list_filter.txt', 'w')
for idx in range(len(datas)):
     print '----', idx, '----'
     image_file = os.path.join(nfsdata, datas[idx].split(' ')[0])
     try:
         img = skimage.io.imread(image_file)
         f.write(datas[idx])
     except:
         print image_file
f.close()

参考:opencv读图片Premature end of JPEG file?.

Last modification:October 9th, 2018 at 09:31 am