LoginSignup
7
6

More than 5 years have passed since last update.

Ricoh thetaのJPGから角度を取り出すコード(2018年版)

Last updated at Posted at 2018-09-19

はじめに

  • THETA Vの静止画から角度情報を取得して画像を正しい向きにする(天頂補正)際に実施した内容(取得編)

作業方針

  • THETA Vの静止画には角度情報がxmpとして入っているためその情報を取得する
    • 以前の方法では、リコー固有ブロックのExif情報を取得していました
  • 必要な部分だけ取り出す
    • XMLパーサなどを使用せずに軽量化

コード

XmpReader.cs
using UnityEngine;
using System.Collections;
using System.IO;
using System;

public class XmpReader 
{
    public static void SerchAngle(string filePath)
    {
        BinaryReader br = new BinaryReader(new FileStream(filePath, FileMode.Open));
        byte [] buf = br.ReadBytes((int)br.BaseStream.Length);
        br.Close();
        br = null;

        float pitch = getPitch(buf);
        float roll = getRoll(buf);

        Debug.Log("filePath : " + filePath);
        Debug.Log("pitch : " + pitch + ", roll : " + roll);
    }

    public static float getPitch(byte[] buf) {
        string pitchStr = getXMLTagData(buf, "GPano:PosePitchDegrees");
        float pitch = 0.0f;
        if (pitchStr != "") {
            pitch = float.Parse(pitchStr);
        }
        return pitch;
    }

    public static float getRoll(byte[] buf) {
        string rollStr = getXMLTagData(buf, "GPano:PoseRollDegrees");
        float roll = 0.0f;
        if (rollStr != "") {
            roll = float.Parse(rollStr);
        }
        return roll;
    }

    static string getXMLTagData(byte[] buf, string xmlTagName) {
        string strStart = String.Format("<{0}>", xmlTagName);
        byte[] byteStart = System.Text.Encoding.ASCII.GetBytes(strStart);
        int xmp_start = findData(buf, byteStart);
        if (xmp_start < 0) {
            return ""; 
        }
        string strEnd = String.Format("</{0}>", xmlTagName);
        byte[] byteEnd = System.Text.Encoding.ASCII.GetBytes(strEnd);
        int xmp_end = findData(buf, byteEnd); 
        if (xmp_end < 0) {
            return ""; 
        }
        xmp_end = xmp_end - strEnd.Length;

        byte[] buf_get = new byte[255];
        int copy_idx = 0;
        for (int i=xmp_start;i<xmp_end; i++) {
            buf_get[copy_idx] = buf[i];
            copy_idx++;
        }
        string result = System.Text.Encoding.ASCII.GetString(buf_get);
        return result;
    }

    static int findData(byte[] buf, byte[] pattern)
    {
        int max = buf.Length;
        if (max > 64*1000) { 
            max = 64*1000; 
        }

        for (int i = 0; i < max; i++) {
            int iTemp = i;
            for (int p = 0; p < pattern.Length ; p++, iTemp++) {
                if (pattern[p] != buf[iTemp] || iTemp >= max) {
                    break;
                }
                if (p == pattern.Length - 1) {
                    return iTemp + 1;
                }
            }
        }
        return -1;
    }
}

さいごに

  • この角度情報を実際に利用する方法はこちらに書きました
  • 他のアプリ(OculusGoのギャラリーなど)は、このXMPがあるためVR表示しますが天頂補正はしませんでした

参考資料

7
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
6