簡易的な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