mirror of
https://github.com/opencv/opencv.git
synced 2025-06-09 10:40:46 +08:00
Added IMREAD_IGNORE_ORIENTATION flag
This commit is contained in:
parent
17ffb28807
commit
f893ee5cec
@ -67,8 +67,8 @@ list(APPEND grfmt_hdrs ${CMAKE_CURRENT_LIST_DIR}/src/bitstrm.hpp)
|
|||||||
list(APPEND grfmt_srcs ${CMAKE_CURRENT_LIST_DIR}/src/bitstrm.cpp)
|
list(APPEND grfmt_srcs ${CMAKE_CURRENT_LIST_DIR}/src/bitstrm.cpp)
|
||||||
list(APPEND grfmt_hdrs ${CMAKE_CURRENT_LIST_DIR}/src/rgbe.hpp)
|
list(APPEND grfmt_hdrs ${CMAKE_CURRENT_LIST_DIR}/src/rgbe.hpp)
|
||||||
list(APPEND grfmt_srcs ${CMAKE_CURRENT_LIST_DIR}/src/rgbe.cpp)
|
list(APPEND grfmt_srcs ${CMAKE_CURRENT_LIST_DIR}/src/rgbe.cpp)
|
||||||
list(APPEND grfmt_hdrs ${CMAKE_CURRENT_LIST_DIR}/src/jpeg_exif.hpp)
|
list(APPEND grfmt_hdrs ${CMAKE_CURRENT_LIST_DIR}/src/exif.hpp)
|
||||||
list(APPEND grfmt_srcs ${CMAKE_CURRENT_LIST_DIR}/src/jpeg_exif.cpp)
|
list(APPEND grfmt_srcs ${CMAKE_CURRENT_LIST_DIR}/src/exif.cpp)
|
||||||
|
|
||||||
source_group("Src\\grfmts" FILES ${grfmt_hdrs} ${grfmt_srcs})
|
source_group("Src\\grfmts" FILES ${grfmt_hdrs} ${grfmt_srcs})
|
||||||
|
|
||||||
|
@ -73,7 +73,8 @@ enum ImreadModes {
|
|||||||
IMREAD_REDUCED_GRAYSCALE_4 = 32, //!< If set, always convert image to the single channel grayscale image and the image size reduced 1/4.
|
IMREAD_REDUCED_GRAYSCALE_4 = 32, //!< If set, always convert image to the single channel grayscale image and the image size reduced 1/4.
|
||||||
IMREAD_REDUCED_COLOR_4 = 33, //!< If set, always convert image to the 3 channel BGR color image and the image size reduced 1/4.
|
IMREAD_REDUCED_COLOR_4 = 33, //!< If set, always convert image to the 3 channel BGR color image and the image size reduced 1/4.
|
||||||
IMREAD_REDUCED_GRAYSCALE_8 = 64, //!< If set, always convert image to the single channel grayscale image and the image size reduced 1/8.
|
IMREAD_REDUCED_GRAYSCALE_8 = 64, //!< If set, always convert image to the single channel grayscale image and the image size reduced 1/8.
|
||||||
IMREAD_REDUCED_COLOR_8 = 65 //!< If set, always convert image to the 3 channel BGR color image and the image size reduced 1/8.
|
IMREAD_REDUCED_COLOR_8 = 65, //!< If set, always convert image to the 3 channel BGR color image and the image size reduced 1/8.
|
||||||
|
IMREAD_IGNORE_ORIENTATION = 128 //!< If set, do not rotate the image according to EXIF's orientation flag.
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Imwrite flags
|
//! Imwrite flags
|
||||||
|
@ -63,7 +63,9 @@ enum
|
|||||||
/* any depth, ? */
|
/* any depth, ? */
|
||||||
CV_LOAD_IMAGE_ANYDEPTH =2,
|
CV_LOAD_IMAGE_ANYDEPTH =2,
|
||||||
/* ?, any color */
|
/* ?, any color */
|
||||||
CV_LOAD_IMAGE_ANYCOLOR =4
|
CV_LOAD_IMAGE_ANYCOLOR =4,
|
||||||
|
/* ?, no rotate */
|
||||||
|
CV_LOAD_IMAGE_IGNORE_ORIENTATION =128
|
||||||
};
|
};
|
||||||
|
|
||||||
/* load image from file
|
/* load image from file
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
//
|
//
|
||||||
//M*/
|
//M*/
|
||||||
|
|
||||||
#include "jpeg_exif.hpp"
|
#include "exif.hpp"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@ -73,7 +73,7 @@ ExifReader::~ExifReader()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Parsing the jpeg file and prepare (internally) exif directory structure
|
* @brief Parsing the file and prepare (internally) exif directory structure
|
||||||
* @return true if parsing was successful and exif information exists in JpegReader object
|
* @return true if parsing was successful and exif information exists in JpegReader object
|
||||||
* false in case of unsuccessful parsing
|
* false in case of unsuccessful parsing
|
||||||
*/
|
*/
|
||||||
@ -114,7 +114,7 @@ ExifEntry_t ExifReader::getTag(const ExifTagName tag)
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get exif directory structure contained in jpeg file (if any)
|
* @brief Get exif directory structure contained in file (if any)
|
||||||
* This is internal function and is not exposed to client
|
* This is internal function and is not exposed to client
|
||||||
*
|
*
|
||||||
* @return Map where key is tag number and value is ExifEntry_t structure
|
* @return Map where key is tag number and value is ExifEntry_t structure
|
@ -41,8 +41,8 @@
|
|||||||
//M*/
|
//M*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _OPENCV_JPEG_EXIF_HPP_
|
#ifndef _OPENCV_EXIF_HPP_
|
||||||
#define _OPENCV_JPEG_EXIF_HPP_
|
#define _OPENCV_EXIF_HPP_
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <map>
|
#include <map>
|
||||||
@ -131,21 +131,21 @@ struct ExifEntry_t
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Picture orientation which may be taken from JPEG's EXIF
|
* @brief Picture orientation which may be taken from EXIF
|
||||||
* Orientation usually matters when the picture is taken by
|
* Orientation usually matters when the picture is taken by
|
||||||
* smartphone or other camera with orientation sensor support
|
* smartphone or other camera with orientation sensor support
|
||||||
* Corresponds to EXIF 2.3 Specification
|
* Corresponds to EXIF 2.3 Specification
|
||||||
*/
|
*/
|
||||||
enum JpegOrientation
|
enum ImageOrientation
|
||||||
{
|
{
|
||||||
JPEG_ORIENTATION_TL = 1, ///< 0th row == visual top, 0th column == visual left-hand side
|
IMAGE_ORIENTATION_TL = 1, ///< Horizontal (normal)
|
||||||
JPEG_ORIENTATION_TR = 2, ///< 0th row == visual top, 0th column == visual right-hand side
|
IMAGE_ORIENTATION_TR = 2, ///< Mirrored horizontal
|
||||||
JPEG_ORIENTATION_BR = 3, ///< 0th row == visual bottom, 0th column == visual right-hand side
|
IMAGE_ORIENTATION_BR = 3, ///< Rotate 180
|
||||||
JPEG_ORIENTATION_BL = 4, ///< 0th row == visual bottom, 0th column == visual left-hand side
|
IMAGE_ORIENTATION_BL = 4, ///< Mirrored vertical
|
||||||
JPEG_ORIENTATION_LT = 5, ///< 0th row == visual left-hand side, 0th column == visual top
|
IMAGE_ORIENTATION_LT = 5, ///< Mirrored horizontal & rotate 270 CW
|
||||||
JPEG_ORIENTATION_RT = 6, ///< 0th row == visual right-hand side, 0th column == visual top
|
IMAGE_ORIENTATION_RT = 6, ///< Rotate 90 CW
|
||||||
JPEG_ORIENTATION_RB = 7, ///< 0th row == visual right-hand side, 0th column == visual bottom
|
IMAGE_ORIENTATION_RB = 7, ///< Mirrored horizontal & rotate 90 CW
|
||||||
JPEG_ORIENTATION_LB = 8 ///< 0th row == visual left-hand side, 0th column == visual bottom
|
IMAGE_ORIENTATION_LB = 8 ///< Rotate 270 CW
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -250,4 +250,4 @@ private:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* JPEG_EXIF_HPP_ */
|
#endif /* _OPENCV_EXIF_HPP_ */
|
@ -41,7 +41,6 @@
|
|||||||
|
|
||||||
#include "precomp.hpp"
|
#include "precomp.hpp"
|
||||||
#include "grfmt_jpeg.hpp"
|
#include "grfmt_jpeg.hpp"
|
||||||
#include "jpeg_exif.hpp"
|
|
||||||
|
|
||||||
#ifdef HAVE_JPEG
|
#ifdef HAVE_JPEG
|
||||||
|
|
||||||
@ -178,7 +177,6 @@ JpegDecoder::JpegDecoder()
|
|||||||
m_state = 0;
|
m_state = 0;
|
||||||
m_f = 0;
|
m_f = 0;
|
||||||
m_buf_supported = true;
|
m_buf_supported = true;
|
||||||
m_orientation = JPEG_ORIENTATION_TL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -255,71 +253,12 @@ bool JpegDecoder::readHeader()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_orientation = getOrientation();
|
|
||||||
|
|
||||||
if( !result )
|
if( !result )
|
||||||
close();
|
close();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int JpegDecoder::getOrientation()
|
|
||||||
{
|
|
||||||
int orientation = JPEG_ORIENTATION_TL;
|
|
||||||
|
|
||||||
if (m_filename.size() > 0)
|
|
||||||
{
|
|
||||||
ExifReader reader( m_filename );
|
|
||||||
if( reader.parse() )
|
|
||||||
{
|
|
||||||
ExifEntry_t entry = reader.getTag( ORIENTATION );
|
|
||||||
if (entry.tag != INVALID_TAG)
|
|
||||||
{
|
|
||||||
orientation = entry.field_u16; //orientation is unsigned short, so check field_u16
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return orientation;
|
|
||||||
}
|
|
||||||
|
|
||||||
void JpegDecoder::setOrientation(Mat& img)
|
|
||||||
{
|
|
||||||
switch( m_orientation )
|
|
||||||
{
|
|
||||||
case JPEG_ORIENTATION_TL: //0th row == visual top, 0th column == visual left-hand side
|
|
||||||
//do nothing, the image already has proper orientation
|
|
||||||
break;
|
|
||||||
case JPEG_ORIENTATION_TR: //0th row == visual top, 0th column == visual right-hand side
|
|
||||||
flip(img, img, 1); //flip horizontally
|
|
||||||
break;
|
|
||||||
case JPEG_ORIENTATION_BR: //0th row == visual bottom, 0th column == visual right-hand side
|
|
||||||
flip(img, img, -1);//flip both horizontally and vertically
|
|
||||||
break;
|
|
||||||
case JPEG_ORIENTATION_BL: //0th row == visual bottom, 0th column == visual left-hand side
|
|
||||||
flip(img, img, 0); //flip vertically
|
|
||||||
break;
|
|
||||||
case JPEG_ORIENTATION_LT: //0th row == visual left-hand side, 0th column == visual top
|
|
||||||
transpose(img, img);
|
|
||||||
break;
|
|
||||||
case JPEG_ORIENTATION_RT: //0th row == visual right-hand side, 0th column == visual top
|
|
||||||
transpose(img, img);
|
|
||||||
flip(img, img, 1); //flip horizontally
|
|
||||||
break;
|
|
||||||
case JPEG_ORIENTATION_RB: //0th row == visual right-hand side, 0th column == visual bottom
|
|
||||||
transpose(img, img);
|
|
||||||
flip(img, img, -1); //flip both horizontally and vertically
|
|
||||||
break;
|
|
||||||
case JPEG_ORIENTATION_LB: //0th row == visual left-hand side, 0th column == visual bottom
|
|
||||||
transpose(img, img);
|
|
||||||
flip(img, img, 0); //flip vertically
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
//by default the image read has normal (JPEG_ORIENTATION_TL) orientation
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* following code is for supporting MJPEG image files
|
* following code is for supporting MJPEG image files
|
||||||
* based on a message of Laurent Pinchart on the video4linux mailing list
|
* based on a message of Laurent Pinchart on the video4linux mailing list
|
||||||
@ -536,7 +475,6 @@ bool JpegDecoder::readData( Mat& img )
|
|||||||
|
|
||||||
result = true;
|
result = true;
|
||||||
jpeg_finish_decompress( cinfo );
|
jpeg_finish_decompress( cinfo );
|
||||||
setOrientation( img );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,12 +70,6 @@ protected:
|
|||||||
|
|
||||||
FILE* m_f;
|
FILE* m_f;
|
||||||
void* m_state;
|
void* m_state;
|
||||||
|
|
||||||
private:
|
|
||||||
//Support for handling exif orientation tag in Jpeg file
|
|
||||||
int m_orientation;
|
|
||||||
int getOrientation();
|
|
||||||
void setOrientation(Mat& img);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,6 +45,8 @@
|
|||||||
|
|
||||||
#include "precomp.hpp"
|
#include "precomp.hpp"
|
||||||
#include "grfmts.hpp"
|
#include "grfmts.hpp"
|
||||||
|
#include "utils.hpp"
|
||||||
|
#include "exif.hpp"
|
||||||
#undef min
|
#undef min
|
||||||
#undef max
|
#undef max
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -227,8 +229,11 @@ static ImageEncoder findEncoder( const String& _ext )
|
|||||||
return ImageEncoder();
|
return ImageEncoder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
enum { LOAD_CVMAT=0, LOAD_IMAGE=1, LOAD_MAT=2 };
|
enum { LOAD_CVMAT=0, LOAD_IMAGE=1, LOAD_MAT=2 };
|
||||||
|
|
||||||
|
void RotateImage(const String& filename, Mat& img);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read an image into memory and return the information
|
* Read an image into memory and return the information
|
||||||
*
|
*
|
||||||
@ -403,6 +408,12 @@ imreadmulti_(const String& filename, int flags, std::vector<Mat>& mats)
|
|||||||
Mat mat(decoder->height(), decoder->width(), type);
|
Mat mat(decoder->height(), decoder->width(), type);
|
||||||
if (!decoder->readData(mat))
|
if (!decoder->readData(mat))
|
||||||
{
|
{
|
||||||
|
// optionally rotate the data if EXIF' orientation flag says so
|
||||||
|
if( (flags & IMREAD_IGNORE_ORIENTATION) == 0 )
|
||||||
|
{
|
||||||
|
RotateImage(filename, mat);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -416,6 +427,59 @@ imreadmulti_(const String& filename, int flags, std::vector<Mat>& mats)
|
|||||||
return !mats.empty();
|
return !mats.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RotateImage(const String& filename, Mat& img)
|
||||||
|
{
|
||||||
|
int orientation = IMAGE_ORIENTATION_TL;
|
||||||
|
|
||||||
|
if (filename.size() > 0)
|
||||||
|
{
|
||||||
|
ExifReader reader( filename );
|
||||||
|
if( reader.parse() )
|
||||||
|
{
|
||||||
|
ExifEntry_t entry = reader.getTag( ORIENTATION );
|
||||||
|
if (entry.tag != INVALID_TAG)
|
||||||
|
{
|
||||||
|
orientation = entry.field_u16; //orientation is unsigned short, so check field_u16
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch( orientation )
|
||||||
|
{
|
||||||
|
case IMAGE_ORIENTATION_TL: //0th row == visual top, 0th column == visual left-hand side
|
||||||
|
//do nothing, the image already has proper orientation
|
||||||
|
break;
|
||||||
|
case IMAGE_ORIENTATION_TR: //0th row == visual top, 0th column == visual right-hand side
|
||||||
|
flip(img, img, 1); //flip horizontally
|
||||||
|
break;
|
||||||
|
case IMAGE_ORIENTATION_BR: //0th row == visual bottom, 0th column == visual right-hand side
|
||||||
|
flip(img, img, -1);//flip both horizontally and vertically
|
||||||
|
break;
|
||||||
|
case IMAGE_ORIENTATION_BL: //0th row == visual bottom, 0th column == visual left-hand side
|
||||||
|
flip(img, img, 0); //flip vertically
|
||||||
|
break;
|
||||||
|
case IMAGE_ORIENTATION_LT: //0th row == visual left-hand side, 0th column == visual top
|
||||||
|
transpose(img, img);
|
||||||
|
break;
|
||||||
|
case IMAGE_ORIENTATION_RT: //0th row == visual right-hand side, 0th column == visual top
|
||||||
|
transpose(img, img);
|
||||||
|
flip(img, img, 1); //flip horizontally
|
||||||
|
break;
|
||||||
|
case IMAGE_ORIENTATION_RB: //0th row == visual right-hand side, 0th column == visual bottom
|
||||||
|
transpose(img, img);
|
||||||
|
flip(img, img, -1); //flip both horizontally and vertically
|
||||||
|
break;
|
||||||
|
case IMAGE_ORIENTATION_LB: //0th row == visual left-hand side, 0th column == visual bottom
|
||||||
|
transpose(img, img);
|
||||||
|
flip(img, img, 0); //flip vertically
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
//by default the image read has normal (JPEG_ORIENTATION_TL) orientation
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read an image
|
* Read an image
|
||||||
*
|
*
|
||||||
@ -432,6 +496,12 @@ Mat imread( const String& filename, int flags )
|
|||||||
/// load the data
|
/// load the data
|
||||||
imread_( filename, flags, LOAD_MAT, &img );
|
imread_( filename, flags, LOAD_MAT, &img );
|
||||||
|
|
||||||
|
/// optionally rotate the data if EXIF' orientation flag says so
|
||||||
|
if( (flags & IMREAD_IGNORE_ORIENTATION) == 0 )
|
||||||
|
{
|
||||||
|
RotateImage(filename, img);
|
||||||
|
}
|
||||||
|
|
||||||
/// return a reference to the data
|
/// return a reference to the data
|
||||||
return img;
|
return img;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user