import glob
import numpy
from matplotlib import image

def rgb2gray(rgb):
    return numpy.dot(rgb[...,:3], [0.299, 0.587, 0.144])

oldimg = None

for infile in glob.glob('*.JPG'):
    img = rgb2gray(image.imread(infile))

    if oldimg is not None:
        diff = numpy.linalg.norm(img - oldimg)
        # ... do something
    oldimg = img

"""
Explanation: Vogelkamera mit dem Raspberry PI
Rebecca Breu, Juni 2016
Wie alles begann...
<img src="vogeltraenke.png" width=100%>
... wird die überhaupt benutzt?
Erster Versuch: Digitalkamera

Intervallaufnahmen mit Digitalkamera
Suchen nach "interessanten" Bildern mit Python:
End of explanation
"""


from astral import Astral

a = Astral()
a.solar_depression = 3
location = a['Berlin']

location.latitude = 50.9534001
location.longitude = 6.9548886
location.elevation = 56

print(location.dawn())
print(location.dusk())

"""
Explanation: Probleme:

Batterie der Kamera reicht nur für gut drei Stunden
Bilder kopieren und auswerten per Hand wird nervig...

Zweiter Versuch: Raspberry PI und Kamera-Modul
<img src="kamera.png" width="50%">
Sonnenstandsberechnung mit astral
End of explanation
"""


import time
import picamera

with picamera.PiCamera() as camera:
    camera.resolution = (1024, 768)
    camera.start_preview()
    # Camera warm-up time
    time.sleep(2)
    camera.capture('test.png')

    camera.start_recording('my_video.h264', motion_output='motion.data')
    camera.wait_recording(60)
    camera.stop_recording()

"""
Explanation: PICamera — Python-Modul für die Kamera
End of explanation
"""


class MotionAnalyser(picamera.array.PiMotionAnalysis):

    FRAMES = 5

    def __init__(self, *args, **kwargs):
        super(MotionAnalyser, self).__init__(*args, **kwargs)
        self.motion = None
        self.last_motions = deque([0] * self.FRAMES, maxlen=self.FRAMES)

    def analyse(self, m):
        data = numpy.sqrt(
            numpy.square(m['x'].astype(numpy.float)) +
            numpy.square(m['y'].astype(numpy.float))
        )
        norm = numpy.linalg.norm(data)
        self.last_motions.append(norm)
        if min(self.last_motions) > MOTION_THRESHOLD:
            self.motion = True


with MotionAnalyser(camera) as analyser:
    camera.start_recording('/dev/null', format='h264', motion_output=analyser)
    while True:
        if analyser.motion:
            camera.stop_recording()
            # ...
            break
        time.sleep(0.1)

"""
Explanation: Bewegungsdaten

Kamerachip liefert Bewegungsdaten zur Kodierung mit H264-Codec
Es werden 16x16-Pixel-Blöcke betrachtet
Für jeden Block: 2D-Vektor, wohin sich der Block bewegt + Wert, wie sehr sich alter und neuer Block unterscheiden

<img src="motion.png" width="100%">
Testen :)
<img src="test.jpg" width="100%">
Bewegungsdaten on the fly analysieren
End of explanation
"""


from RPi import GPIO
import time

IR_PIN = 14 # data

GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(IR_PIN, GPIO.IN)

try:
    while True:
        if GPIO.input(IR_PIN):
            print('Bewegung!')
        time.sleep(1)
except KeyboardInterrupt:
    GPIO.cleanup()

"""
Explanation: Erste Ergebnisse nach ein paar warmen, trockenen Tagen: Es kommen Vögel zum Trinken und Baden!
Aber...
Wellen durch Wind und Regen = Bewegung :(
<img src="rain.png" width="100%">
Dritter Versuch: Passiver Infrarot-Sensor
<img src="pir.png" width="100%">
<img src="pir_raspi.png" width="100%">
Das RPi-GPIO-Modul
End of explanation
"""


GPIO.add_event_detect(IR_PIN, GPIO.RISING)
while True:
    if GPIO.event_detected(IR_PIN):
        print('Bewegung!')
    time.sleep(1)

"""
Explanation: Das RPi-GPIO-Modul
End of explanation
"""


def my_callback(channel):
    print('Bewegung!')

GPIO.add_event_detect(IR_PIN, GPIO.RISING, callback=my_callback)


"""
Explanation: Interrupts:
End of explanation
"""


motion_mask = matplotlib.image.imread('motion_mask.png')[..., 0]

class MotionAnalyser(picamera.array.PiMotionAnalysis):

    # ...
    
    def analyse(self, m):
        data = numpy.sqrt(
            numpy.square(m['x'].astype(numpy.float)) +
            numpy.square(m['y'].astype(numpy.float))
        )
        data = numpy.multiply(data, motion_mask)
        norm = numpy.linalg.norm(data)
        self.last_motions.append(norm)
        if min(self.last_motions) > MOTION_THRESHOLD:
            self.motion = True

"""
Explanation: Aber...

Sensor nicht empfindlich genug für kleine Vögel
Sensor reagiert träge

:(
Gibt es bessere Sensoren?
Vierter Versuch: Bewegungsanalyse v. 2

Idee: Ignorieren der Wasseroberfläche
Vögel werden zumindestens beim Anflug erkannt und wenn sie auf dem Rand sitzen
Eventuell weniger Aufnahmen von badenden Vögeln in der Mitte der Tränke
Dafür kein Bilder-Spam bei Wind und Regen
Annahme: Kamera immer in gleicher Position, d.h. Wasseroberfläche anhand fester Pixelbereiche identifizierbar

Motion Mask
<img src="motion_mask.png" border="2" width="100%">
Anpassen der Bewegungs-Analyse
End of explanation
"""


