new function imread_reduced()
authorSuleyman TURKMEN <sturkmen@hotmail.com>
Sat, 27 Jun 2015 14:18:51 +0000 (17:18 +0300)
committerSuleyman TURKMEN <sturkmen@hotmail.com>
Sun, 19 Jul 2015 00:53:43 +0000 (03:53 +0300)
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

modules/imgcodecs/include/opencv2/imgcodecs.hpp
modules/imgcodecs/src/grfmt_base.cpp
modules/imgcodecs/src/grfmt_base.hpp
modules/imgcodecs/src/grfmt_jpeg.cpp
modules/imgcodecs/src/loadsave.cpp
modules/imgcodecs/src/precomp.hpp

index 91e44fb..b7c8633 100644 (file)
@@ -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.
index 267cb31..cda8b10 100644 (file)
@@ -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();
index dcb75b0..88e3ca7 100644 (file)
@@ -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;
index d6272e0..efe0058 100644 (file)
@@ -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;
         }
index 383c25a..a7bf46f 100644 (file)
@@ -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;
 }
@@ -412,6 +422,27 @@ Mat imread( const String& filename, int flags )
 }
 
 /**
+ * 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
 *
 *  This function merely calls the actual implementation above and returns itself.
index a5bbb41..101f015 100644 (file)
@@ -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"