在opencv2.4.x版本中处理图像EXIF orientation不统一的问题

来源:互联网 发布:java核心技术卷2 编辑:程序博客网 时间:2024/05/27 06:55

在用opencv的imread函数读取手机拍的照片时会出现翻转的情况,即用opencv中的imshow看到的图像和手机上看到的图像的宽高是相反的。(当然,读取电脑上的照片时也可能会出现这个问题)
出现这个问题的原因是opencv中的imread函数读取图像时没有对图像exif中的orientation信息进行解析。而通常的看图工具打开图像时都会根据orientation对图像进行相应的翻转以便我们看到的图像是正常的。
通过查找发现在opencv的源码github中,有人解决了读取orientation的问题,并且在opencv源码中进行了提交。另外,在opencv3.2中也对该问题进行了相关的支持。

为了解决该问题,我从源码中抽取了exif.hpp和exif.cpp两个相关文件,并通过如下函数成功解决了根据orientation对图像进行翻转。

void ReadWithExifOrientation(const String& filename, Mat& img){    img = imread(filename);    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;    }}

exif.hpp和exif.cpp下载地址:http://download.csdn.net/detail/computerme/9884696
使用姿势如下:

#include <opencv2/opencv.hpp>#include "exif.hpp"int  main(int argc,char *argv[]){    char* testimage = "/Users/Downloads/IMG_4198.JPG";    Mat img;     ReadWithExifOrientation(testimage, img);  //new image read function    return 1;}

Reference:
https://github.com/opencv/opencv/pull/5538/commits/0a306f88047586356548335f5e8c9697ce43b8fc
https://my.oschina.net/shf/blog/876489
https://fossies.org/dox/opencv-3.2.0/exif_8cpp_source.html
http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/EXIF.html

原创粉丝点击