// The method describes how input stream is transformed to the output stream. Called once per applied stream. // Scale transformer transforms the stream so that all samples are of the same size. StreamInformation ScaleTransformer::Transform(const StreamInformation& inputStream) { TransformBase::Transform(inputStream); auto dims = ImageDimensions(m_imgWidth, m_imgHeight, m_imgChannels).AsTensorShape(HWC).GetDims(); m_outputStream.m_sampleLayout = NDShape(std::vector<size_t>(dims.begin(), dims.end())); return m_outputStream; }
ImageDimensions GetClosestImageSize( Integration::ResourcePointer resourceBuffer, ImageDimensions size, FittingMode::Type fittingMode, SamplingMode::Type samplingMode, bool orientationCorrection ) { unsigned int width = 0; unsigned int height = 0; // Get the blob of binary data that we need to decode: DALI_ASSERT_DEBUG( resourceBuffer ); Dali::RefCountedVector<uint8_t>* const encodedBlob = reinterpret_cast<Dali::RefCountedVector<uint8_t>*>( resourceBuffer.Get() ); if( encodedBlob != 0 ) { const size_t blobSize = encodedBlob->GetVector().Size(); uint8_t * const blobBytes = &(encodedBlob->GetVector()[0]); DALI_ASSERT_DEBUG( blobSize > 0U ); DALI_ASSERT_DEBUG( blobBytes != 0U ); if( blobBytes != 0 && blobSize > 0U ) { // Open a file handle on the memory buffer: Internal::Platform::FileCloser fc( blobBytes, blobSize, "rb" ); FILE *fp = fc.GetFile(); if ( fp != NULL ) { LoadBitmapFunction loaderFunction; LoadBitmapHeaderFunction headerFunction; Bitmap::Profile profile; if ( GetBitmapLoaderFunctions( fp, FORMAT_UNKNOWN, loaderFunction, headerFunction, profile ) ) { const ImageLoader::Input input( fp, ScalingParameters( size, fittingMode, samplingMode ), orientationCorrection ); const bool read_res = headerFunction( input, width, height ); if( !read_res ) { DALI_LOG_WARNING( "Image Decoder failed to read header for resourceBuffer\n" ); } } } } } return ImageDimensions( width, height ); }
///@ToDo: Rename GetClosestImageSize() functions. Make them use the orientation correction and scaling information. Requires jpeg loader to tell us about reorientation. [Is there still a requirement for this functionality at all?] ImageDimensions GetClosestImageSize( const std::string& filename, ImageDimensions size, FittingMode::Type fittingMode, SamplingMode::Type samplingMode, bool orientationCorrection ) { unsigned int width = 0; unsigned int height = 0; Internal::Platform::FileCloser fc(filename.c_str(), "rb"); FILE *fp = fc.GetFile(); if (fp != NULL) { LoadBitmapFunction loaderFunction; LoadBitmapHeaderFunction headerFunction; Bitmap::Profile profile; if ( GetBitmapLoaderFunctions( fp, GetFormatHint(filename), loaderFunction, headerFunction, profile ) ) { const ImageLoader::Input input( fp, ScalingParameters( size, fittingMode, samplingMode ), orientationCorrection ); const bool read_res = headerFunction( input, width, height ); if(!read_res) { DALI_LOG_WARNING("Image Decoder failed to read header for %s\n", filename.c_str()); } } else { DALI_LOG_WARNING("Image Decoder for %s unavailable\n", filename.c_str()); } } return ImageDimensions( width, height ); }
// The method describes how input stream is transformed to the output stream. Called once per applied stream. // Scale transformer transforms the stream so that all samples are of the same size. StreamDescription ScaleTransformer::Transform(const StreamDescription& inputStream) { ImageTransformerBase::Transform(inputStream); m_outputStream.m_sampleLayout = std::make_shared<TensorShape>(ImageDimensions(m_imgWidth, m_imgHeight, m_imgChannels).AsTensorShape(HWC)); return m_outputStream; }
ImageConfigHelper::ImageConfigHelper(const ConfigParameters& config) : m_dataFormat(CHW) { std::vector<std::string> featureNames = GetSectionsWithParameter(config, "width"); std::vector<std::string> labelNames = GetSectionsWithParameter(config, "labelDim"); // REVIEW alexeyk: currently support only one feature and label section. if (featureNames.size() != 1 || labelNames.size() != 1) { RuntimeError( "ImageReader currently supports a single feature and label stream. '%d' features , '%d' labels found.", static_cast<int>(featureNames.size()), static_cast<int>(labelNames.size())); } ConfigParameters featureSection = config(featureNames[0]); size_t w = featureSection("width"); size_t h = featureSection("height"); size_t c = featureSection("channels"); std::string mbFmt = featureSection("mbFormat", "nchw"); if (AreEqualIgnoreCase(mbFmt, "nhwc") || AreEqualIgnoreCase(mbFmt, "legacy")) { m_dataFormat = HWC; } else if (!AreEqualIgnoreCase(mbFmt, "nchw") || AreEqualIgnoreCase(mbFmt, "cudnn")) { RuntimeError("ImageReader does not support the sample format '%s', only 'nchw' and 'nhwc' are supported.", mbFmt.c_str()); } auto features = std::make_shared<StreamDescription>(); features->m_id = 0; features->m_name = msra::strfun::utf16(featureSection.ConfigName()); features->m_sampleLayout = std::make_shared<TensorShape>(ImageDimensions(w, h, c).AsTensorShape(m_dataFormat)); m_streams.push_back(features); ConfigParameters label = config(labelNames[0]); size_t labelDimension = label("labelDim"); auto labelSection = std::make_shared<StreamDescription>(); labelSection->m_id = 1; labelSection->m_name = msra::strfun::utf16(label.ConfigName()); labelSection->m_sampleLayout = std::make_shared<TensorShape>(labelDimension); m_streams.push_back(labelSection); m_mapPath = config(L"file"); std::string rand = config(L"randomize", "auto"); if (AreEqualIgnoreCase(rand, "auto")) { m_randomize = true; } else if (AreEqualIgnoreCase(rand, "none")) { m_randomize = false; } else { RuntimeError("'randomize' parameter must be set to 'auto' or 'none'"); } // Identify precision string precision = config.Find("precision", "float"); if (AreEqualIgnoreCase(precision, "float")) { features->m_elementType = ElementType::tfloat; labelSection->m_elementType = ElementType::tfloat; } else if (AreEqualIgnoreCase(precision, "double")) { features->m_elementType = ElementType::tdouble; labelSection->m_elementType = ElementType::tdouble; } else { RuntimeError("Not supported precision '%s'. Expected 'double' or 'float'.", precision.c_str()); } m_cpuThreadCount = config(L"numCPUThreads", 0); }
Image NewImage( const Property::Value& property ) { Image ret; std::string filename; Internal::ImageAttributes attributes = Internal::ImageAttributes::New(); const Property::Map* map = property.GetMap(); ImageType imageType = RESOURCE_IMAGE; // default to resource image if( map ) { // first check the type as it determines, which other parameters are needed const Property::Value* value = map->Find( "type" ); if( value ) { std::string type; value->Get( type ); for( unsigned int i = 0; i < imageTypeCount; ++i ) { if( 0 == type.compare( ImageTypeName[ i ] ) ) { imageType = static_cast<ImageType>( i ); break; } } } // filename is only needed for resource images if( RESOURCE_IMAGE == imageType ) { const Property::Value* value = map->Find( "filename" ); if( value ) { value->Get( filename ); } // if empty file, no need to go further if( filename.size() == 0 ) { DALI_LOG_ERROR( "No filename\n" ); return Image(); } } // Width and height can be set individually. Dali derives the unspecified // dimension from the aspect ratio of the raw image. int width = 0, height = 0; value = map->Find( "width" ); if( value ) { // handle floats and integer the same for json script if( value->GetType() == Property::FLOAT ) { width = static_cast<unsigned int>( value->Get<float>() ); } else { value->Get( width ); } } value = map->Find( "height" ); if( value ) { if( value->GetType() == Property::FLOAT ) { height = static_cast<int>( value->Get<float>() ); } else { value->Get( height ); } } attributes.SetSize( width, height ); Pixel::Format pixelFormat = Pixel::RGBA8888; value = map->Find( "pixelFormat" ); if( value ) { std::string format; value->Get( format ); GetEnumeration< Pixel::Format >( format.c_str(), PIXEL_FORMAT_TABLE, PIXEL_FORMAT_TABLE_COUNT, pixelFormat ); } value = map->Find( "fittingMode" ); if( value ) { std::string fitting; value->Get( fitting ); FittingMode::Type mode; if( GetEnumeration< FittingMode::Type >( fitting.c_str(), IMAGE_FITTING_MODE_TABLE, IMAGE_FITTING_MODE_TABLE_COUNT, mode ) ) { attributes.SetScalingMode( mode ); } } value = map->Find( "samplingMode" ); if( value ) { std::string sampling; value->Get( sampling ); SamplingMode::Type mode; if( GetEnumeration< SamplingMode::Type >( sampling.c_str(), IMAGE_SAMPLING_MODE_TABLE, IMAGE_SAMPLING_MODE_TABLE_COUNT, mode ) ) { attributes.SetFilterMode( mode ); } } value = map->Find( "orientation" ); if( value ) { bool b = value->Get<bool>(); attributes.SetOrientationCorrection( b ); } switch( imageType ) { case RESOURCE_IMAGE : { ret = ResourceImage::New( filename, ImageDimensions( attributes.GetSize().x, attributes.GetSize().y ), attributes.GetScalingMode(), attributes.GetFilterMode(), attributes.GetOrientationCorrection() ); break; } case BUFFER_IMAGE : { ret = BufferImage::New( attributes.GetWidth(), attributes.GetHeight(), pixelFormat ); break; } case FRAME_BUFFER_IMAGE : { ret = FrameBufferImage::New( attributes.GetWidth(), attributes.GetHeight(), pixelFormat ); break; } } } return ret; } // Image NewImage( Property::Value map )