簡體   English   中英

你能把閃光燈翻譯成摩爾斯電碼嗎?

[英]Can you translate a flashing light into morse code?

我做了一個莫爾斯電碼翻譯器,我希望它能夠記錄閃光並把它變成莫爾斯電碼。 我想我需要 OpenCV 或光傳感器,但我不知道如何使用它們。 我還沒有任何代碼,因為我在其他任何地方都找不到任何解決方案。

以下只是您可以嘗試的概念。 是的,你也可以為此訓練一個神經網絡,但如果你的設置足夠簡單,一些工程就可以了。

我們首先創建一個“玩具視頻”來處理:

import numpy as np
import matplotlib.pyplot as plt

# Create a toy "video"

image = np.asarray([
    [0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0],
    [0, 0, 1, 2, 2, 1],
    [0, 0, 2, 4, 4, 2],
    [0, 0, 2, 4, 4, 2],
    [0, 0, 1, 2, 2, 1],
])

signal = np.asarray([0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0])
x = list(range(len(signal)))
signal = np.interp(np.linspace(0, len(signal), 100), x, signal)[..., None]
frames = np.einsum('tk,xy->txyk', signal, image)[..., 0]

Plot幾幀:

fig, axes = plt.subplots(1, 12, sharex='all', sharey='all')
for i, ax in enumerate(axes):
    ax.matshow(frames[i], vmin=0, vmax=1)
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)
    ax.set_title(i)
plt.show()

在此處輸入圖像描述

現在您有了這種玩具視頻,可以很直接地將它轉換回某種二進制信號。 您只需計算每幀的平均亮度:

reconstructed = frames.mean(1).mean(1)
reconstructed_bin = reconstructed > 0.5
plt.plot(reconstructed, label='original')
plt.plot(reconstructed_bin, label='binary')
plt.title('Reconstructed Signal')
plt.legend()
plt.show()

在此處輸入圖像描述

從這里我們只需要確定每個 flash 的長度。

# This is ugly, I know. Just for understanding though:
# 1. Splits the binary signal on zero-values
# 2. Filters out the garbage (accept only lists where len(e) > 1)
# 3. Gets the length of the remaining list == the duration of each flash
tmp = np.split(reconstructed_bin, np.where(reconstructed_bin == 0)[0][1:])
flashes = list(map(len, filter(lambda e: len(e) > 1, tmp)))

我們現在可以看看閃光需要多長時間:

print(flashes)

給我們

[5, 5, 5, 10, 9, 9, 5, 5, 5]

所以..“短”閃光似乎需要 5 幀,“長”大約需要 10 幀。有了這個,我們可以通過定義一個合理的閾值 7 將每個 flash 分類為“長”或“短”,如下所示:

# Classify each flash-duration
flashes_classified = list(map(lambda f: 'long' if f > 7 else 'short', flashes))

讓我們重復暫停

# Repeat for pauses
tmp = np.split(reconstructed_bin, np.where(reconstructed_bin != False)[0][1:])
pauses = list(map(len, filter(lambda e: len(e) > 1, tmp)))
pauses_classified = np.asarray(list(map(lambda f: 'w' if f > 6 else 'c', pauses)))
pauses_indices, = np.where(np.asarray(pauses_classified) == 'w') 

現在我們可以將結果可視化。

fig = plt.figure()
ax = fig.gca()
ax.bar(range(len(flashes)), flashes, label='Flash duration')
ax.set_xticks(list(range(len(flashes_classified))))
ax.set_xticklabels(flashes_classified)
[ax.axvline(idx-0.5, ls='--', c='r', label='Pause' if i == 0 else None) for i, idx in enumerate(pauses_indices)]
plt.legend()
plt.show()

在此處輸入圖像描述

這在某種程度上取決於您的環境。 您可以花 1 英鎊試用 Raspberry Pi Zero(9 英鎊)甚至Pico (4 英鎊)或 Arduino 和附加的LDR - 光敏電阻,而不是 100 英鎊的 USB 相機。

然后,您的程序將歸結為反復測量電阻(取決於光強度)並將其變成長脈沖和短脈沖。

這樣做的好處是便宜而且不需要你學習OpenCV ,但 Stefan 的想法要有趣得多,我投了贊成票!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM