[PYTHON] RICOH THETA S API in mehreren Sprachen.

At first

RICOH THETA API V2 Es gibt eine Entwicklerseite (https://developers.theta360.com/en/), eine Referenz (https://developers.theta360.com/de/docs/v2/api_reference/) und ein Forum ](Https://developers.theta360.com/ja/forums/) ist für die Öffentlichkeit zugänglich.

Diese Seite zeigt ein Beispiel für das tatsächliche Aufrufen der folgenden API basierend auf Erste Schritte.

  1. Informationen zum Kameragehäuse abrufen GET / osc / info
  2. Sitzung starten POST / osc / command / execute camera.startSession
  3. Standbildaufnahme POST / osc / command / execute camera.takePicture
  4. Aufnahmestatus abrufen POST / OSC / state
  5. Datei abrufen POST / osc / command / execute camera.getImage
  6. Sitzung beenden POST / osc / command / execute camera.closeSession

Grundsätzlich wird POST verwendet, um JSON-formatierte Parameter und Antworten auszutauschen.

Prerequisite

Shell Script Um ein Bild des Verarbeitungsablaufs zu erhalten, drücken wir zunächst Shell, während wir die Antwort überprüfen. Dieses Mal verwenden wir den Befehl "curl", der standardmäßig unter Mac OS X installiert ist.

#Informieren Sie sich über das Kameragehäuse
$ curl http://192.168.1.1:80/osc/info
{"manufacturer":"RICOH","model":"RICOH THETA S","serialNumber":"XXXXXXXX","firmwareVersion":"01.11","supportUrl":"https://theta360.com/en/support/","endpoints":{"httpPort":80,"httpUpdatesPort":80},"gps":false,"gyro":false,"uptime":583,"api":["/osc/info","/osc/state","/osc/checkForUpdates","/osc/commands/execute","/osc/commands/status"]}

Informationen zum Kameragehäuse wurden erfasst. Dieser Wert wird danach nicht mehr verwendet.

#Sitzung starten
$ curl -X POST http://192.168.1.1:80/osc/commands/execute -d '{"name": "camera.startSession"}'
{"name":"camera.startSession","state":"done","results":{ "sessionId":"SID_0001","timeout":180}}

Die hier erhaltene "sessionId" wird später verwendet. Sie müssen es manuell an der Stelle platzieren, die "SID_0001" in der nächsten Zeile entspricht.

#Standbildaufnahmen
$ curl -X POST http://192.168.1.1:80/osc/commands/execute -d '{"name": "camera.takePicture", "parameters": {"sessionId": "SID_0001"}}'
{"name":"camera.takePicture","state":"inProgress","id":"2","progress":{"completion":0.0}}

Die Kamera heißt Cuin. Es dauert einige Zeit, bis das Bild fertig ist.

#Erfassung des Aufnahmestatus
$ curl -X POST http://192.168.1.1:80/osc/state
{"fingerprint":"FIG_0006","state":{"sessionId":"SID_0001","batteryLevel":1.0,"storageChanged":false,"_captureStatus":"idle","_recordedTime":0,"_recordableTime":0,"_latestFileUri":"100RICOH/R0010174.JPG","_batteryState":"charging"}}

Verwenden Sie hier "_latestFileUri", das Sie erhalten, wenn der Aufnahmevorgang mit der folgenden API abgeschlossen ist. Wenn sich der "Fingerabdruck" ändert, ist die Bildverarbeitung beendet. Möglicherweise müssen Sie es mehrmals ausführen, bis Sie "_latestFileUri" erhalten.

#Dateierfassung
$ curl -X POST http://192.168.1.1:80/osc/commands/execute -d '{"name": "camera.getImage", "parameters": {"fileUri": "100RICOH/R0010174.JPG"}}' > image.jpg && open image.jpg

Die Datei wird in image.jpg im Ausführungsverzeichnis aufgenommen und gespeichert. Es ist nach dem Aufnehmen im Viewer geöffnet.

#Sitzungsende
$ curl -X POST http://192.168.1.1:80/osc/commands/execute -d '{"name": "camera.closeSession", "parameters": {"sessionId": "SID_0001"}}'
{"name":"camera.closeSession","state":"done"}

Die Bereinigung ist abgeschlossen.

Die Angabe der Parameter dauert einige Zeit, aber ich denke, es wurde bestätigt, dass Sie mit HTTP problemlos Bilder aufnehmen und abrufen können.

Ruby

require 'net/http'
require 'json'

http = Net::HTTP.new('192.168.1.1', 80)
JSON.parse(http.get("/osc/info").body)

res = http.post('/osc/commands/execute', {name: "camera.startSession"}.to_json)
sessionId = JSON.parse(res.body)["results"]["sessionId"]

params = {name: "camera.takePicture", parameters: {sessionId: sessionId}}.to_json
http.post('/osc/commands/execute', params)

fileUri = JSON.parse(http.post('/osc/state',"").body)["state"]["_latestFileUri"] while fileUri.empty?

params = {name: "camera.getImage", parameters: {fileUri: fileUri}}.to_json
res = http.post('/osc/commands/execute', params)

open("image.jpg ", "wb") {|f| f.write(res.body)}
`open image.jpg`

params = {name: "camera.closeSession", parameters: {sessionId: sessionId}}.to_json
http.post('/osc/commands/execute', params)

Ich denke, es kann intuitiv gelesen werden. Ich mag Ruby.

Python

import urllib
import json

urllib.urlopen("http://192.168.1.1/osc/info").read()

data = json.dumps({"name":"camera.startSession"})
res = urllib.urlopen('http://192.168.1.1/osc/commands/execute', data)
sessionId = json.loads(res.read())["results"]["sessionId"]

data = json.dumps({"name":"camera.takePicture", "parameters": {"sessionId": sessionId}})
urllib.urlopen('http://192.168.1.1/osc/commands/execute', data)

fileUri = ""
while not fileUri:
    res = urllib.urlopen('http://192.168.1.1/osc/state', urllib.urlencode({}))
    fileUri = json.loads(res.read())["state"]["_latestFileUri"]

data = json.dumps({"name":"camera.getImage", "parameters": {"fileUri": fileUri}})
res = urllib.urlopen('http://192.168.1.1/osc/commands/execute', data)
with open("image.jpg ", "wb") as file:
    file.write(res.read())

data = json.dumps({"name":"camera.closeSession", "parameters": {"sessionId": sessionId}})
urllib.urlopen('http://192.168.1.1/osc/commands/execute', data)

Ich denke, Sie können dies auch intuitiv lesen.

Ich wollte das Bild öffnen, aber als ich den folgenden Code nach dem obigen Code zusammenfügte, war das Verhalten von Popen nicht stabil. Wenn es zu irgendeinem Zeitpunkt ausgeführt wird, kann das Image auch in der REPL-Umgebung mit dem folgenden Code geöffnet werden.

import subprocess
subprocess.Popen(['open', 'image.jpg'])

Swift

import UIKit

// for asynchronous use in Playground
import XCPlayground 
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true 

let session = NSURLSession.sharedSession()

// osc/info
var url = NSURL(string: "http://192.168.1.1/osc/info")
var task = session.dataTaskWithURL(url!) {
    (data, response, error) in
    print(NSString(data: data!, encoding: NSUTF8StringEncoding))
}
task.resume()

// camera.startSession
var sessionId = "";
var jsonDic = NSDictionary()
url = NSURL(string: "http://192.168.1.1/osc/commands/execute")
var req = NSMutableURLRequest(URL: url!)
var params: [String: AnyObject] = ["name": "camera.startSession"]
req.HTTPMethod = "POST"
req.HTTPBody = try NSJSONSerialization.dataWithJSONObject(params, options: NSJSONWritingOptions.PrettyPrinted)
task = session.dataTaskWithRequest(req) {
    (data, response, error) in
    print(NSString(data: data!, encoding: NSUTF8StringEncoding))
    do {
        jsonDic = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! NSDictionary
    } catch {}
    let result = jsonDic["results"]  as! NSDictionary
    sessionId = result["sessionId"] as! String
}
task.resume()
while sessionId.isEmpty { sleep(1) }

// camera.takePicture
url = NSURL(string: "http://192.168.1.1/osc/commands/execute")
req = NSMutableURLRequest(URL: url!)
params = ["name": "camera.takePicture", "parameters": ["sessionId": sessionId]]
req.HTTPMethod = "POST"
req.HTTPBody = try NSJSONSerialization.dataWithJSONObject(params,
    options: NSJSONWritingOptions.PrettyPrinted)
task = session.dataTaskWithRequest(req) {
    (data, response, error) in
    print(NSString(data: data!, encoding: NSUTF8StringEncoding))
}
task.resume()

// osc/state
var fileUri = "";
url = NSURL(string: "http://192.168.1.1/osc/state")
req = NSMutableURLRequest(URL: url!)
req.HTTPMethod = "POST"
repeat {
    sleep(1)
    print("try osc/state")
    task = session.dataTaskWithRequest(req) {
        (data, response, error) in
        print(NSString(data: data!, encoding: NSUTF8StringEncoding))
        do {
            jsonDic = try NSJSONSerialization.JSONObjectWithData(data!,
                options: NSJSONReadingOptions.MutableContainers) as! NSDictionary
        } catch {}
        let result = jsonDic["state"]  as! NSDictionary
        fileUri = result["_latestFileUri"] as! String
    }
    task.resume()
} while fileUri.isEmpty
print(fileUri)

// camera.getImage
var img :UIImage?
url = NSURL(string: "http://192.168.1.1/osc/commands/execute")
req = NSMutableURLRequest(URL: url!)
params = ["name": "camera.getImage", "parameters": ["fileUri": fileUri]]
req.HTTPMethod = "POST"
req.HTTPBody = try NSJSONSerialization.dataWithJSONObject(params,
    options: NSJSONWritingOptions.PrettyPrinted)
task = session.dataTaskWithRequest(req) {
    (data, response, error) in
//    NSData.init(data: data!)
    img = UIImage(data: data!)
}
task.resume()
while (img == nil) { sleep(1) }

// camera.closeSession
url = NSURL(string: "http://192.168.1.1/osc/commands/execute")
req = NSMutableURLRequest(URL: url!)
params = ["name": "camera.closeSession", "parameters": ["sessionId": sessionId]]
req.HTTPMethod = "POST"
req.HTTPBody = try NSJSONSerialization.dataWithJSONObject(params,
    options: NSJSONWritingOptions.PrettyPrinted)
task = session.dataTaskWithRequest(req) {
    (data, response, error) in
    print(NSString(data: data!, encoding: NSUTF8StringEncoding))
}
task.resume()

Da NSURLSession eine API ist, die asynchron ausgeführt wird, wird hier und da eine Warteverarbeitung eingefügt. Wenn der Wert in img eingegeben wird, können Sie das Bild überprüfen, indem Sie eine Vorschau der Variablen in der Ergebnisseitenleiste der Spielplatzumgebung anzeigen. Ich möchte es bei der Verarbeitung von JSON etwas schöner schreiben.

Unity

C#

using UnityEngine;
using UnityEngine.UI;
using System.Text;
using System.Collections;
using System.Collections.Generic;

public class THETAOSC : MonoBehaviour {

	void Start () {
		StartCoroutine(StartThetaS());
	}

	IEnumerator StartThetaS () {
		string url = "http://192.168.1.1/osc/info";
		WWW www = new WWW(url);
		yield return www;
		Debug.Log(www.text);

		Dictionary<string, string> header = new Dictionary<string, string>();
		url = "http://192.168.1.1/osc/commands/execute";
		string jsonStr = "{\"name\": \"camera.startSession\"}";
		byte[] postBytes = Encoding.Default.GetBytes (jsonStr);
		www = new WWW (url, postBytes, header);
		yield return www;
		JsonNode json = JsonNode.Parse(www.text);
		string sessionId = json["results"]["sessionId"].Get<string>();
		Debug.Log(sessionId);

		jsonStr = "{\"name\": \"camera.takePicture\", \"parameters\": {\"sessionId\": \"" + sessionId + "\"}}";
		postBytes = Encoding.Default.GetBytes (jsonStr);
		www = new WWW (url, postBytes, header);
		yield return www;
		Debug.Log(www.text);

		string fileUri = "";
		url = "http://192.168.1.1/osc/state";
		jsonStr = "{}";
		postBytes = Encoding.Default.GetBytes (jsonStr);
		while(fileUri == "") {
			www = new WWW (url, postBytes, header);
			yield return www;
			Debug.Log(www.text);
			json = JsonNode.Parse(www.text);
			fileUri = json["state"]["_latestFileUri"].Get<string>();
		}
		Debug.Log(fileUri);

		//Selbst wenn fileUri abgerufen wird, ist der Vorgang möglicherweise nicht abgeschlossen. Warten Sie daher eine Weile
		yield return new WaitForSeconds(3); 

		url = "http://192.168.1.1/osc/commands/execute";
		jsonStr = "{\"name\": \"camera.getImage\", \"parameters\": {\"fileUri\": \"" + fileUri + "\"}}";
		postBytes = Encoding.Default.GetBytes (jsonStr);
		www = new WWW (url, postBytes, header);
		yield return www;

		//Zur Bestätigung im Rohbild anzeigen
		RawImage rawImage = GetComponent<RawImage>();
		rawImage.texture = www.textureNonReadable;
		rawImage.SetNativeSize();

		jsonStr = "{\"name\": \"camera.closeSession\", \"parameters\": {\"sessionId\": \"" + sessionId + "\"}}";
		postBytes = Encoding.Default.GetBytes (jsonStr);
		www = new WWW (url, postBytes, header);
		yield return www;
		Debug.Log(www.text);
	}
}

Unreal Engine 4 (geplant)

Summary Mit der OSC-kompatiblen API von THETA S habe ich tatsächlich versucht, den Ablauf der Aufnahme und Bildsammlung zu verschieben und zu ermitteln, wie die API in jeder Umgebung aufgerufen werden kann. Auf die gleiche Weise können Sie auch Aufnahmeoptionen für die Kamera festlegen, sodass Sie meiner Meinung nach damit herumspielen können. Ich hoffe, es wird eine Referenz und eine Gelegenheit sein!

Recommended Posts

RICOH THETA S API in mehreren Sprachen.
Sprechen Sie über die Zeiterfassungs-API in der Programmiersprache
Evernote-API in Python
HMAC in verschiedenen Sprachen
C-API in Python 3