From 7b7d54df6821aa85479a81df15e6603be9b450d1 Mon Sep 17 00:00:00 2001 From: Suleyman TURKMEN Date: Sat, 27 Jun 2015 17:18:51 +0300 Subject: [PATCH] new function imread_reduced() by this new function we can set libjpeg "scale_denom" parameter and load jpeg images scaled 1/2 - 1/4 - 1/8 other image formats resized after loading --- .../imgcodecs/include/opencv2/imgcodecs.hpp | 8 +++++ modules/imgcodecs/src/grfmt_base.cpp | 8 +++++ modules/imgcodecs/src/grfmt_base.hpp | 2 ++ modules/imgcodecs/src/grfmt_jpeg.cpp | 8 +++-- modules/imgcodecs/src/loadsave.cpp | 33 ++++++++++++++++++- modules/imgcodecs/src/precomp.hpp | 1 + 6 files changed, 57 insertions(+), 3 deletions(-) diff --git a/modules/imgcodecs/include/opencv2/imgcodecs.hpp b/modules/imgcodecs/include/opencv2/imgcodecs.hpp index 91e44fb869..b7c8633cef 100644 --- a/modules/imgcodecs/include/opencv2/imgcodecs.hpp +++ b/modules/imgcodecs/include/opencv2/imgcodecs.hpp @@ -131,6 +131,14 @@ returns an empty matrix ( Mat::data==NULL ). Currently, the following file forma */ CV_EXPORTS_W Mat imread( const String& filename, int flags = IMREAD_COLOR ); +/** @brief Loads and resizes down an image from a file. +@anchor imread_reduced +@param filename Name of file to be loaded. +@param flags Flag that can take values of @ref cv::ImreadModes +@param scale_denom + */ +CV_EXPORTS_W Mat imread_reduced( const String& filename, int flags = IMREAD_COLOR, int scale_denom=1 ); + /** @brief Loads a multi-page image from a file. (see imread for details.) @param filename Name of file to be loaded. diff --git a/modules/imgcodecs/src/grfmt_base.cpp b/modules/imgcodecs/src/grfmt_base.cpp index 267cb31b57..cda8b10b5e 100644 --- a/modules/imgcodecs/src/grfmt_base.cpp +++ b/modules/imgcodecs/src/grfmt_base.cpp @@ -52,6 +52,7 @@ BaseImageDecoder::BaseImageDecoder() m_width = m_height = 0; m_type = -1; m_buf_supported = false; + m_scale_denom = 1; } bool BaseImageDecoder::setSource( const String& filename ) @@ -81,6 +82,13 @@ bool BaseImageDecoder::checkSignature( const String& signature ) const return signature.size() >= len && memcmp( signature.c_str(), m_signature.c_str(), len ) == 0; } +int BaseImageDecoder::setScale( const int& scale_denom ) +{ + int temp = m_scale_denom; + m_scale_denom = scale_denom; + return temp; +} + ImageDecoder BaseImageDecoder::newDecoder() const { return ImageDecoder(); diff --git a/modules/imgcodecs/src/grfmt_base.hpp b/modules/imgcodecs/src/grfmt_base.hpp index dcb75b0dcd..88e3ca7c1c 100644 --- a/modules/imgcodecs/src/grfmt_base.hpp +++ b/modules/imgcodecs/src/grfmt_base.hpp @@ -67,6 +67,7 @@ public: virtual bool setSource( const String& filename ); virtual bool setSource( const Mat& buf ); + virtual int setScale( const int& scale_denom ); virtual bool readHeader() = 0; virtual bool readData( Mat& img ) = 0; @@ -81,6 +82,7 @@ protected: int m_width; // width of the image ( filled by readHeader ) int m_height; // height of the image ( filled by readHeader ) int m_type; + int m_scale_denom; String m_filename; String m_signature; Mat m_buf; diff --git a/modules/imgcodecs/src/grfmt_jpeg.cpp b/modules/imgcodecs/src/grfmt_jpeg.cpp index d6272e00db..efe0058fff 100644 --- a/modules/imgcodecs/src/grfmt_jpeg.cpp +++ b/modules/imgcodecs/src/grfmt_jpeg.cpp @@ -242,8 +242,12 @@ bool JpegDecoder::readHeader() { jpeg_read_header( &state->cinfo, TRUE ); - m_width = state->cinfo.image_width; - m_height = state->cinfo.image_height; + state->cinfo.scale_num=1; + state->cinfo.scale_denom = m_scale_denom; + m_scale_denom=1; // trick! to know which decoder used scale_denom see imread_ + jpeg_calc_output_dimensions(&state->cinfo); + m_width = state->cinfo.output_width; + m_height = state->cinfo.output_height; m_type = state->cinfo.num_components > 1 ? CV_8UC3 : CV_8UC1; result = true; } diff --git a/modules/imgcodecs/src/loadsave.cpp b/modules/imgcodecs/src/loadsave.cpp index 383c25a2b3..a7bf46f427 100644 --- a/modules/imgcodecs/src/loadsave.cpp +++ b/modules/imgcodecs/src/loadsave.cpp @@ -234,10 +234,11 @@ enum { LOAD_CVMAT=0, LOAD_IMAGE=1, LOAD_MAT=2 }; * LOAD_MAT=2 * } * @param[in] mat Reference to C++ Mat object (If LOAD_MAT) + * @param[in] scale_denom Scale value * */ static void* -imread_( const String& filename, int flags, int hdrtype, Mat* mat=0 ) +imread_( const String& filename, int flags, int hdrtype, Mat* mat=0, int scale_denom=1 ) { IplImage* image = 0; CvMat *matrix = 0; @@ -261,6 +262,9 @@ imread_( const String& filename, int flags, int hdrtype, Mat* mat=0 ) return 0; } + /// set the scale_denom in the driver + decoder->setScale( scale_denom ); + /// set the filename in the driver decoder->setSource(filename); @@ -316,6 +320,12 @@ imread_( const String& filename, int flags, int hdrtype, Mat* mat=0 ) return 0; } + int testdecoder = decoder->setScale( scale_denom ); // if decoder is JpegDecoder then testdecoder will be 1 + if( (scale_denom > 1 ) & ( testdecoder > 1 ) ) + { + resize(*mat,*mat,Size(size.width/scale_denom,size.height/scale_denom)); + } + return hdrtype == LOAD_CVMAT ? (void*)matrix : hdrtype == LOAD_IMAGE ? (void*)image : (void*)mat; } @@ -411,6 +421,27 @@ Mat imread( const String& filename, int flags ) return img; } +/** + * Read an image and resize it + * + * This function merely calls the actual implementation above and returns itself. + * + * @param[in] filename File to load + * @param[in] flags Flags you wish to set. + * @param[in] scale_denom Scale value +*/ +Mat imread_reduced( const String& filename, int flags, int scale_denom ) +{ + /// create the basic container + Mat img; + + /// load the data + imread_( filename, flags, LOAD_MAT, &img, scale_denom ); + + /// return a reference to the data + return img; +} + /** * Read a multi-page image * diff --git a/modules/imgcodecs/src/precomp.hpp b/modules/imgcodecs/src/precomp.hpp index a5bbb41918..101f01577c 100644 --- a/modules/imgcodecs/src/precomp.hpp +++ b/modules/imgcodecs/src/precomp.hpp @@ -47,6 +47,7 @@ #include "opencv2/core/utility.hpp" #include "opencv2/core/private.hpp" +#include "opencv2/imgproc.hpp" #include "opencv2/imgproc/imgproc_c.h" #include "opencv2/imgcodecs/imgcodecs_c.h"