关闭

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

标签: opencvimread图像方向
753人阅读 评论(0) 收藏 举报
分类:

在用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

0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

读取和修改JPEG图片文件的头信息EXIF和JFIF

1. JPEG图片格式的历程和简单介绍可参考下面这篇文章 http://blog.csdn.net/kickxxx/article/details/8173332 
  • xywy2008
  • xywy2008
  • 2014-07-24 22:43
  • 8734

JPEG系列二 JPEG文件中的EXIF(下)

本文介绍EXIF中都保存了哪些数据,这些数据的内容和格式,最后介绍一下EXIF中的缩略图信息。 EXIF JPEG文件将EXIF信息存储在JFIF的APP1标记中。 EXIF主要保存拍摄照片时的相机...
  • shelldon
  • shelldon
  • 2017-01-13 12:52
  • 2279

读取或解析图片的exif信息

  • 2013-01-23 15:34
  • 10KB
  • 下载

读取JPG图片的Exif属性(一) - Exif信息简介

Exif 是什么? Exif就是用来记录拍摄图像时的各种信息:图像信息(厂商,分辨率等),相机拍摄记录(ISO,白平衡,饱和度,锐度等),缩略图(缩略图宽度,高度等),gps(拍摄时的经度,纬度,高...
  • fioletfly
  • fioletfly
  • 2016-12-13 08:47
  • 6000

20170227. EXIF信息的说明(opencv320 ApplyExifOrientation)

在opencv3.2.0中,对imread函数做了修改 Mat imread( const String& filename, int flags ) { /// create the ba...
  • u014488388
  • u014488388
  • 2017-02-27 16:00
  • 217

opencv 读取图片信息及区域数据

#include #include #include void main() { IplImage* src_img=cvLoadImage("zjut.jpg",1); ...
  • sunboyiris
  • sunboyiris
  • 2014-02-27 11:27
  • 1605

利用exif js及脚本修正图片的orientation显示

假如图片是ios及数码相机拍摄,那么它就会带有exif信息,其中一个叫orientation的方向信息,这个方向是你拍摄的方向,假如有这个方向的话,在pc,安卓及ios上面的显示都不一样。下面是两个对...
  • cdnight
  • cdnight
  • 2015-06-11 14:33
  • 16246

Exif的Orientation信息说明

EXIF Orientation 参数让你随便照像但都可以看到正确方向的照片而无需手动旋转(前提要图片浏览器支持,Windows 自带的不支持) 这个参数在佳能、尼康相机照的照片是自带的,但我的...
  • ouyangtianhan
  • ouyangtianhan
  • 2014-06-10 12:54
  • 10167

读取图片的exif相关信息并且将其调整顺序

在看这个之前请看看
  • cdnight
  • cdnight
  • 2014-07-01 09:34
  • 6178

读取JPG图片的Exif属性(一) - Exif信息简介

Exif 是什么? Exif就是用来记录拍摄图像时的各种信息:图像信息(厂商,分辨率等),相机拍摄记录(ISO,白平衡,饱和度,锐度等),缩略图(缩略图宽度,高度等),gps(拍摄时的经度,纬度,高...
  • fioletfly
  • fioletfly
  • 2016-12-13 08:47
  • 6000
    个人资料
    • 访问:182623次
    • 积分:2760
    • 等级:
    • 排名:第15013名
    • 原创:86篇
    • 转载:6篇
    • 译文:0篇
    • 评论:73条
    文章分类
    最新评论