簡易的なIBL用のHDRIを作成するため、素材になる天球マップ画像をRicoh THETA SをiPhoneで遠隔操作して手軽にオートブラケット撮影できるようにしてみました。
撮影方法は、ISOを固定しEVを変化させて行う露出ブラケット撮影になります。
今の所、使用する撮影モードではシャッタースピードを同時に操作できなそうなので、自動設定にしてあります。
THETA SはRAWデータでの撮影ができず、また撮影時に厳密なホワイトバランス設定などもできないので精度は落ちますが、簡易的に使用するにはそこそこ使えるHDRIが得られると思います。
iOSデバイスに限らず、THETA Sとネットワーク接続できるデバイスで、なおかつ標準的なPythonを実行できるなら同じように使用できるはずです。
というわけで、需要がありそうなのでソースコードを公開します。
時間の関係で良い作例の用意ができていませんが、そのうち貼りたいと思います。
・使い方
1:デバイスとTHETA Sをネットワーク接続接続します
2:下記スクリプトをデバイス内のPython実行環境で実行します
当方は、iPhone6S+上で iOS用のPython 2.7 というアプリを使用しています。
3:撮影されたJPEG画像をHDR ShopやLuminance HDRなどを使ってHDRIにします
#******************************************************************************
'''
Tool Name : MYAM_ThetaAutoBracket.py
Description :
Copyright : (c) Yamabe Michiyoshi
Author Name : Yamabe Michiyoshi
'''
#******************************************************************************
import httplib
import json
import time
#
class ThetaSettings(object):
# Full
# evs = [-2.0, -1.7, -1.3, -1.0, -0.7, -0.3, 0.0, 0.3, 0.7, 1.0, 1.3, 1.7, 2.0]
# Simple
evs = [-2.0, -1.0, 0.0, 1.0, 2.0]
exposureProgram = 9
iso = 100
whiteBalance = "auto"
_shutterVolume = 50
shutterInterval = 1
#
class Theta(object):
def __init__(self):
self.headers = {"Content-Type":"application/json", "Accept":"application/json"}
# Auto Bracket
def takePicturesByAutoBracket(self):
print "--------------------"
print "START AUTO BRACKET"
print "--------------------"
# Connect to THETA
connection = self.connect()
# Start Session
self.startSession(connection)
# Get Session ID
responseData = self.getResponseData(connection)
sessionId = responseData["results"]["sessionId"]
# Take Pictures
for i in range(len(ThetaSettings.evs)):
# Set options
ev = ThetaSettings.evs[i]
print "----------"
print "%i / %i" % ((i + 1), len(ThetaSettings.evs))
print "iso : %i" % ThetaSettings.iso
print "EV : %d" % ev
picOpt = {"exposureProgram":ThetaSettings.exposureProgram,
"exposureCompensation":ev,
"iso":ThetaSettings.iso,
"whiteBalance":ThetaSettings.whiteBalance,
"_shutterVolume":ThetaSettings._shutterVolume}
self.setOptions(connection, sessionId, optionParams=picOpt)
responseData = self.getResponseData(connection)
# Take Pictute
self.takePicture(connection, sessionId)
# Wait to finish idle time
self.waitFinishCurrentCommand(connection, interval=ThetaSettings.shutterInterval)
# Close Session
self.closeSession(connection, sessionId)
# Disconnect from THETA
self.disconnect(connection)
print "--------------------"
print "FINISH AUTO BRACKET"
print "--------------------"
# HTTPConnection Control
def connect(self):
connection = httplib.HTTPConnection("192.168.1.1",80)
return connection
def disconnect(self,connection):
connection.close()
# Common Commands
def postExecCommand(self,connection,params):
connection.request("POST", "/osc/commands/execute", params, self.headers)
def postStatusCommand(self, connection, commandId):
params = json.dumps({ "id":commandId })
connection.request("POST", "/osc/commands/status", params, self.headers)
def waitFinishCurrentCommand(self, connection, interval=1):
responseData = self.getResponseData(connection)
commandId = responseData["id"]
while True:
self.postStatusCommand(connection, commandId)
responseData = self.getResponseData(connection)
commandStatus = responseData["state"]
if "inProgress" == commandStatus:
print "commandId [%s] : Processing..." % ( commandId )
time.sleep(interval)
else:
print "commandId [%s] : Finish!" % ( commandId )
break
# Command Control
def startSession(self, connection):
params = json.dumps({ "name":"camera.startSession", "parameters":{} })
self.postExecCommand(connection, params)
def updateSession(self,connection,sessionId):
params = json.dumps({ "name":"camera.updateSession", "parameters":{"sessionId":sessionId} })
self.postExecCommand(connection, params)
def closeSession(self, connection, sessionId):
params = json.dumps({ "name":"camera.closeSession", "parameters":{"sessionId":sessionId} })
self.postExecCommand(connection, params)
def takePicture(self,connection , sessionId):
params = json.dumps({ "name":"camera.takePicture", "parameters":{"sessionId":sessionId} })
self.postExecCommand(connection, params)
def setOptions(self, connection, sessionId, optionParams):
params = { "name":"camera.setOptions" , "parameters":{"sessionId":sessionId, "options":{} } }
for key , value in optionParams.items():
params["parameters"]["options"][key] = value
jsonParams = json.dumps(params)
self.postExecCommand(connection, jsonParams )
def getOptions(self, connection, sessionId, optionNames):
params = { "name":"camera.setOptions" , "parameters":{"sessionId":sessionId, "optionNames":{} } }
for key , value in optionParams.items():
params["parameters"]["options"][key] = value
jsonParams = json.dumps(params)
self.postExecCommand(connection, jsonParams )
self.postExecCommand(connection, params)
# Support Functions
def getResponseString(self,connection):
response = connection.getresponse()
responseString = response.read()
return responseString
def getResponseData(self,connection):
responseString = self.getResponseString(connection)
responseData = self.convertJSONToPythonData(responseString)
return responseData
def convertJSONToPythonData(self,jsonDataString):
jsonDecoder = json.JSONDecoder()
pythonData = jsonDecoder.decode(jsonDataString)
return pythonData
def convertPythonDataToJSON(self,pythonData):
jsonEncoder = json.JSONEncoder()
jsonDataString = jsonEncoder.encode(pythonData)
return jsonDataString
def main():
theta = Theta()
theta.takePicturesByAutoBracket()
if __name__ == "__main__":
main()
・設定
設定の変更を行うにはコードを直接書き換える必要があります。
撮影枚数は、ThetaSettingsの evs で指定されているEV値の数で指定されます。
撮影ごとにリスト内のEV値がそれぞれ使用されます。
・EV値と撮影枚数の設定
class ThetaSettings(object):
# Full
# evs = [-2.0, -1.7, -1.3, -1.0, -0.7, -0.3, 0.0, 0.3, 0.7, 1.0, 1.3, 1.7, 2.0]
# Simple
evs = [-2.0, -1.0, 0.0, 1.0, 2.0]
指定できるEV値は、上記の Full で指定されている13個の値になります。
THETA Sは一枚撮影するごとに内部処理に約8秒ほどかかるようなので、撮影枚数が多くなると時間がかかります。
必要に応じ、不要な値を削除するなどして調整してください。
・各種オプションの設定
exposureProgram = 9
iso = 100
whiteBalance = "auto"
_shutterVolume = 50
現在は、上記を指定できます。
必要に応じ、RICOH THETA API v2 Referenceを参照して値を設定してください。
といいつつおそらく上記の中では iso と _shutterVolume くらいしかいじらないと思います。
・_shutterVolume
0−100の間で指定します。0が無音です。
・iso
以下の値が使えます
100, 125, 160, 200, 250, 320, 400, 500, 640, 800, 1000, 1250, 1600