基于exif信息进行坐标旋转、翻转修正

基于exif信息进行坐标旋转、翻转修正

上次完成《基于exif信息进行图片方向旋转修正》后,出现了一个新的问题: 第一次标注了实例的外边框,第二次标注了实例的文本区域,合并后前后两次标注的坐标点无法与图片匹配吻合。
在这里插入图片描述产生这个问题的原因是两次标注的图片方向不一致,第二次标注时图片没有被exif信息进行旋转,所以合并后第一次的标注坐标出现了问题,现在需要从exif中读取出图片方向,对坐标进行旋转。

import cv2
import numpy as np
import json
import base64
import os
import glob
import imageio
from io import BytesIO
import math
import PIL.ExifTags
import PIL.Image
import PIL.ImageOps
import re

def apply_exif_orientation(image):
    """
    从图片exif信息中读取旋转角度
    :param image:
    :return:
    """
    try:
        exif = image._getexif()
    except AttributeError:
        exif = None

    if exif is None:
        return None, None

    exif = {
        PIL.ExifTags.TAGS[k]: v
        for k, v in exif.items()
        if k in PIL.ExifTags.TAGS
    }

    orientation = exif.get('Orientation', None)
    # return orientation
    if orientation == 1:
        # do nothing
        return None, None
    elif orientation == 2:
        # left-to-right mirror
        return 'mirror', None
    elif orientation == 3:
        # rotate 180
        return None, 180
    elif orientation == 4:
        # top-to-bottom mirror
        return 'flip', None
    elif orientation == 5:
        # top-to-left mirror
        return 'mirror', -90
    elif orientation == 6:
        # rotate 270
        return None, -90
    elif orientation == 7:
        # top-to-right mirror
        return 'mirror', 90
    elif orientation == 8:
        # rotate 90
        return None, 90
    else:
        return image

def flip_point(h, points):
    """
    点上下翻转
    :param h: int, eg 10
    :param point: ndarray, [ [1, 2] [1, 8 ] ]
    :return:[ [1, 8] [1, 2 ] ]
    """
    points[:,0:1] = h-points[:,0:1]
    return points

def mirror_point(w, points):
    """
    点左右翻转
    :param w: int, eg. 10
    :param point:NDarray, eg. array([[1, 2], [7, 4]])
    :return:NDarray,eg array([[9, 2], [3, 4]])
    """
    points[:,1:2] = w-points[:,0:1]
    return points

def rotation_point(h, w, angle, point):
    """
    坐标点旋转
    :param h: 图片高度
    :param w: 图片宽度
    :param angle: 旋转角度
    :param point: 坐标点 eg. NDarray([[1,2],[2,3]])
    :return: point: 坐标点 eg. NDarray([[1,2],[2,3]])
    """
    cols = h
    rows = w
    M = cv2.getRotationMatrix2D((cols / 2, rows / 2), angle, 1)
    heightNew = int(cols * math.fabs(math.sin(math.radians(angle))) + rows * math.fabs(math.cos(math.radians(angle))))
    widthNew = int(rows * math.fabs(math.sin(math.radians(angle))) + cols * math.fabs(math.cos(math.radians(angle))))

    M[0, 2] += (widthNew - cols) / 2
    M[1, 2] += (heightNew - rows) / 2
    a = M[:, :2]
    b = M[:, 2:]
    b = np.reshape(b, newshape=(1, 2))
    a = np.transpose(a)
    point = np.reshape(point, newshape=(len(point), 2))
    if angle == 180:
        point = np.dot(point, a) + np.array([b[0][1], b[0][0]])
    else:
        point = np.dot(point, a) + b

    return point


def main():
    image_path = "xx.jpg"
    pil_image = PIL.Image.open(open(image_path))
    h, w = pil_image.size
    transform, angle = apply_exif_orientation(pil_image)
    print(f"angle:{angle}, transform:{transform}")
    pts = np.array([[90, 230], [160, 230], [160, 250], [90, 250]])
    if angle in [-90, 90, 180]:
        pts = rotation_point(h, w, angle, pts).astype(np.int32)
    if transform in ['mirror']:
        pts = mirror_point(w, pts)
    elif transform in ['flop']:
        pts = flip_point(h, pts)
  


if __name__ == "__main__":
    main()

以上是坐标旋转,我进行了图片旋转修正,请参考《基于exif信息进行图片方向旋转修正》,最终效果如下:

在这里插入图片描述
完成!

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值