From 8226364eedc86e40afe7cc7d60dd74e1fb3e87fe Mon Sep 17 00:00:00 2001
From: Boyan <boyan@bobokara.com>
Date: Wed, 21 Jun 2023 17:26:37 +0300
Subject: [PATCH] Made NOAA decoder

---
 src/classes/NOAADecoder.py | 65 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 65 insertions(+)
 create mode 100644 src/classes/NOAADecoder.py

diff --git a/src/classes/NOAADecoder.py b/src/classes/NOAADecoder.py
new file mode 100644
index 0000000..acfb32e
--- /dev/null
+++ b/src/classes/NOAADecoder.py
@@ -0,0 +1,65 @@
+# Based on this article:
+# https://medium.com/swlh/decoding-noaa-satellite-images-using-50-lines-of-code-3c5d1d0a08da
+
+import scipy.io.wavfile as wav
+import scipy.signal as signal
+import numpy as np
+import matplotlib.pyplot as plt
+from PIL import Image
+from tqdm import tqdm
+
+class NOAADecoder:
+    def __init__(self, iq_data=None, filename=None) -> None:
+        # Check if iq_data or filename are set correctly
+        if iq_data and filename:
+            raise ValueError("Both iq_data and filename are set.")
+        if not iq_data and not filename:
+            raise ValueError("Neither iq_data nor filename are set.")
+        
+        # Set iq_data or filename
+        if filename:
+            self.filename=filename
+            self.sample_rate, self.data = wav.read(f'{self.filename}')
+        if iq_data:
+            self.sample_rate = 2048000
+            self.data = self.iq_data
+
+    def hilbert(self, data):
+        # Hilbert transform
+        analytical_signal = signal.hilbert(data)
+        amplitude_envelope = np.abs(analytical_signal)
+        return amplitude_envelope
+
+    def decode(self, resample=4):
+
+        # Resample data
+        data = self.data[::resample]
+        sample_rate = self.sample_rate//resample
+        
+        # Demodulate
+        data_am = self.hilbert(data)
+        frame_width = int(0.5*sample_rate)
+        
+        # Image processing
+        w, h = frame_width, data_am.shape[0]//frame_width
+        image = Image.new('L', (w, h))
+        px, py = 0, 0
+        
+        for p in tqdm(range(data_am.shape[0])):
+            if data_am[p][0] != data_am[p][1]:
+                raise BufferError("Mismatch in data array.")
+            lum = int(data_am[p][0]//32 - 32)
+            if lum < 0: lum = 0
+            if lum > 255: lum = 255
+            image.putpixel((px, py),lum)
+            px += 1
+            if px >= w:
+                px = 0
+                py += 1
+                if py >= h:
+                    break
+        image = image.resize((w, 4*h))
+        plt.imshow(image, cmap='gray')
+        # Save image
+        image.save('noaa.png')
+        return
\ No newline at end of file