如何根据 python 中一天中的时间每分钟从最大值和最小值计算曝光时间

How to calculate exposure time from a maximum and minimum value, every minute based on time of day in python

我想做我的Raspberry Pi camera timelapse boxes to take long exposures at night, and shorter exposures at day. I've gathered a list of sunset and sunrises for my location like this (Script here)

它有一天中太阳升起、中午和落下的时间。 (或者值“太阳”:never_rises,或 never_sets 代表我居住的极地冬季和极地夏季。)

我的 Picamera 最大曝光时间为 6 秒,即 6000000 微秒,以便在夜间获得可用的图像。在白天,我获得了大约 4000 微秒曝光的良好曝光。

我想做一个脚本,根据当前时间计算曝光时间从max:6000000到min:4000,每分钟。

我在想这样的事情:低于时间,直到日出前 2 小时,天黑了,= max 曝光。

从日出到白天的 2 小时内,获取从 maxmin 的值。

min 持续一整天。

然后,在两个小时内从 minmax,从日落开始向外,当天又黑时。

但是我的数学能力很弱。我如何计算两小时内每分钟从 maxmin 的平滑过渡?

如果每天日落和升起的时间相同,我可以制作一个 excel sheet 来获得可用的值,但是由于每天太阳落山和升起的时间不同变得棘手。

可以找到用于制作延时摄影的脚本here

这需要一些时间运行,所以可能有更好的实现方式。它假定曝光时间为 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"])

弄清楚这实际上很有趣。希望有用。