这需要一些时间来运行,因此可能有更好的方法来实现它。它假定曝光时间为 1 微秒步长,因此如果不同,只需修改 np.linspace 行。
我从最大曝光开始,在日出曝光开始线性下降到日出时的最小值前 2 小时。在日落时,它开始线性增加到日落后 2 小时的最大值。如果日落和日出之间的时间少于 4 小时,我决定根据时差调整最大曝光量。使用不同的尺度(即对数或几何)可能会有更好的结果,但这可能更多来自实验而不是编码本身。
就个人而言,我认为时间假设有点偏离,但这更多的是基于一天中的时间进行适当曝光设置的问题,而不是这里提出的问题,并且脚本可以这样调整。
import requests
import datetime
import numpy as np
import pandas as pd
import time
import plotly.graph_objects as go
max = 6000000
min = 4000
change = np.round(np.linspace(min, max, 121))
mins = pd.DataFrame({"time": pd.date_range("1/1/2021", "31/12/2021", freq="T"), "exposure": max})
url = "https://raw.githubusercontent.com/ekstremedia/raspberry-timelapse/master/scripts/solartimes.json"
data = requests.get(url).json()
sunset = None
neversets = False
for i in data:
if not data[i]["data"]:
if data[i]["sun"] == "never_sets":
day = datetime.datetime.strptime(f'2021-{i}', "%Y-%d-%m")
day_end = day + datetime.timedelta(hours=23, minutes=59)
mins.loc[(mins["time"] >= day) & (mins["time"] <= day_end), "exposure"] = min
if not neversets:
new_max = int((((day-sunset).seconds/120)/120)*max)
new_change = np.linspace(min, new_max, int(((day-sunset).seconds/120))+1)
new_change_a = np.round(np.concatenate([new_change[:-1], new_change[::-1]]))
try:
mins.loc[(mins["time"] >= sunset) & (mins["time"] <= day), "exposure"] = new_change_a
except ValueError:
new_change_a = np.round(np.concatenate([new_change, new_change[::-1]]))
mins.loc[(mins["time"] >= sunset) & (mins["time"] <= day), "exposure"] = new_change_a
neversets = True
else:
sunrise = datetime.datetime.strptime(f'2021-{i} {data[i]["sunrise"]}', "%Y-%d-%m %H:%M")
pre_sunrise = sunrise - datetime.timedelta(hours=2)
if neversets:
day = datetime.datetime.strptime(f'2021-{i}', "%Y-%d-%m")
sunrise = datetime.datetime.strptime(f'2021-{i} {data[i]["sunrise"]}', "%Y-%d-%m %H:%M")
new_max = int((((sunrise-day).seconds/120)/120)*max)
new_change = np.linspace(min, new_max, int(((sunrise-day).seconds/120))+1)
new_change_a = np.round(np.concatenate([new_change[:-1], new_change[::-1]]))
try:
mins.loc[(mins["time"] >= day) & (mins["time"] <= sunrise), "exposure"] = new_change_a
except ValueError:
new_change_a = np.round(np.concatenate([new_change, new_change[::-1]]))
mins.loc[(mins["time"] >= day) & (mins["time"] <= sunrise), "exposure"] = new_change_a
sunset = datetime.datetime.strptime(f'2021-{i} {data[i]["sunset"]}', "%Y-%d-%m %H:%M")
post_sunset = sunset + datetime.timedelta(hours=2)
mins.loc[(mins["time"] >= sunrise) & (mins["time"] <= sunset), "exposure"] = min
mins.loc[(mins["time"] >= sunset) & (mins["time"] <= post_sunset), "exposure"] = change
neversets = False
continue
if sunset:
yest_sunset = sunset
if sunrise-yest_sunset < datetime.timedelta(hours=4):
new_max = int((((sunrise-yest_sunset).seconds/120)/120)*max)
new_change = np.linspace(min, new_max, int(((sunrise-yest_sunset).seconds/120))+1)
new_change_a = np.round(np.concatenate([new_change[:-1], new_change[::-1]]))
try:
mins.loc[(mins["time"] >= yest_sunset) & (mins["time"] <= sunrise), "exposure"] = new_change_a
except ValueError:
new_change_a = np.round(np.concatenate([new_change, new_change[::-1]]))
mins.loc[(mins["time"] >= yest_sunset) & (mins["time"] <= sunrise), "exposure"] = new_change_a
sunset = datetime.datetime.strptime(f'2021-{i} {data[i]["sunset"]}', "%Y-%d-%m %H:%M")
post_sunset = sunset + datetime.timedelta(hours=2)
mins.loc[(mins["time"] >= sunrise) & (mins["time"] <= sunset), "exposure"] = min
mins.loc[(mins["time"] >= sunset) & (mins["time"] <= post_sunset), "exposure"] = change
continue
sunset = datetime.datetime.strptime(f'2021-{i} {data[i]["sunset"]}', "%Y-%d-%m %H:%M")
post_sunset = sunset + datetime.timedelta(hours=2)
mins.loc[(mins["time"] >= pre_sunrise) & (mins["time"] <= sunrise), "exposure"] = change[::-1]
mins.loc[(mins["time"] >= sunrise) & (mins["time"] <= sunset), "exposure"] = min
mins.loc[(mins["time"] >= sunset) & (mins["time"] <= post_sunset), "exposure"] = change
fig = go.Figure(data=go.Scattergl(x=mins["time"], y=mins["exposure"], mode='lines'))
fig.update_xaxes(rangeslider_visible=True)
fig.show()
current = datetime.datetime.now().replace(second=0, microsecond=0)
print(mins.loc[mins["time"] == current, "exposure"])
这实际上很有趣。我希望它有效。