in src/mlio/image_reader.cc [156:236]
bool Image_reader::decode_core(stdx::span<std::uint8_t> out, const Instance &instance) const
{
Memory_slice img_buf{};
if (params_.image_frame == Image_frame::recordio) {
// Skip the 24-byte header defined in image_recordio.h in the
// MXNet GitHub repository. This header contains metadata and
// is not relevant in our implementation.
img_buf = instance.bits().subslice(recordio_image_header_offset_);
}
else {
img_buf = instance.bits();
}
cv::Mat mat{1,
static_cast<int>(img_buf.size()),
CV_8U,
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
static_cast<void *>(const_cast<std::byte *>(img_buf.data()))};
cv::ImreadModes mode{};
int type{};
switch (img_dims_[0]) {
case 1:
mode = cv::ImreadModes::IMREAD_GRAYSCALE;
type = CV_8UC1;
break;
case 3:
mode = cv::ImreadModes::IMREAD_COLOR;
type = CV_8UC3;
break;
case 4:
mode = cv::ImreadModes::IMREAD_UNCHANGED;
type = CV_8UC4;
break;
default:
throw std::invalid_argument{fmt::format(
"The specified image dimensions have an unsupported number of channels ({0:n}).",
img_dims_[0])};
}
cv::Mat tmp = decode_image(mat, mode, instance);
if (tmp.empty()) {
return false;
}
if (params_.resize) {
if (!resize(tmp, tmp, instance)) {
return false;
}
}
if (params_.to_rgb && tmp.channels() != 1) {
try {
cv::cvtColor(tmp, tmp, cv::COLOR_BGR2RGB);
}
catch (const cv::Exception &e) {
if (warn_bad_instances() || error_bad_example_) {
auto msg = fmt::format(
"The BGR2RGB operation failed for the image #{1:n} in the data store '{0}' with the following exception: {2}",
instance.data_store().id(),
instance.index(),
e.what());
if (warn_bad_instances()) {
logger::warn(msg);
}
if (error_bad_example_) {
throw Invalid_instance_error{msg};
}
}
return false;
}
}
cv::Mat dst{img_dims_[1], img_dims_[2], type, out.data()};
return crop(tmp, dst, instance);
}