Difference between revisions of "Team:NAWI Graz/FlourescenceChamber"

Line 62: Line 62:
  
 
     <div class="section container">
 
     <div class="section container">
         <h2 class="section-sub">Camera and Software</h2>
+
         <h2 class="section-sub">Camera</h2>
 
         <div class="section-text container">
 
         <div class="section-text container">
 
             … see “colicam_nu.py” on github/daniel_moser/colibot/server/cam/ … 1 second shutterspeed..
 
             … see “colicam_nu.py” on github/daniel_moser/colibot/server/cam/ … 1 second shutterspeed..
 +
        </div>
 +
    </div>
 +
    <br>
 +
 +
    <div class="section container">
 +
        <h2 class="section-sub">Software</h2>
 +
        <div class="section-text container">
 +
 +
Camera Master:
 +
<br>
 +
<!-- HTML generated using hilite.me --><div style="background: #f8f8f8; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #8f5902; font-style: italic">#!/usr/bin/env python</span>
 +
<span style="color: #8f5902; font-style: italic">&quot;&quot;&quot;</span>
 +
<span style="color: #8f5902; font-style: italic">Code for the master-camera.</span>
 +
 +
<span style="color: #8f5902; font-style: italic">It is connected to the slave-camera via 2 GPIO pins</span>
 +
<span style="color: #8f5902; font-style: italic">and outputs the total detected bacterial state (aggregated</span>
 +
<span style="color: #8f5902; font-style: italic">from both cameras).</span>
 +
 +
<span style="color: #8f5902; font-style: italic">@author: Daniel Hofstadler, 2017</span>
 +
<span style="color: #8f5902; font-style: italic">&quot;&quot;&quot;</span>
 +
<span style="color: #204a87; font-weight: bold">import</span> <span style="color: #000000">os</span>
 +
<span style="color: #204a87; font-weight: bold">import</span> <span style="color: #000000">csv</span>
 +
<span style="color: #204a87; font-weight: bold">import</span> <span style="color: #000000">time</span>
 +
<span style="color: #204a87; font-weight: bold">import</span> <span style="color: #000000">argparse</span>
 +
<span style="color: #204a87; font-weight: bold">import</span> <span style="color: #000000">gpiozero</span>
 +
<span style="color: #204a87; font-weight: bold">from</span> <span style="color: #000000">datetime</span> <span style="color: #204a87; font-weight: bold">import</span> <span style="color: #000000">datetime</span>
 +
<span style="color: #204a87; font-weight: bold">from</span> <span style="color: #000000">fractions</span> <span style="color: #204a87; font-weight: bold">import</span> <span style="color: #000000">Fraction</span>
 +
 +
<span style="color: #204a87; font-weight: bold">import</span> <span style="color: #000000">numpy</span> <span style="color: #204a87; font-weight: bold">as</span> <span style="color: #000000">np</span>
 +
<span style="color: #204a87; font-weight: bold">import</span> <span style="color: #000000">picamera</span>
 +
<span style="color: #204a87; font-weight: bold">import</span> <span style="color: #000000">picamera.array</span>
 +
 +
<span style="color: #204a87; font-weight: bold">from</span> <span style="color: #000000">matplotlib</span> <span style="color: #204a87; font-weight: bold">import</span> <span style="color: #000000">pyplot</span> <span style="color: #204a87; font-weight: bold">as</span> <span style="color: #000000">plt</span>
 +
 +
<span style="color: #8f5902; font-style: italic"># import warnings</span>
 +
<span style="color: #8f5902; font-style: italic"># warnings.filterwarnings(&#39;error&#39;, category=DeprecationWarning)</span>
 +
 +
<span style="color: #8f5902; font-style: italic"># globals</span>
 +
<span style="color: #8f5902; font-style: italic"># LOCAL_TZ = pytz.timezone(&quot;Etc/UTC&quot;)  # read from cams.csv</span>
 +
<span style="color: #000000">OUT_APPEND</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #4e9a06">&quot;_coli&quot;</span>
 +
<span style="color: #000000">CSV_NAME</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #4e9a06">&quot;colicam&quot;</span>
 +
<span style="color: #000000">CSV_HEADER</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000; font-weight: bold">[</span><span style="color: #4e9a06">&quot;framerate&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;exposure_time_us&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;iso&quot;</span><span style="color: #000000; font-weight: bold">,</span>
 +
              <span style="color: #4e9a06">&quot;g1&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;g2&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;g3&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;g4&quot;</span><span style="color: #000000; font-weight: bold">,</span>
 +
              <span style="color: #4e9a06">&quot;timestamp&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;time_utc&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;tag&quot;</span><span style="color: #000000; font-weight: bold">,</span>
 +
              <span style="color: #4e9a06">&quot;red&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;green&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;blue&quot;</span><span style="color: #000000; font-weight: bold">]</span>
 +
<span style="color: #8f5902; font-style: italic"># RESOLUTION = (2592, 1944)</span>
 +
<span style="color: #000000">RESOLUTION</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000; font-weight: bold">(</span><span style="color: #0000cf; font-weight: bold">1280</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #0000cf; font-weight: bold">720</span><span style="color: #000000; font-weight: bold">)</span>
 +
<span style="color: #8f5902; font-style: italic"># REGION_OF_INTEREST = (0.35, 0.4, 0.5, 0.7)</span>
 +
<span style="color: #000000">ROI</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000; font-weight: bold">[</span><span style="color: #0000cf; font-weight: bold">200</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #0000cf; font-weight: bold">520</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #0000cf; font-weight: bold">480</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #0000cf; font-weight: bold">800</span><span style="color: #000000; font-weight: bold">]</span>  <span style="color: #8f5902; font-style: italic"># Y0, Y1, X0, X1</span>
 +
<span style="color: #000000">DETECTION_THRESHOLD</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #0000cf; font-weight: bold">150</span>
 +
<span style="color: #000000">PIN_RX</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #0000cf; font-weight: bold">17</span>
 +
<span style="color: #000000">PIN_TX</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #0000cf; font-weight: bold">18</span>
 +
 +
<span style="color: #000000">SETTINGS_FIXED</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000; font-weight: bold">{</span>
 +
        <span style="color: #4e9a06">&#39;name&#39;</span><span style="color: #000000; font-weight: bold">:</span> <span style="color: #4e9a06">&quot;fixed&quot;</span><span style="color: #000000; font-weight: bold">,</span>
 +
        <span style="color: #4e9a06">&#39;ss&#39;</span><span style="color: #000000; font-weight: bold">:</span> <span style="color: #0000cf; font-weight: bold">1000000</span><span style="color: #000000; font-weight: bold">,</span>  <span style="color: #8f5902; font-style: italic"># 1000 milliseconds = 1 sec</span>
 +
        <span style="color: #4e9a06">&#39;fps&#39;</span><span style="color: #000000; font-weight: bold">:</span> <span style="color: #000000">Fraction</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #0000cf; font-weight: bold">1</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #0000cf; font-weight: bold">2</span><span style="color: #000000; font-weight: bold">),</span>  <span style="color: #8f5902; font-style: italic"># (1, 2)</span>
 +
        <span style="color: #4e9a06">&#39;iso&#39;</span><span style="color: #000000; font-weight: bold">:</span> <span style="color: #0000cf; font-weight: bold">800</span><span style="color: #000000; font-weight: bold">,</span>  <span style="color: #8f5902; font-style: italic"># 800</span>
 +
        <span style="color: #4e9a06">&#39;g&#39;</span><span style="color: #000000; font-weight: bold">:</span> <span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">Fraction</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #0000cf; font-weight: bold">2</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #0000cf; font-weight: bold">1</span><span style="color: #000000; font-weight: bold">),</span> <span style="color: #000000">Fraction</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #0000cf; font-weight: bold">1</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #0000cf; font-weight: bold">1</span><span style="color: #000000; font-weight: bold">)),</span>
 +
        <span style="color: #8f5902; font-style: italic"># &#39;g&#39;: (Fraction(345, 256), Fraction(167, 128)),</span>
 +
        <span style="color: #4e9a06">&#39;sleep&#39;</span><span style="color: #000000; font-weight: bold">:</span> <span style="color: #0000cf; font-weight: bold">15</span><span style="color: #000000; font-weight: bold">}</span>  <span style="color: #8f5902; font-style: italic"># 10</span>
 +
<span style="color: #000000">SETTINGS_SENSITIVE</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000; font-weight: bold">{</span>
 +
        <span style="color: #4e9a06">&#39;name&#39;</span><span style="color: #000000; font-weight: bold">:</span> <span style="color: #4e9a06">&quot;sensitive&quot;</span><span style="color: #000000; font-weight: bold">,</span>
 +
        <span style="color: #4e9a06">&#39;ss&#39;</span><span style="color: #000000; font-weight: bold">:</span> <span style="color: #0000cf; font-weight: bold">6000000</span><span style="color: #000000; font-weight: bold">,</span>  <span style="color: #8f5902; font-style: italic"># 6 seconds</span>
 +
        <span style="color: #4e9a06">&#39;fps&#39;</span><span style="color: #000000; font-weight: bold">:</span> <span style="color: #000000">Fraction</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #0000cf; font-weight: bold">1</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #0000cf; font-weight: bold">6</span><span style="color: #000000; font-weight: bold">),</span>
 +
        <span style="color: #4e9a06">&#39;iso&#39;</span><span style="color: #000000; font-weight: bold">:</span> <span style="color: #0000cf; font-weight: bold">800</span><span style="color: #000000; font-weight: bold">,</span>
 +
        <span style="color: #4e9a06">&#39;g&#39;</span><span style="color: #000000; font-weight: bold">:</span> <span style="color: #3465a4">None</span><span style="color: #000000; font-weight: bold">,</span>
 +
        <span style="color: #4e9a06">&#39;sleep&#39;</span><span style="color: #000000; font-weight: bold">:</span> <span style="color: #0000cf; font-weight: bold">30</span><span style="color: #000000; font-weight: bold">}</span>
 +
<span style="color: #000000">SETTINGS_AUTO</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000; font-weight: bold">{</span>
 +
        <span style="color: #4e9a06">&#39;name&#39;</span><span style="color: #000000; font-weight: bold">:</span> <span style="color: #4e9a06">&quot;auto&quot;</span><span style="color: #000000; font-weight: bold">,</span>
 +
        <span style="color: #4e9a06">&#39;ss&#39;</span><span style="color: #000000; font-weight: bold">:</span> <span style="color: #3465a4">None</span><span style="color: #000000; font-weight: bold">,</span>
 +
        <span style="color: #4e9a06">&#39;fps&#39;</span><span style="color: #000000; font-weight: bold">:</span> <span style="color: #0000cf; font-weight: bold">30</span><span style="color: #000000; font-weight: bold">,</span>
 +
        <span style="color: #4e9a06">&#39;iso&#39;</span><span style="color: #000000; font-weight: bold">:</span> <span style="color: #0000cf; font-weight: bold">0</span><span style="color: #000000; font-weight: bold">,</span>
 +
        <span style="color: #4e9a06">&#39;g&#39;</span><span style="color: #000000; font-weight: bold">:</span> <span style="color: #3465a4">None</span><span style="color: #000000; font-weight: bold">,</span>
 +
        <span style="color: #4e9a06">&#39;sleep&#39;</span><span style="color: #000000; font-weight: bold">:</span> <span style="color: #0000cf; font-weight: bold">2</span><span style="color: #000000; font-weight: bold">}</span>
 +
 +
<span style="color: #000000">SETTINGS_DEFAULT</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #4e9a06">&quot;fixed&quot;</span>
 +
 +
<span style="color: #8f5902; font-style: italic"># argument parsing</span>
 +
<span style="color: #000000">parser</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">argparse</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">ArgumentParser</span><span style="color: #000000; font-weight: bold">(</span>
 +
        <span style="color: #000000">description</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #4e9a06">&quot;Colibot Photometer Camera.&quot;</span><span style="color: #000000; font-weight: bold">)</span>
 +
<span style="color: #000000">parser</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">add_argument</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;-d&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;--debug&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">action</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #4e9a06">&quot;store_true&quot;</span><span style="color: #000000; font-weight: bold">,</span>
 +
                    <span style="color: #000000">help</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #4e9a06">&quot;debug mode&quot;</span><span style="color: #000000; font-weight: bold">)</span>
 +
<span style="color: #000000">parser</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">add_argument</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;-m&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;--mode&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #204a87">type</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #204a87">str</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">default</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #4e9a06">&quot;fixed&quot;</span><span style="color: #000000; font-weight: bold">,</span>
 +
                    <span style="color: #000000">choices</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #4e9a06">&quot;f&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;fixed&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;s&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;sensitive&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;a&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;auto&quot;</span><span style="color: #000000; font-weight: bold">],</span>
 +
                    <span style="color: #000000">help</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #4e9a06">&quot;set the camera mode&quot;</span><span style="color: #000000; font-weight: bold">)</span>
 +
<span style="color: #000000">parser</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">add_argument</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;-p&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;--postfix&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #204a87">type</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #204a87">str</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">default</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #4e9a06">&quot;&quot;</span><span style="color: #000000; font-weight: bold">,</span>
 +
                    <span style="color: #000000">help</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #4e9a06">&quot;add string to filename&quot;</span><span style="color: #000000; font-weight: bold">)</span>
 +
<span style="color: #8f5902; font-style: italic"># args = vars(ap.parse_args())</span>
 +
<span style="color: #000000">args</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">parser</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">parse_args</span><span style="color: #000000; font-weight: bold">()</span>
 +
<span style="color: #204a87; font-weight: bold">if</span> <span style="color: #204a87; font-weight: bold">not</span> <span style="color: #000000">args</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">postfix</span> <span style="color: #ce5c00; font-weight: bold">==</span> <span style="color: #4e9a06">&quot;&quot;</span> <span style="color: #204a87; font-weight: bold">and</span> <span style="color: #204a87; font-weight: bold">not</span> <span style="color: #000000">args</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">postfix</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">startswith</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;_&quot;</span><span style="color: #000000; font-weight: bold">):</span>
 +
    <span style="color: #000000">args</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">postfix</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #4e9a06">&quot;_&quot;</span> <span style="color: #ce5c00; font-weight: bold">+</span> <span style="color: #000000">args</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">postfix</span>
 +
 +
 +
<span style="color: #204a87; font-weight: bold">def</span> <span style="color: #000000">now_str</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">pattern</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #4e9a06">&quot;_%y%m%d-%H%M%S_utc&quot;</span><span style="color: #000000; font-weight: bold">):</span>
 +
    <span style="color: #8f5902; font-style: italic"># return time.strftime(pattern, time.gmtime())</span>
 +
    <span style="color: #204a87; font-weight: bold">return</span> <span style="color: #000000">datetime</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">utcnow</span><span style="color: #000000; font-weight: bold">()</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">strftime</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">pattern</span><span style="color: #000000; font-weight: bold">)</span>
 +
 +
 +
<span style="color: #204a87; font-weight: bold">def</span> <span style="color: #000000">from_timestamp</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">ts</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">pattern</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #4e9a06">&quot;%y%m%d-%H%M%S_utc&quot;</span><span style="color: #000000; font-weight: bold">):</span>
 +
    <span style="color: #204a87; font-weight: bold">return</span> <span style="color: #000000">datetime</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">utcfromtimestamp</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">ts</span><span style="color: #000000; font-weight: bold">)</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">strftime</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">pattern</span><span style="color: #000000; font-weight: bold">)</span>
 +
 +
 +
<span style="color: #204a87; font-weight: bold">def</span> <span style="color: #000000">safename</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">s</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">s_type</span><span style="color: #000000; font-weight: bold">):</span>
 +
    <span style="color: #8f5902; font-style: italic">&quot;&quot;&quot;Check whether a given file or folder &#39;s&#39; exists, return a non-existing</span>
 +
<span style="color: #8f5902; font-style: italic">    filename.</span>
 +
<span style="color: #8f5902; font-style: italic">    s ........ (full) filename or directory</span>
 +
<span style="color: #8f5902; font-style: italic">    s_type ... &#39;file&#39; or &#39;f&#39; for files,</span>
 +
<span style="color: #8f5902; font-style: italic">              &#39;directory&#39; or &#39;dir&#39; or &#39;d&#39; for folders</span>
 +
<span style="color: #8f5902; font-style: italic">    Returns a file- or pathname that is supposedly safe to save</span>
 +
<span style="color: #8f5902; font-style: italic">    without overwriting data.</span>
 +
<span style="color: #8f5902; font-style: italic">    &quot;&quot;&quot;</span>
 +
    <span style="color: #000000">low_type</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #204a87">str</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">lower</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">s_type</span><span style="color: #000000; font-weight: bold">)</span>
 +
    <span style="color: #204a87; font-weight: bold">if</span> <span style="color: #000000">low_type</span> <span style="color: #ce5c00; font-weight: bold">==</span> <span style="color: #4e9a06">&#39;file&#39;</span> <span style="color: #204a87; font-weight: bold">or</span> <span style="color: #000000">low_type</span> <span style="color: #ce5c00; font-weight: bold">==</span> <span style="color: #4e9a06">&#39;f&#39;</span><span style="color: #000000; font-weight: bold">:</span>
 +
        <span style="color: #204a87; font-weight: bold">if</span> <span style="color: #000000">os</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">path</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">isfile</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">s</span><span style="color: #000000; font-weight: bold">):</span>
 +
            <span style="color: #000000">s2</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">s</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">split</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&#39;.&#39;</span><span style="color: #000000; font-weight: bold">)</span>
 +
            <span style="color: #000000">s_base</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">s2</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #0000cf; font-weight: bold">0</span><span style="color: #000000; font-weight: bold">]</span>
 +
            <span style="color: #000000">s_ext</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">s2</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #ce5c00; font-weight: bold">-</span><span style="color: #0000cf; font-weight: bold">1</span><span style="color: #000000; font-weight: bold">]</span>
 +
 +
            <span style="color: #000000">counter</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #0000cf; font-weight: bold">0</span>
 +
            <span style="color: #204a87; font-weight: bold">while</span> <span style="color: #000000">os</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">path</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">isfile</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">s</span><span style="color: #000000; font-weight: bold">):</span>
 +
                <span style="color: #000000">s</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">s_base</span> <span style="color: #ce5c00; font-weight: bold">+</span> <span style="color: #4e9a06">&quot;-{:02d}.&quot;</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">format</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">counter</span><span style="color: #000000; font-weight: bold">)</span> <span style="color: #ce5c00; font-weight: bold">+</span> <span style="color: #000000">s_ext</span>
 +
                <span style="color: #000000">counter</span> <span style="color: #ce5c00; font-weight: bold">+=</span> <span style="color: #0000cf; font-weight: bold">1</span>
 +
 +
    <span style="color: #204a87; font-weight: bold">elif</span> <span style="color: #000000">low_type</span> <span style="color: #ce5c00; font-weight: bold">==</span> <span style="color: #4e9a06">&#39;directory&#39;</span> <span style="color: #204a87; font-weight: bold">or</span> <span style="color: #000000">low_type</span> <span style="color: #ce5c00; font-weight: bold">==</span> <span style="color: #4e9a06">&#39;dir&#39;</span> <span style="color: #204a87; font-weight: bold">or</span> <span style="color: #000000">low_type</span> <span style="color: #ce5c00; font-weight: bold">==</span> <span style="color: #4e9a06">&#39;d&#39;</span><span style="color: #000000; font-weight: bold">:</span>
 +
        <span style="color: #204a87; font-weight: bold">if</span> <span style="color: #000000">os</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">path</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">isdir</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">s</span><span style="color: #000000; font-weight: bold">):</span>
 +
            <span style="color: #000000">s_base</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">s</span>
 +
 +
            <span style="color: #000000">counter</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #0000cf; font-weight: bold">0</span>
 +
            <span style="color: #204a87; font-weight: bold">while</span> <span style="color: #000000">os</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">path</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">isdir</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">s</span><span style="color: #000000; font-weight: bold">):</span>
 +
                <span style="color: #000000">s</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">s_base</span> <span style="color: #ce5c00; font-weight: bold">+</span> <span style="color: #4e9a06">&quot;-{:02d}&quot;</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">format</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">counter</span><span style="color: #000000; font-weight: bold">)</span>
 +
                <span style="color: #000000">counter</span> <span style="color: #ce5c00; font-weight: bold">+=</span> <span style="color: #0000cf; font-weight: bold">1</span>
 +
    <span style="color: #204a87; font-weight: bold">return</span> <span style="color: #000000">s</span>
 +
 +
 +
<span style="color: #204a87; font-weight: bold">class</span> <span style="color: #000000">ColiCamMaster</span><span style="color: #000000; font-weight: bold">:</span>
 +
    <span style="color: #204a87; font-weight: bold">global</span> <span style="color: #000000">RESOLUTION</span>
 +
    <span style="color: #204a87; font-weight: bold">global</span> <span style="color: #000000">ROI</span>  <span style="color: #8f5902; font-style: italic"># REGION_OF_INTEREST</span>
 +
    <span style="color: #204a87; font-weight: bold">global</span> <span style="color: #000000">DETECTION_THRESHOLD</span>
 +
    <span style="color: #204a87; font-weight: bold">global</span> <span style="color: #000000">SETTINGS_FIXED</span>
 +
    <span style="color: #204a87; font-weight: bold">global</span> <span style="color: #000000">SETTINGS_SENSITIVE</span>
 +
    <span style="color: #204a87; font-weight: bold">global</span> <span style="color: #000000">SETTINGS_AUTO</span>
 +
    <span style="color: #204a87; font-weight: bold">global</span> <span style="color: #000000">DEF_SETTINGS_NAME</span>
 +
    <span style="color: #204a87; font-weight: bold">global</span> <span style="color: #000000">PIN_RX</span>
 +
    <span style="color: #204a87; font-weight: bold">global</span> <span style="color: #000000">PIN_TX</span>
 +
 +
    <span style="color: #204a87; font-weight: bold">def</span> <span style="color: #000000">__init__</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #3465a4">self</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">resolution</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #000000">RESOLUTION</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">mode</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #000000">DEF_SETTINGS_NAME</span><span style="color: #000000; font-weight: bold">):</span>
 +
        <span style="color: #204a87; font-weight: bold">try</span><span style="color: #000000; font-weight: bold">:</span>
 +
            <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">picamera</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">PiCamera</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">resolution</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #000000">resolution</span><span style="color: #000000; font-weight: bold">)</span>
 +
            <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">set_cam</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">mode</span><span style="color: #000000; font-weight: bold">)</span>
 +
        <span style="color: #204a87; font-weight: bold">except</span> <span style="color: #cc0000; font-weight: bold">Exception</span> <span style="color: #204a87; font-weight: bold">as</span> <span style="color: #000000">err</span><span style="color: #000000; font-weight: bold">:</span>
 +
            <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #4e9a06">&quot;&quot;</span>
 +
            <span style="color: #204a87; font-weight: bold">print</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;couldn&#39;t initialize camera, error: {}&quot;</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">format</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">err</span><span style="color: #000000; font-weight: bold">))</span>
 +
        <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">rx</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">gpiozero</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">InputDevice</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">PIN_RX</span><span style="color: #000000; font-weight: bold">)</span>
 +
        <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">tx</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">gpiozero</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">OutputDevice</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">PIN_TX</span><span style="color: #000000; font-weight: bold">)</span>
 +
 +
    <span style="color: #204a87; font-weight: bold">def</span> <span style="color: #000000">set_cam</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #3465a4">self</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">mode</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #4e9a06">&quot;fixed&quot;</span><span style="color: #000000; font-weight: bold">):</span>
 +
 +
        <span style="color: #204a87; font-weight: bold">if</span> <span style="color: #000000">mode</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">lower</span><span style="color: #000000; font-weight: bold">()</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">startswith</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;f&quot;</span><span style="color: #000000; font-weight: bold">):</span>
 +
            <span style="color: #000000">settings</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">SETTINGS_FIXED</span>
 +
        <span style="color: #204a87; font-weight: bold">elif</span> <span style="color: #000000">mode</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">lower</span><span style="color: #000000; font-weight: bold">()</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">startswith</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;s&quot;</span><span style="color: #000000; font-weight: bold">):</span>
 +
            <span style="color: #000000">settings</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">SETTINGS_SENSITIVE</span>
 +
        <span style="color: #204a87; font-weight: bold">elif</span> <span style="color: #000000">mode</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">lower</span><span style="color: #000000; font-weight: bold">()</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">startswith</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;a&quot;</span><span style="color: #000000; font-weight: bold">):</span>
 +
            <span style="color: #000000">settings</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">SETTINGS_AUTO</span>
 +
        <span style="color: #204a87; font-weight: bold">else</span><span style="color: #000000; font-weight: bold">:</span>
 +
            <span style="color: #204a87; font-weight: bold">print</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;wrong camera mode&quot;</span><span style="color: #000000; font-weight: bold">)</span>
 +
 +
        <span style="color: #8f5902; font-style: italic"># switch on auto mode</span>
 +
        <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">awb_mode</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #4e9a06">&#39;auto&#39;</span>
 +
        <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">exposure_mode</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #4e9a06">&#39;auto&#39;</span>
 +
 +
        <span style="color: #8f5902; font-style: italic"># settings = dict with fields: name, ss, fps, iso, g, sleep</span>
 +
        <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">framerate</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">settings</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #4e9a06">&#39;fps&#39;</span><span style="color: #000000; font-weight: bold">]</span>
 +
        <span style="color: #204a87; font-weight: bold">if</span> <span style="color: #000000">settings</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #4e9a06">&#39;ss&#39;</span><span style="color: #000000; font-weight: bold">]:</span>
 +
            <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">shutter_speed</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">settings</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #4e9a06">&#39;ss&#39;</span><span style="color: #000000; font-weight: bold">]</span>
 +
        <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">iso</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">settings</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #4e9a06">&#39;iso&#39;</span><span style="color: #000000; font-weight: bold">]</span>
 +
 +
        <span style="color: #8f5902; font-style: italic"># Wait for the automatic gain control to settle</span>
 +
        <span style="color: #000000">time</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">sleep</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">settings</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #4e9a06">&#39;sleep&#39;</span><span style="color: #000000; font-weight: bold">])</span>
 +
 +
        <span style="color: #8f5902; font-style: italic"># Now fix the values</span>
 +
        <span style="color: #204a87; font-weight: bold">if</span> <span style="color: #204a87; font-weight: bold">not</span> <span style="color: #000000">settings</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #4e9a06">&#39;ss&#39;</span><span style="color: #000000; font-weight: bold">]:</span>
 +
            <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">shutter_speed</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">exposure_speed</span>
 +
        <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">exposure_mode</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #4e9a06">&#39;off&#39;</span>
 +
 +
        <span style="color: #204a87; font-weight: bold">if</span> <span style="color: #000000">settings</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #4e9a06">&#39;g&#39;</span><span style="color: #000000; font-weight: bold">]:</span>
 +
            <span style="color: #000000">g</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">settings</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #4e9a06">&#39;g&#39;</span><span style="color: #000000; font-weight: bold">]</span>
 +
        <span style="color: #204a87; font-weight: bold">else</span><span style="color: #000000; font-weight: bold">:</span>
 +
            <span style="color: #000000">g</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">awb_gains</span>
 +
        <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">awb_mode</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #4e9a06">&#39;off&#39;</span>
 +
        <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">awb_gains</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">g</span>
 +
 +
    <span style="color: #204a87; font-weight: bold">def</span> <span style="color: #000000">measure</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #3465a4">self</span><span style="color: #000000; font-weight: bold">,</span>
 +
                <span style="color: #000000">roi</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #000000">ROI</span><span style="color: #000000; font-weight: bold">,</span>
 +
                <span style="color: #000000">channel_name</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #4e9a06">&quot;green&quot;</span><span style="color: #000000; font-weight: bold">,</span>
 +
                <span style="color: #000000">threshold</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #000000">DETECTION_THRESHOLD</span><span style="color: #000000; font-weight: bold">,</span>
 +
                <span style="color: #000000">dir_out</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #3465a4">None</span><span style="color: #000000; font-weight: bold">,</span>
 +
                <span style="color: #000000">csv_out</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #3465a4">None</span><span style="color: #000000; font-weight: bold">,</span>
 +
                <span style="color: #000000">postfix</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #4e9a06">&quot;&quot;</span><span style="color: #000000; font-weight: bold">):</span>
 +
 +
        <span style="color: #8f5902; font-style: italic"># notify other camera to take a picture</span>
 +
        <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">tx</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">on</span><span style="color: #000000; font-weight: bold">()</span>
 +
 +
        <span style="color: #8f5902; font-style: italic"># check whether channel is valid</span>
 +
        <span style="color: #204a87; font-weight: bold">if</span> <span style="color: #000000">channel_name</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">lower</span><span style="color: #000000; font-weight: bold">()</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">startswith</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;r&quot;</span><span style="color: #000000; font-weight: bold">):</span>
 +
            <span style="color: #000000">channel</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #0000cf; font-weight: bold">0</span>
 +
            <span style="color: #000000">channel_name</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #4e9a06">&quot;red&quot;</span>
 +
        <span style="color: #204a87; font-weight: bold">elif</span> <span style="color: #000000">channel_name</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">lower</span><span style="color: #000000; font-weight: bold">()</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">startswith</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;g&quot;</span><span style="color: #000000; font-weight: bold">):</span>
 +
            <span style="color: #000000">channel</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #0000cf; font-weight: bold">1</span>
 +
            <span style="color: #000000">channel_name</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #4e9a06">&quot;green&quot;</span>
 +
        <span style="color: #204a87; font-weight: bold">elif</span> <span style="color: #000000">channel_name</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">lower</span><span style="color: #000000; font-weight: bold">()</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">startswith</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;b&quot;</span><span style="color: #000000; font-weight: bold">):</span>
 +
            <span style="color: #000000">channel</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #0000cf; font-weight: bold">2</span>
 +
            <span style="color: #000000">channel_name</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #4e9a06">&quot;blue&quot;</span>
 +
        <span style="color: #204a87; font-weight: bold">else</span><span style="color: #000000; font-weight: bold">:</span>
 +
            <span style="color: #204a87; font-weight: bold">print</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;wrong channel_name: &#39;{}&#39;&quot;</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">format</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">channel_name</span><span style="color: #000000; font-weight: bold">))</span>
 +
 +
        <span style="color: #8f5902; font-style: italic"># get camera settings</span>
 +
        <span style="color: #000000">time</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">sleep</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #0000cf; font-weight: bold">1</span><span style="color: #000000; font-weight: bold">)</span>
 +
        <span style="color: #000000">fps</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #204a87">float</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">framerate</span><span style="color: #000000; font-weight: bold">)</span>
 +
        <span style="color: #000000">ss</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">exposure_speed</span>
 +
        <span style="color: #000000">g</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">awb_gains</span>
 +
        <span style="color: #000000">g1</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">g</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #0000cf; font-weight: bold">0</span><span style="color: #000000; font-weight: bold">]</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">numerator</span>
 +
        <span style="color: #000000">g2</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">g</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #0000cf; font-weight: bold">0</span><span style="color: #000000; font-weight: bold">]</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">denominator</span>
 +
        <span style="color: #000000">g3</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">g</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #0000cf; font-weight: bold">1</span><span style="color: #000000; font-weight: bold">]</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">numerator</span>
 +
        <span style="color: #000000">g4</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">g</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #0000cf; font-weight: bold">1</span><span style="color: #000000; font-weight: bold">]</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">denominator</span>
 +
        <span style="color: #000000">iso</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">iso</span>
 +
        <span style="color: #000000">settings_str</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #4e9a06">&quot;ss{}_g{}-{}_{}-{}_iso{}_&quot;</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">format</span><span style="color: #000000; font-weight: bold">(</span>
 +
                <span style="color: #000000">ss</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">g1</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">g2</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">g3</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">g4</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">iso</span><span style="color: #000000; font-weight: bold">)</span>
 +
        <span style="color: #000000">csv_row</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000; font-weight: bold">[</span><span style="color: #000000">fps</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">ss</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">iso</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">g1</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">g2</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">g3</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">g4</span><span style="color: #000000; font-weight: bold">]</span>
 +
        <span style="color: #204a87; font-weight: bold">print</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;taking photos with settings: {}&quot;</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">format</span><span style="color: #000000; font-weight: bold">(</span>
 +
                <span style="color: #000000">settings_str</span><span style="color: #000000; font-weight: bold">))</span>
 +
 +
        <span style="color: #8f5902; font-style: italic"># with picamera.PiCamera(resolution=RESOLUTION) as cam:</span>
 +
        <span style="color: #8f5902; font-style: italic"># https://picamera.readthedocs.io/en/latest/</span>
 +
        <span style="color: #8f5902; font-style: italic">#        api_array.html#module-picamera.array</span>
 +
        <span style="color: #204a87; font-weight: bold">with</span> <span style="color: #000000">picamera</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">array</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">PiRGBArray</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span><span style="color: #000000; font-weight: bold">)</span> <span style="color: #204a87; font-weight: bold">as</span> <span style="color: #000000">output</span><span style="color: #000000; font-weight: bold">:</span>
 +
 +
            <span style="color: #8f5902; font-style: italic"># cam.zoom = REGION_OF_INTEREST</span>
 +
            <span style="color: #8f5902; font-style: italic"># cam.start_preview()</span>
 +
 +
            <span style="color: #8f5902; font-style: italic"># take picture</span>
 +
            <span style="color: #000000">t0</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">time</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">time</span><span style="color: #000000; font-weight: bold">()</span>
 +
            <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">capture</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">output</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">format</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #4e9a06">&quot;rgb&quot;</span><span style="color: #000000; font-weight: bold">)</span>
 +
            <span style="color: #000000">a</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">output</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">array</span>
 +
            <span style="color: #000000">t1</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">time</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">time</span><span style="color: #000000; font-weight: bold">()</span>
 +
            <span style="color: #204a87; font-weight: bold">print</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;recorded for {} sec&quot;</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">format</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #204a87">round</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">t1</span><span style="color: #ce5c00; font-weight: bold">-</span><span style="color: #000000">t0</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #0000cf; font-weight: bold">2</span><span style="color: #000000; font-weight: bold">)))</span>
 +
            <span style="color: #000000">t_pic</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #204a87">int</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #204a87">round</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">np</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">mean</span><span style="color: #000000; font-weight: bold">([</span><span style="color: #000000">t0</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">t1</span><span style="color: #000000; font-weight: bold">])))</span>
 +
            <span style="color: #8f5902; font-style: italic"># re-empty output (to reuse next iteration)</span>
 +
            <span style="color: #8f5902; font-style: italic"># output.truncate(0)</span>
 +
 +
        <span style="color: #8f5902; font-style: italic"># crop to region of interest</span>
 +
        <span style="color: #000000">roi</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">a</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #000000">ROI</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #0000cf; font-weight: bold">0</span><span style="color: #000000; font-weight: bold">]:</span><span style="color: #000000">ROI</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #0000cf; font-weight: bold">1</span><span style="color: #000000; font-weight: bold">],</span> <span style="color: #000000">ROI</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #0000cf; font-weight: bold">2</span><span style="color: #000000; font-weight: bold">]:</span><span style="color: #000000">ROI</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #0000cf; font-weight: bold">3</span><span style="color: #000000; font-weight: bold">],</span> <span style="color: #000000; font-weight: bold">:]</span>
 +
 +
        <span style="color: #000000">vals</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000; font-weight: bold">[]</span>
 +
        <span style="color: #000000">vals</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">append</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">np</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">median</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">roi</span><span style="color: #000000; font-weight: bold">[:,</span> <span style="color: #000000; font-weight: bold">:,</span> <span style="color: #0000cf; font-weight: bold">0</span><span style="color: #000000; font-weight: bold">]))</span>
 +
        <span style="color: #000000">vals</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">append</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">np</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">median</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">roi</span><span style="color: #000000; font-weight: bold">[:,</span> <span style="color: #000000; font-weight: bold">:,</span> <span style="color: #0000cf; font-weight: bold">1</span><span style="color: #000000; font-weight: bold">]))</span>
 +
        <span style="color: #000000">vals</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">append</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">np</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">median</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">roi</span><span style="color: #000000; font-weight: bold">[:,</span> <span style="color: #000000; font-weight: bold">:,</span> <span style="color: #0000cf; font-weight: bold">2</span><span style="color: #000000; font-weight: bold">]))</span>
 +
 +
        <span style="color: #204a87; font-weight: bold">print</span><span style="color: #000000; font-weight: bold">((</span><span style="color: #4e9a06">&quot;roi.shape={},\n&quot;</span> <span style="color: #ce5c00; font-weight: bold">+</span>
 +
              <span style="color: #8f5902; font-style: italic"># &quot;sum(red)={}, sum(green)={}, sum(blue)={},\n&quot; +</span>
 +
              <span style="color: #4e9a06">&quot;med(red)={}, med(green)={}, med(blue)={}&quot;</span><span style="color: #000000; font-weight: bold">)</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">format</span><span style="color: #000000; font-weight: bold">(</span>
 +
                      <span style="color: #000000">roi</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">shape</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">vals</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #0000cf; font-weight: bold">0</span><span style="color: #000000; font-weight: bold">],</span> <span style="color: #000000">vals</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #0000cf; font-weight: bold">1</span><span style="color: #000000; font-weight: bold">],</span> <span style="color: #000000">vals</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #0000cf; font-weight: bold">2</span><span style="color: #000000; font-weight: bold">]))</span>
 +
 +
        <span style="color: #000000">val</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">vals</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #000000">channel</span><span style="color: #000000; font-weight: bold">]</span>
 +
        <span style="color: #204a87; font-weight: bold">print</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;reading the {} channel...\nvalue: {}&quot;</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">format</span><span style="color: #000000; font-weight: bold">(</span>
 +
                <span style="color: #000000">channel_name</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">val</span><span style="color: #000000; font-weight: bold">))</span>
 +
        <span style="color: #204a87; font-weight: bold">if</span> <span style="color: #000000">val</span> <span style="color: #ce5c00; font-weight: bold">&gt;=</span> <span style="color: #000000">threshold</span><span style="color: #000000; font-weight: bold">:</span>
 +
            <span style="color: #000000">activated</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #3465a4">True</span>
 +
        <span style="color: #204a87; font-weight: bold">else</span><span style="color: #000000; font-weight: bold">:</span>
 +
            <span style="color: #000000">activated</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #3465a4">False</span>
 +
        <span style="color: #204a87; font-weight: bold">print</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;active={} (threshold: {})&quot;</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">format</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">activated</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">threshold</span><span style="color: #000000; font-weight: bold">))</span>
 +
 +
        <span style="color: #8f5902; font-style: italic"># debug mode:</span>
 +
        <span style="color: #8f5902; font-style: italic"># output images and csv if output directory exists</span>
 +
        <span style="color: #204a87; font-weight: bold">if</span> <span style="color: #000000">dir_out</span><span style="color: #000000; font-weight: bold">:</span>
 +
 +
            <span style="color: #000000">names</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000; font-weight: bold">[</span><span style="color: #4e9a06">&quot;1-red&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;2-green&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;3-blue&quot;</span><span style="color: #000000; font-weight: bold">]</span>
 +
 +
            <span style="color: #8f5902; font-style: italic"># whole images</span>
 +
            <span style="color: #000000">fn</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #4e9a06">&quot;full_{}{}_0-rgb{}.png&quot;</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">format</span><span style="color: #000000; font-weight: bold">(</span>
 +
                    <span style="color: #000000">settings_str</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">postfix</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">now_str</span><span style="color: #000000; font-weight: bold">())</span>
 +
            <span style="color: #000000">ffn</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">safename</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">os</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">path</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">join</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">dir_out</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">fn</span><span style="color: #000000; font-weight: bold">),</span> <span style="color: #4e9a06">&quot;file&quot;</span><span style="color: #000000; font-weight: bold">)</span>
 +
            <span style="color: #000000">plt</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">imsave</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">ffn</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">a</span><span style="color: #000000; font-weight: bold">)</span>
 +
            <span style="color: #204a87; font-weight: bold">for</span> <span style="color: #000000">i</span> <span style="color: #204a87; font-weight: bold">in</span> <span style="color: #204a87">range</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #0000cf; font-weight: bold">3</span><span style="color: #000000; font-weight: bold">):</span>
 +
                <span style="color: #000000">fn</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #4e9a06">&quot;full_{}{}_{}{}.png&quot;</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">format</span><span style="color: #000000; font-weight: bold">(</span>
 +
                        <span style="color: #000000">settings_str</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">postfix</span><span style="color: #000000; font-weight: bold">,</span>
 +
                        <span style="color: #000000">names</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #000000">i</span><span style="color: #000000; font-weight: bold">],</span> <span style="color: #000000">now_str</span><span style="color: #000000; font-weight: bold">())</span>
 +
                <span style="color: #000000">ffn</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">safename</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">os</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">path</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">join</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">dir_out</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">fn</span><span style="color: #000000; font-weight: bold">),</span> <span style="color: #4e9a06">&quot;file&quot;</span><span style="color: #000000; font-weight: bold">)</span>
 +
                <span style="color: #000000">plt</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">imsave</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">ffn</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">a</span><span style="color: #000000; font-weight: bold">[:,</span> <span style="color: #000000; font-weight: bold">:,</span> <span style="color: #000000">i</span><span style="color: #000000; font-weight: bold">],</span> <span style="color: #000000">vmin</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #0000cf; font-weight: bold">0</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">vmax</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #0000cf; font-weight: bold">255</span><span style="color: #000000; font-weight: bold">)</span>
 +
 +
            <span style="color: #8f5902; font-style: italic"># cropped to ROI</span>
 +
            <span style="color: #000000">fn</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #4e9a06">&quot;roi_{}{}_0-rgb{}.png&quot;</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">format</span><span style="color: #000000; font-weight: bold">(</span>
 +
                    <span style="color: #000000">settings_str</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">postfix</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">now_str</span><span style="color: #000000; font-weight: bold">())</span>
 +
            <span style="color: #000000">ffn</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">safename</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">os</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">path</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">join</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">dir_out</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">fn</span><span style="color: #000000; font-weight: bold">),</span> <span style="color: #4e9a06">&quot;file&quot;</span><span style="color: #000000; font-weight: bold">)</span>
 +
            <span style="color: #000000">plt</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">imsave</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">ffn</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">roi</span><span style="color: #000000; font-weight: bold">)</span>
 +
            <span style="color: #204a87; font-weight: bold">for</span> <span style="color: #000000">i</span> <span style="color: #204a87; font-weight: bold">in</span> <span style="color: #204a87">range</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #0000cf; font-weight: bold">3</span><span style="color: #000000; font-weight: bold">):</span>
 +
                <span style="color: #000000">fn</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #4e9a06">&quot;roi_{}{}_{}{}.png&quot;</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">format</span><span style="color: #000000; font-weight: bold">(</span>
 +
                        <span style="color: #000000">settings_str</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">postfix</span><span style="color: #000000; font-weight: bold">,</span>
 +
                        <span style="color: #000000">names</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #000000">i</span><span style="color: #000000; font-weight: bold">],</span> <span style="color: #000000">now_str</span><span style="color: #000000; font-weight: bold">())</span>
 +
                <span style="color: #000000">ffn</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">safename</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">os</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">path</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">join</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">dir_out</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">fn</span><span style="color: #000000; font-weight: bold">),</span> <span style="color: #4e9a06">&quot;file&quot;</span><span style="color: #000000; font-weight: bold">)</span>
 +
                <span style="color: #000000">plt</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">imsave</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">ffn</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">roi</span><span style="color: #000000; font-weight: bold">[:,</span> <span style="color: #000000; font-weight: bold">:,</span> <span style="color: #000000">i</span><span style="color: #000000; font-weight: bold">],</span> <span style="color: #000000">vmin</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #0000cf; font-weight: bold">0</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">vmax</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #0000cf; font-weight: bold">255</span><span style="color: #000000; font-weight: bold">)</span>
 +
 +
            <span style="color: #000000">csv_row</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">extend</span><span style="color: #000000; font-weight: bold">([</span><span style="color: #000000">t_pic</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">from_timestamp</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">t_pic</span><span style="color: #000000; font-weight: bold">),</span> <span style="color: #000000">postfix</span><span style="color: #000000; font-weight: bold">,</span>
 +
                            <span style="color: #000000">vals</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #0000cf; font-weight: bold">0</span><span style="color: #000000; font-weight: bold">],</span> <span style="color: #000000">vals</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #0000cf; font-weight: bold">1</span><span style="color: #000000; font-weight: bold">],</span> <span style="color: #000000">vals</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #0000cf; font-weight: bold">2</span><span style="color: #000000; font-weight: bold">]])</span>
 +
            <span style="color: #204a87; font-weight: bold">with</span> <span style="color: #204a87">open</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">csv_out</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;at&quot;</span><span style="color: #000000; font-weight: bold">)</span> <span style="color: #204a87; font-weight: bold">as</span> <span style="color: #000000">csvfile</span><span style="color: #000000; font-weight: bold">:</span>
 +
                <span style="color: #000000">csvwriter</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">csv</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">writer</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">csvfile</span><span style="color: #000000; font-weight: bold">)</span>
 +
                <span style="color: #000000">csvwriter</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">writerow</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">csv_row</span><span style="color: #000000; font-weight: bold">)</span>
 +
            <span style="color: #204a87; font-weight: bold">print</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;wrote csv_row: {}&quot;</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">format</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">csv_row</span><span style="color: #000000; font-weight: bold">))</span>
 +
 +
        <span style="color: #8f5902; font-style: italic"># read state of the slave-camera</span>
 +
        <span style="color: #000000">other_activated</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #3465a4">False</span>
 +
        <span style="color: #8f5902; font-style: italic"># impossible that both are active!</span>
 +
        <span style="color: #204a87; font-weight: bold">if</span> <span style="color: #204a87; font-weight: bold">not</span> <span style="color: #000000">activated</span><span style="color: #000000; font-weight: bold">:</span>
 +
            <span style="color: #000000">timeout</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">time</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">time</span><span style="color: #000000; font-weight: bold">()</span> <span style="color: #ce5c00; font-weight: bold">+</span> <span style="color: #0000cf; font-weight: bold">2</span>  <span style="color: #8f5902; font-style: italic"># seconds</span>
 +
            <span style="color: #204a87; font-weight: bold">while</span> <span style="color: #204a87; font-weight: bold">not</span> <span style="color: #000000">other_activated</span> <span style="color: #204a87; font-weight: bold">and</span> <span style="color: #000000">time</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">time</span><span style="color: #000000; font-weight: bold">()</span> <span style="color: #ce5c00; font-weight: bold">&lt;</span> <span style="color: #000000">timeout</span><span style="color: #000000; font-weight: bold">:</span>
 +
                <span style="color: #000000">other_activated</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">rx</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">is_active</span>
 +
        <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">tx</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">off</span><span style="color: #000000; font-weight: bold">()</span>
 +
 +
        <span style="color: #8f5902; font-style: italic"># determine final state</span>
 +
        <span style="color: #204a87; font-weight: bold">if</span> <span style="color: #000000">activated</span><span style="color: #000000; font-weight: bold">:</span>
 +
            <span style="color: #000000">output</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #0000cf; font-weight: bold">1</span>
 +
        <span style="color: #204a87; font-weight: bold">elif</span> <span style="color: #000000">other_activated</span><span style="color: #000000; font-weight: bold">:</span>
 +
            <span style="color: #000000">output</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #ce5c00; font-weight: bold">-</span><span style="color: #0000cf; font-weight: bold">1</span>
 +
        <span style="color: #204a87; font-weight: bold">else</span><span style="color: #000000; font-weight: bold">:</span>
 +
            <span style="color: #000000">output</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #0000cf; font-weight: bold">0</span>
 +
 +
        <span style="color: #204a87; font-weight: bold">return</span> <span style="color: #000000">output</span>
 +
 +
    <span style="color: #204a87; font-weight: bold">def</span> <span style="color: #000000">exit_clean</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #3465a4">self</span><span style="color: #000000; font-weight: bold">):</span>
 +
        <span style="color: #204a87; font-weight: bold">if</span> <span style="color: #204a87; font-weight: bold">not</span> <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span> <span style="color: #ce5c00; font-weight: bold">==</span> <span style="color: #4e9a06">&quot;&quot;</span><span style="color: #000000; font-weight: bold">:</span>
 +
            <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">close</span><span style="color: #000000; font-weight: bold">()</span>
 +
 +
 +
<span style="color: #204a87; font-weight: bold">def</span> <span style="color: #000000">main</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">args</span><span style="color: #000000; font-weight: bold">):</span>
 +
    <span style="color: #204a87; font-weight: bold">global</span> <span style="color: #000000">CSV_NAME</span>
 +
    <span style="color: #204a87; font-weight: bold">global</span> <span style="color: #000000">CSV_HEADER</span>
 +
 +
    <span style="color: #8f5902; font-style: italic"># t0 = time.time()</span>
 +
    <span style="color: #000000">cam</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">ColiCam</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">mode</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #000000">args</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">mode</span><span style="color: #000000; font-weight: bold">)</span>
 +
    <span style="color: #8f5902; font-style: italic"># t_cam = time.time() - t0</span>
 +
 +
    <span style="color: #8f5902; font-style: italic"># select mode (camera settings)</span>
 +
    <span style="color: #000000">current_mode</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">args</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">mode</span>
 +
 +
    <span style="color: #8f5902; font-style: italic"># optionally create output directory for debugging</span>
 +
    <span style="color: #204a87; font-weight: bold">if</span> <span style="color: #000000">args</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">debug</span><span style="color: #000000; font-weight: bold">:</span>
 +
        <span style="color: #8f5902; font-style: italic"># setup output directory (and copy over the code?)</span>
 +
        <span style="color: #000000">dir_out</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #4e9a06">&quot;/home/pi/ColiCam_{}&quot;</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">format</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">now_str</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;%y%m%d&quot;</span><span style="color: #000000; font-weight: bold">))</span>
 +
        <span style="color: #000000">dir_out</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">safename</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">dir_out</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;dir&quot;</span><span style="color: #000000; font-weight: bold">)</span>
 +
        <span style="color: #204a87; font-weight: bold">if</span> <span style="color: #204a87; font-weight: bold">not</span> <span style="color: #000000">os</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">path</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">isdir</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">dir_out</span><span style="color: #000000; font-weight: bold">):</span>
 +
            <span style="color: #000000">os</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">mkdir</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">dir_out</span><span style="color: #000000; font-weight: bold">)</span>
 +
        <span style="color: #204a87; font-weight: bold">print</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;outputting to &#39;{}&#39;&quot;</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">format</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">dir_out</span><span style="color: #000000; font-weight: bold">))</span>
 +
        <span style="color: #8f5902; font-style: italic"># initialize csv-log</span>
 +
        <span style="color: #000000">csv_fn</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #4e9a06">&quot;{}{}{}.csv&quot;</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">format</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">CSV_NAME</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">args</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">postfix</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">now_str</span><span style="color: #000000; font-weight: bold">())</span>
 +
        <span style="color: #000000">csv_out</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">safename</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">os</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">path</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">join</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">dir_out</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">csv_fn</span><span style="color: #000000; font-weight: bold">),</span> <span style="color: #4e9a06">&#39;file&#39;</span><span style="color: #000000; font-weight: bold">)</span>
 +
        <span style="color: #8f5902; font-style: italic"># write header</span>
 +
        <span style="color: #204a87; font-weight: bold">with</span> <span style="color: #204a87">open</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">csv_out</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;wt&quot;</span><span style="color: #000000; font-weight: bold">)</span> <span style="color: #204a87; font-weight: bold">as</span> <span style="color: #000000">csvfile</span><span style="color: #000000; font-weight: bold">:</span>
 +
            <span style="color: #000000">csvwriter</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">csv</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">writer</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">csvfile</span><span style="color: #000000; font-weight: bold">)</span>
 +
            <span style="color: #000000">csvwriter</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">writerow</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">CSV_HEADER</span><span style="color: #000000; font-weight: bold">)</span>
 +
        <span style="color: #204a87; font-weight: bold">print</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;initialized {} with header {}&quot;</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">format</span><span style="color: #000000; font-weight: bold">(</span>
 +
                <span style="color: #000000">csv_out</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">CSV_HEADER</span><span style="color: #000000; font-weight: bold">))</span>
 +
    <span style="color: #204a87; font-weight: bold">else</span><span style="color: #000000; font-weight: bold">:</span>
 +
        <span style="color: #000000">dir_out</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #3465a4">None</span>
 +
        <span style="color: #000000">csv_out</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #3465a4">None</span>
 +
 +
    <span style="color: #8f5902; font-style: italic"># it = 0</span>
 +
    <span style="color: #204a87; font-weight: bold">try</span><span style="color: #000000; font-weight: bold">:</span>
 +
        <span style="color: #204a87; font-weight: bold">while</span> <span style="color: #3465a4">True</span><span style="color: #000000; font-weight: bold">:</span>
 +
            <span style="color: #8f5902; font-style: italic"># it += 1</span>
 +
 +
            <span style="color: #8f5902; font-style: italic"># update mode</span>
 +
            <span style="color: #000000">new_mode</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">args</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">mode</span>
 +
            <span style="color: #204a87; font-weight: bold">if</span> <span style="color: #204a87; font-weight: bold">not</span> <span style="color: #000000">current_mode</span> <span style="color: #ce5c00; font-weight: bold">==</span> <span style="color: #000000">new_mode</span><span style="color: #000000; font-weight: bold">:</span>
 +
                <span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">set_cam</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">mode</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #000000">new_mode</span><span style="color: #000000; font-weight: bold">)</span>
 +
            <span style="color: #8f5902; font-style: italic"># cam.set_cam(mode=args.mode)</span>
 +
            <span style="color: #204a87; font-weight: bold">print</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;measuring in {} mode (default):&quot;</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">format</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">args</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">mode</span><span style="color: #000000; font-weight: bold">))</span>
 +
 +
            <span style="color: #8f5902; font-style: italic"># measure with both cams</span>
 +
            <span style="color: #000000">val</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">measure</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">dir_out</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #000000">dir_out</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">csv_out</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #000000">csv_out</span><span style="color: #000000; font-weight: bold">,</span>
 +
                              <span style="color: #000000">postfix</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #000000">args</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">postfix</span><span style="color: #000000; font-weight: bold">)</span>
 +
            <span style="color: #204a87; font-weight: bold">if</span> <span style="color: #000000">val</span> <span style="color: #ce5c00; font-weight: bold">==</span> <span style="color: #ce5c00; font-weight: bold">-</span><span style="color: #0000cf; font-weight: bold">1</span><span style="color: #000000; font-weight: bold">:</span>
 +
                <span style="color: #204a87; font-weight: bold">print</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;wall on the left\n&quot;</span><span style="color: #000000; font-weight: bold">)</span>
 +
            <span style="color: #204a87; font-weight: bold">elif</span> <span style="color: #000000">val</span> <span style="color: #ce5c00; font-weight: bold">==</span> <span style="color: #0000cf; font-weight: bold">0</span><span style="color: #000000; font-weight: bold">:</span>
 +
                <span style="color: #204a87; font-weight: bold">print</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;no wall detected\n&quot;</span><span style="color: #000000; font-weight: bold">)</span>
 +
            <span style="color: #204a87; font-weight: bold">elif</span> <span style="color: #000000">val</span> <span style="color: #ce5c00; font-weight: bold">==</span> <span style="color: #0000cf; font-weight: bold">1</span><span style="color: #000000; font-weight: bold">:</span>
 +
                <span style="color: #204a87; font-weight: bold">print</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;wall on the right\n&quot;</span><span style="color: #000000; font-weight: bold">)</span>
 +
 +
    <span style="color: #204a87; font-weight: bold">except</span> <span style="color: #cc0000; font-weight: bold">KeyboardInterrupt</span><span style="color: #000000; font-weight: bold">:</span>
 +
        <span style="color: #204a87; font-weight: bold">print</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;manually interrupted program&quot;</span><span style="color: #000000; font-weight: bold">)</span>
 +
 +
    <span style="color: #204a87; font-weight: bold">finally</span><span style="color: #000000; font-weight: bold">:</span>
 +
        <span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">exit_clean</span><span style="color: #000000; font-weight: bold">()</span>
 +
        <span style="color: #204a87; font-weight: bold">print</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;camera closed, done!&quot;</span><span style="color: #000000; font-weight: bold">)</span>
 +
 +
 +
<span style="color: #204a87; font-weight: bold">if</span> <span style="color: #000000">__name__</span> <span style="color: #ce5c00; font-weight: bold">==</span> <span style="color: #4e9a06">&quot;__main__&quot;</span><span style="color: #000000; font-weight: bold">:</span>
 +
    <span style="color: #000000">main</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">args</span><span style="color: #000000; font-weight: bold">)</span>
 +
</pre></div>
 +
 +
 +
 +
<br>
 +
Camera Slave:
 +
<br>
 +
 +
 +
 +
 +
<!-- HTML generated using hilite.me --><div style="background: #f8f8f8; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"><pre style="margin: 0; line-height: 125%"><span style="color: #8f5902; font-style: italic">#!/usr/bin/env python</span>
 +
<span style="color: #8f5902; font-style: italic">&quot;&quot;&quot;</span>
 +
<span style="color: #8f5902; font-style: italic">Code for the slave-camera</span>
 +
 +
<span style="color: #8f5902; font-style: italic">It is connected to the master-camera via 2 GPIO pins</span>
 +
<span style="color: #8f5902; font-style: italic">and outputs the detected bacterial state via the</span>
 +
<span style="color: #8f5902; font-style: italic">GPIO-connection to the master-camera.</span>
 +
 +
<span style="color: #8f5902; font-style: italic">In order to constantly listen for commands from the</span>
 +
<span style="color: #8f5902; font-style: italic">master camera, it needs to start a background-</span>
 +
<span style="color: #8f5902; font-style: italic">thread.</span>
 +
 +
<span style="color: #8f5902; font-style: italic">@author: Daniel Hofstadler, 2017</span>
 +
<span style="color: #8f5902; font-style: italic">&quot;&quot;&quot;</span>
 +
<span style="color: #204a87; font-weight: bold">import</span> <span style="color: #000000">os</span>
 +
<span style="color: #204a87; font-weight: bold">import</span> <span style="color: #000000">csv</span>
 +
<span style="color: #204a87; font-weight: bold">import</span> <span style="color: #000000">time</span>
 +
<span style="color: #204a87; font-weight: bold">import</span> <span style="color: #000000">argparse</span>
 +
<span style="color: #204a87; font-weight: bold">import</span> <span style="color: #000000">gpiozero</span>
 +
<span style="color: #204a87; font-weight: bold">import</span> <span style="color: #000000">threading</span>
 +
<span style="color: #204a87; font-weight: bold">from</span> <span style="color: #000000">datetime</span> <span style="color: #204a87; font-weight: bold">import</span> <span style="color: #000000">datetime</span>
 +
<span style="color: #204a87; font-weight: bold">from</span> <span style="color: #000000">fractions</span> <span style="color: #204a87; font-weight: bold">import</span> <span style="color: #000000">Fraction</span>
 +
 +
<span style="color: #204a87; font-weight: bold">import</span> <span style="color: #000000">numpy</span> <span style="color: #204a87; font-weight: bold">as</span> <span style="color: #000000">np</span>
 +
<span style="color: #204a87; font-weight: bold">import</span> <span style="color: #000000">picamera</span>
 +
<span style="color: #204a87; font-weight: bold">import</span> <span style="color: #000000">picamera.array</span>
 +
 +
<span style="color: #204a87; font-weight: bold">from</span> <span style="color: #000000">matplotlib</span> <span style="color: #204a87; font-weight: bold">import</span> <span style="color: #000000">pyplot</span> <span style="color: #204a87; font-weight: bold">as</span> <span style="color: #000000">plt</span>
 +
 +
<span style="color: #8f5902; font-style: italic"># import warnings</span>
 +
<span style="color: #8f5902; font-style: italic"># warnings.filterwarnings(&#39;error&#39;, category=DeprecationWarning)</span>
 +
 +
<span style="color: #8f5902; font-style: italic"># globals</span>
 +
<span style="color: #8f5902; font-style: italic"># LOCAL_TZ = pytz.timezone(&quot;Etc/UTC&quot;)  # read from cams.csv</span>
 +
<span style="color: #000000">OUT_APPEND</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #4e9a06">&quot;_coli&quot;</span>
 +
<span style="color: #000000">CSV_NAME</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #4e9a06">&quot;colicam&quot;</span>
 +
<span style="color: #000000">CSV_HEADER</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000; font-weight: bold">[</span><span style="color: #4e9a06">&quot;framerate&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;exposure_time_us&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;iso&quot;</span><span style="color: #000000; font-weight: bold">,</span>
 +
              <span style="color: #4e9a06">&quot;g1&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;g2&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;g3&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;g4&quot;</span><span style="color: #000000; font-weight: bold">,</span>
 +
              <span style="color: #4e9a06">&quot;timestamp&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;time_utc&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;tag&quot;</span><span style="color: #000000; font-weight: bold">,</span>
 +
              <span style="color: #4e9a06">&quot;red&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;green&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;blue&quot;</span><span style="color: #000000; font-weight: bold">]</span>
 +
<span style="color: #8f5902; font-style: italic"># RESOLUTION = (2592, 1944)</span>
 +
<span style="color: #000000">RESOLUTION</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000; font-weight: bold">(</span><span style="color: #0000cf; font-weight: bold">1280</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #0000cf; font-weight: bold">720</span><span style="color: #000000; font-weight: bold">)</span>
 +
<span style="color: #8f5902; font-style: italic"># REGION_OF_INTEREST = (0.35, 0.4, 0.5, 0.7)</span>
 +
<span style="color: #000000">ROI</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000; font-weight: bold">[</span><span style="color: #0000cf; font-weight: bold">200</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #0000cf; font-weight: bold">520</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #0000cf; font-weight: bold">480</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #0000cf; font-weight: bold">800</span><span style="color: #000000; font-weight: bold">]</span>  <span style="color: #8f5902; font-style: italic"># Y0, Y1, X0, X1</span>
 +
<span style="color: #000000">DETECTION_THRESHOLD</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #0000cf; font-weight: bold">150</span>
 +
<span style="color: #000000">PIN_RX</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #0000cf; font-weight: bold">17</span>
 +
<span style="color: #000000">PIN_TX</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #0000cf; font-weight: bold">18</span>
 +
 +
<span style="color: #000000">SETTINGS_FIXED</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000; font-weight: bold">{</span>
 +
        <span style="color: #4e9a06">&#39;name&#39;</span><span style="color: #000000; font-weight: bold">:</span> <span style="color: #4e9a06">&quot;fixed&quot;</span><span style="color: #000000; font-weight: bold">,</span>
 +
        <span style="color: #4e9a06">&#39;ss&#39;</span><span style="color: #000000; font-weight: bold">:</span> <span style="color: #0000cf; font-weight: bold">1000000</span><span style="color: #000000; font-weight: bold">,</span>  <span style="color: #8f5902; font-style: italic"># 1000 milliseconds = 1 sec</span>
 +
        <span style="color: #4e9a06">&#39;fps&#39;</span><span style="color: #000000; font-weight: bold">:</span> <span style="color: #000000">Fraction</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #0000cf; font-weight: bold">1</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #0000cf; font-weight: bold">2</span><span style="color: #000000; font-weight: bold">),</span>  <span style="color: #8f5902; font-style: italic"># (1, 2)</span>
 +
        <span style="color: #4e9a06">&#39;iso&#39;</span><span style="color: #000000; font-weight: bold">:</span> <span style="color: #0000cf; font-weight: bold">800</span><span style="color: #000000; font-weight: bold">,</span>  <span style="color: #8f5902; font-style: italic"># 800</span>
 +
        <span style="color: #4e9a06">&#39;g&#39;</span><span style="color: #000000; font-weight: bold">:</span> <span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">Fraction</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #0000cf; font-weight: bold">2</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #0000cf; font-weight: bold">1</span><span style="color: #000000; font-weight: bold">),</span> <span style="color: #000000">Fraction</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #0000cf; font-weight: bold">1</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #0000cf; font-weight: bold">1</span><span style="color: #000000; font-weight: bold">)),</span>
 +
        <span style="color: #8f5902; font-style: italic"># &#39;g&#39;: (Fraction(345, 256), Fraction(167, 128)),</span>
 +
        <span style="color: #4e9a06">&#39;sleep&#39;</span><span style="color: #000000; font-weight: bold">:</span> <span style="color: #0000cf; font-weight: bold">15</span><span style="color: #000000; font-weight: bold">}</span>  <span style="color: #8f5902; font-style: italic"># 10</span>
 +
<span style="color: #000000">SETTINGS_SENSITIVE</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000; font-weight: bold">{</span>
 +
        <span style="color: #4e9a06">&#39;name&#39;</span><span style="color: #000000; font-weight: bold">:</span> <span style="color: #4e9a06">&quot;sensitive&quot;</span><span style="color: #000000; font-weight: bold">,</span>
 +
        <span style="color: #4e9a06">&#39;ss&#39;</span><span style="color: #000000; font-weight: bold">:</span> <span style="color: #0000cf; font-weight: bold">6000000</span><span style="color: #000000; font-weight: bold">,</span>  <span style="color: #8f5902; font-style: italic"># 6 seconds</span>
 +
        <span style="color: #4e9a06">&#39;fps&#39;</span><span style="color: #000000; font-weight: bold">:</span> <span style="color: #000000">Fraction</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #0000cf; font-weight: bold">1</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #0000cf; font-weight: bold">6</span><span style="color: #000000; font-weight: bold">),</span>
 +
        <span style="color: #4e9a06">&#39;iso&#39;</span><span style="color: #000000; font-weight: bold">:</span> <span style="color: #0000cf; font-weight: bold">800</span><span style="color: #000000; font-weight: bold">,</span>
 +
        <span style="color: #4e9a06">&#39;g&#39;</span><span style="color: #000000; font-weight: bold">:</span> <span style="color: #3465a4">None</span><span style="color: #000000; font-weight: bold">,</span>
 +
        <span style="color: #4e9a06">&#39;sleep&#39;</span><span style="color: #000000; font-weight: bold">:</span> <span style="color: #0000cf; font-weight: bold">30</span><span style="color: #000000; font-weight: bold">}</span>
 +
<span style="color: #000000">SETTINGS_AUTO</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000; font-weight: bold">{</span>
 +
        <span style="color: #4e9a06">&#39;name&#39;</span><span style="color: #000000; font-weight: bold">:</span> <span style="color: #4e9a06">&quot;auto&quot;</span><span style="color: #000000; font-weight: bold">,</span>
 +
        <span style="color: #4e9a06">&#39;ss&#39;</span><span style="color: #000000; font-weight: bold">:</span> <span style="color: #3465a4">None</span><span style="color: #000000; font-weight: bold">,</span>
 +
        <span style="color: #4e9a06">&#39;fps&#39;</span><span style="color: #000000; font-weight: bold">:</span> <span style="color: #0000cf; font-weight: bold">30</span><span style="color: #000000; font-weight: bold">,</span>
 +
        <span style="color: #4e9a06">&#39;iso&#39;</span><span style="color: #000000; font-weight: bold">:</span> <span style="color: #0000cf; font-weight: bold">0</span><span style="color: #000000; font-weight: bold">,</span>
 +
        <span style="color: #4e9a06">&#39;g&#39;</span><span style="color: #000000; font-weight: bold">:</span> <span style="color: #3465a4">None</span><span style="color: #000000; font-weight: bold">,</span>
 +
        <span style="color: #4e9a06">&#39;sleep&#39;</span><span style="color: #000000; font-weight: bold">:</span> <span style="color: #0000cf; font-weight: bold">2</span><span style="color: #000000; font-weight: bold">}</span>
 +
 +
<span style="color: #000000">SETTINGS_DEFAULT</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #4e9a06">&quot;fixed&quot;</span>
 +
 +
<span style="color: #8f5902; font-style: italic"># argument parsing</span>
 +
<span style="color: #000000">parser</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">argparse</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">ArgumentParser</span><span style="color: #000000; font-weight: bold">(</span>
 +
        <span style="color: #000000">description</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #4e9a06">&quot;Colibot Photometer Camera.&quot;</span><span style="color: #000000; font-weight: bold">)</span>
 +
<span style="color: #000000">parser</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">add_argument</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;-d&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;--debug&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">action</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #4e9a06">&quot;store_true&quot;</span><span style="color: #000000; font-weight: bold">,</span>
 +
                    <span style="color: #000000">help</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #4e9a06">&quot;debug mode&quot;</span><span style="color: #000000; font-weight: bold">)</span>
 +
<span style="color: #000000">parser</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">add_argument</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;-m&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;--mode&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #204a87">type</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #204a87">str</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">default</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #4e9a06">&quot;fixed&quot;</span><span style="color: #000000; font-weight: bold">,</span>
 +
                    <span style="color: #000000">choices</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #4e9a06">&quot;f&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;fixed&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;s&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;sensitive&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;a&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;auto&quot;</span><span style="color: #000000; font-weight: bold">],</span>
 +
                    <span style="color: #000000">help</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #4e9a06">&quot;set the camera mode&quot;</span><span style="color: #000000; font-weight: bold">)</span>
 +
<span style="color: #000000">parser</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">add_argument</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;-p&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;--postfix&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #204a87">type</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #204a87">str</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">default</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #4e9a06">&quot;&quot;</span><span style="color: #000000; font-weight: bold">,</span>
 +
                    <span style="color: #000000">help</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #4e9a06">&quot;add string to filename&quot;</span><span style="color: #000000; font-weight: bold">)</span>
 +
<span style="color: #8f5902; font-style: italic"># args = vars(ap.parse_args())</span>
 +
<span style="color: #000000">args</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">parser</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">parse_args</span><span style="color: #000000; font-weight: bold">()</span>
 +
<span style="color: #204a87; font-weight: bold">if</span> <span style="color: #204a87; font-weight: bold">not</span> <span style="color: #000000">args</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">postfix</span> <span style="color: #ce5c00; font-weight: bold">==</span> <span style="color: #4e9a06">&quot;&quot;</span> <span style="color: #204a87; font-weight: bold">and</span> <span style="color: #204a87; font-weight: bold">not</span> <span style="color: #000000">args</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">postfix</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">startswith</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;_&quot;</span><span style="color: #000000; font-weight: bold">):</span>
 +
    <span style="color: #000000">args</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">postfix</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #4e9a06">&quot;_&quot;</span> <span style="color: #ce5c00; font-weight: bold">+</span> <span style="color: #000000">args</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">postfix</span>
 +
 +
 +
<span style="color: #204a87; font-weight: bold">def</span> <span style="color: #000000">now_str</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">pattern</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #4e9a06">&quot;_%y%m%d-%H%M%S_utc&quot;</span><span style="color: #000000; font-weight: bold">):</span>
 +
    <span style="color: #8f5902; font-style: italic"># return time.strftime(pattern, time.gmtime())</span>
 +
    <span style="color: #204a87; font-weight: bold">return</span> <span style="color: #000000">datetime</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">utcnow</span><span style="color: #000000; font-weight: bold">()</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">strftime</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">pattern</span><span style="color: #000000; font-weight: bold">)</span>
 +
 +
 +
<span style="color: #204a87; font-weight: bold">def</span> <span style="color: #000000">from_timestamp</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">ts</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">pattern</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #4e9a06">&quot;%y%m%d-%H%M%S_utc&quot;</span><span style="color: #000000; font-weight: bold">):</span>
 +
    <span style="color: #204a87; font-weight: bold">return</span> <span style="color: #000000">datetime</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">utcfromtimestamp</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">ts</span><span style="color: #000000; font-weight: bold">)</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">strftime</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">pattern</span><span style="color: #000000; font-weight: bold">)</span>
 +
 +
 +
<span style="color: #204a87; font-weight: bold">def</span> <span style="color: #000000">safename</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">s</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">s_type</span><span style="color: #000000; font-weight: bold">):</span>
 +
    <span style="color: #8f5902; font-style: italic">&quot;&quot;&quot;Check whether a given file or folder &#39;s&#39; exists, return a non-existing</span>
 +
<span style="color: #8f5902; font-style: italic">    filename.</span>
 +
<span style="color: #8f5902; font-style: italic">    s ........ (full) filename or directory</span>
 +
<span style="color: #8f5902; font-style: italic">    s_type ... &#39;file&#39; or &#39;f&#39; for files,</span>
 +
<span style="color: #8f5902; font-style: italic">              &#39;directory&#39; or &#39;dir&#39; or &#39;d&#39; for folders</span>
 +
<span style="color: #8f5902; font-style: italic">    Returns a file- or pathname that is supposedly safe to save</span>
 +
<span style="color: #8f5902; font-style: italic">    without overwriting data.</span>
 +
<span style="color: #8f5902; font-style: italic">    &quot;&quot;&quot;</span>
 +
    <span style="color: #000000">low_type</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #204a87">str</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">lower</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">s_type</span><span style="color: #000000; font-weight: bold">)</span>
 +
    <span style="color: #204a87; font-weight: bold">if</span> <span style="color: #000000">low_type</span> <span style="color: #ce5c00; font-weight: bold">==</span> <span style="color: #4e9a06">&#39;file&#39;</span> <span style="color: #204a87; font-weight: bold">or</span> <span style="color: #000000">low_type</span> <span style="color: #ce5c00; font-weight: bold">==</span> <span style="color: #4e9a06">&#39;f&#39;</span><span style="color: #000000; font-weight: bold">:</span>
 +
        <span style="color: #204a87; font-weight: bold">if</span> <span style="color: #000000">os</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">path</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">isfile</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">s</span><span style="color: #000000; font-weight: bold">):</span>
 +
            <span style="color: #000000">s2</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">s</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">split</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&#39;.&#39;</span><span style="color: #000000; font-weight: bold">)</span>
 +
            <span style="color: #000000">s_base</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">s2</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #0000cf; font-weight: bold">0</span><span style="color: #000000; font-weight: bold">]</span>
 +
            <span style="color: #000000">s_ext</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">s2</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #ce5c00; font-weight: bold">-</span><span style="color: #0000cf; font-weight: bold">1</span><span style="color: #000000; font-weight: bold">]</span>
 +
 +
            <span style="color: #000000">counter</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #0000cf; font-weight: bold">0</span>
 +
            <span style="color: #204a87; font-weight: bold">while</span> <span style="color: #000000">os</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">path</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">isfile</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">s</span><span style="color: #000000; font-weight: bold">):</span>
 +
                <span style="color: #000000">s</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">s_base</span> <span style="color: #ce5c00; font-weight: bold">+</span> <span style="color: #4e9a06">&quot;-{:02d}.&quot;</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">format</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">counter</span><span style="color: #000000; font-weight: bold">)</span> <span style="color: #ce5c00; font-weight: bold">+</span> <span style="color: #000000">s_ext</span>
 +
                <span style="color: #000000">counter</span> <span style="color: #ce5c00; font-weight: bold">+=</span> <span style="color: #0000cf; font-weight: bold">1</span>
 +
 +
    <span style="color: #204a87; font-weight: bold">elif</span> <span style="color: #000000">low_type</span> <span style="color: #ce5c00; font-weight: bold">==</span> <span style="color: #4e9a06">&#39;directory&#39;</span> <span style="color: #204a87; font-weight: bold">or</span> <span style="color: #000000">low_type</span> <span style="color: #ce5c00; font-weight: bold">==</span> <span style="color: #4e9a06">&#39;dir&#39;</span> <span style="color: #204a87; font-weight: bold">or</span> <span style="color: #000000">low_type</span> <span style="color: #ce5c00; font-weight: bold">==</span> <span style="color: #4e9a06">&#39;d&#39;</span><span style="color: #000000; font-weight: bold">:</span>
 +
        <span style="color: #204a87; font-weight: bold">if</span> <span style="color: #000000">os</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">path</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">isdir</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">s</span><span style="color: #000000; font-weight: bold">):</span>
 +
            <span style="color: #000000">s_base</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">s</span>
 +
 +
            <span style="color: #000000">counter</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #0000cf; font-weight: bold">0</span>
 +
            <span style="color: #204a87; font-weight: bold">while</span> <span style="color: #000000">os</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">path</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">isdir</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">s</span><span style="color: #000000; font-weight: bold">):</span>
 +
                <span style="color: #000000">s</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">s_base</span> <span style="color: #ce5c00; font-weight: bold">+</span> <span style="color: #4e9a06">&quot;-{:02d}&quot;</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">format</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">counter</span><span style="color: #000000; font-weight: bold">)</span>
 +
                <span style="color: #000000">counter</span> <span style="color: #ce5c00; font-weight: bold">+=</span> <span style="color: #0000cf; font-weight: bold">1</span>
 +
    <span style="color: #204a87; font-weight: bold">return</span> <span style="color: #000000">s</span>
 +
 +
 +
<span style="color: #204a87; font-weight: bold">def</span> <span style="color: #000000">thread_listener</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">cam</span><span style="color: #000000; font-weight: bold">):</span>
 +
    <span style="color: #8f5902; font-style: italic">&quot;&quot;&quot;Background thread listening on the receive-pin</span>
 +
<span style="color: #8f5902; font-style: italic">    whether to make a measurement.&quot;&quot;&quot;</span>
 +
    <span style="color: #204a87; font-weight: bold">try</span><span style="color: #000000; font-weight: bold">:</span>
 +
        <span style="color: #204a87; font-weight: bold">while</span> <span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">active</span><span style="color: #000000; font-weight: bold">:</span>
 +
            <span style="color: #204a87; font-weight: bold">if</span> <span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">rx</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">is_active</span><span style="color: #000000; font-weight: bold">:</span>
 +
                <span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">measure_slave</span><span style="color: #000000; font-weight: bold">()</span>
 +
            <span style="color: #000000">time</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">sleep</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #0000cf; font-weight: bold">0.5</span><span style="color: #000000; font-weight: bold">)</span>
 +
    <span style="color: #204a87; font-weight: bold">finally</span><span style="color: #000000; font-weight: bold">:</span>
 +
        <span style="color: #204a87; font-weight: bold">print</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;listener thread shutting down&quot;</span><span style="color: #000000; font-weight: bold">)</span>
 +
 +
 +
<span style="color: #204a87; font-weight: bold">class</span> <span style="color: #000000">ColiCamSlave</span><span style="color: #000000; font-weight: bold">:</span>
 +
    <span style="color: #204a87; font-weight: bold">global</span> <span style="color: #000000">RESOLUTION</span>
 +
    <span style="color: #204a87; font-weight: bold">global</span> <span style="color: #000000">ROI</span>  <span style="color: #8f5902; font-style: italic"># REGION_OF_INTEREST</span>
 +
    <span style="color: #204a87; font-weight: bold">global</span> <span style="color: #000000">DETECTION_THRESHOLD</span>
 +
    <span style="color: #204a87; font-weight: bold">global</span> <span style="color: #000000">SETTINGS_FIXED</span>
 +
    <span style="color: #204a87; font-weight: bold">global</span> <span style="color: #000000">SETTINGS_SENSITIVE</span>
 +
    <span style="color: #204a87; font-weight: bold">global</span> <span style="color: #000000">SETTINGS_AUTO</span>
 +
    <span style="color: #204a87; font-weight: bold">global</span> <span style="color: #000000">DEF_SETTINGS_NAME</span>
 +
    <span style="color: #204a87; font-weight: bold">global</span> <span style="color: #000000">PIN_RX</span>
 +
    <span style="color: #204a87; font-weight: bold">global</span> <span style="color: #000000">PIN_TX</span>
 +
 +
    <span style="color: #204a87; font-weight: bold">def</span> <span style="color: #000000">__init__</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #3465a4">self</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">resolution</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #000000">RESOLUTION</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">mode</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #000000">DEF_SETTINGS_NAME</span><span style="color: #000000; font-weight: bold">):</span>
 +
        <span style="color: #204a87; font-weight: bold">try</span><span style="color: #000000; font-weight: bold">:</span>
 +
            <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">picamera</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">PiCamera</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">resolution</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #000000">resolution</span><span style="color: #000000; font-weight: bold">)</span>
 +
            <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">set_cam</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">mode</span><span style="color: #000000; font-weight: bold">)</span>
 +
        <span style="color: #204a87; font-weight: bold">except</span> <span style="color: #cc0000; font-weight: bold">Exception</span> <span style="color: #204a87; font-weight: bold">as</span> <span style="color: #000000">err</span><span style="color: #000000; font-weight: bold">:</span>
 +
            <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #4e9a06">&quot;&quot;</span>
 +
            <span style="color: #204a87; font-weight: bold">print</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;couldn&#39;t initialize camera, error: {}&quot;</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">format</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">err</span><span style="color: #000000; font-weight: bold">))</span>
 +
        <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">rx</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">gpiozero</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">InputDevice</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">PIN_RX</span><span style="color: #000000; font-weight: bold">)</span>
 +
        <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">tx</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">gpiozero</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">OutputDevice</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">PIN_TX</span><span style="color: #000000; font-weight: bold">)</span>
 +
        <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">active</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #3465a4">True</span>
 +
 +
        <span style="color: #8f5902; font-style: italic"># start the listening thread</span>
 +
        <span style="color: #000000">listener</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">threading</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">Thread</span><span style="color: #000000; font-weight: bold">(</span>
 +
                <span style="color: #000000">target</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #000000">thread_listener</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">args</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #3465a4">self</span><span style="color: #000000; font-weight: bold">))</span>
 +
        <span style="color: #000000">listener</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">daemon</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #3465a4">True</span>
 +
        <span style="color: #000000">listener</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">start</span><span style="color: #000000; font-weight: bold">()</span>
 +
        <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">listener</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">listener</span>
 +
 +
    <span style="color: #204a87; font-weight: bold">def</span> <span style="color: #000000">set_cam</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #3465a4">self</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">mode</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #4e9a06">&quot;fixed&quot;</span><span style="color: #000000; font-weight: bold">):</span>
 +
 +
        <span style="color: #204a87; font-weight: bold">if</span> <span style="color: #000000">mode</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">lower</span><span style="color: #000000; font-weight: bold">()</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">startswith</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;f&quot;</span><span style="color: #000000; font-weight: bold">):</span>
 +
            <span style="color: #000000">settings</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">SETTINGS_FIXED</span>
 +
        <span style="color: #204a87; font-weight: bold">elif</span> <span style="color: #000000">mode</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">lower</span><span style="color: #000000; font-weight: bold">()</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">startswith</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;s&quot;</span><span style="color: #000000; font-weight: bold">):</span>
 +
            <span style="color: #000000">settings</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">SETTINGS_SENSITIVE</span>
 +
        <span style="color: #204a87; font-weight: bold">elif</span> <span style="color: #000000">mode</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">lower</span><span style="color: #000000; font-weight: bold">()</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">startswith</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;a&quot;</span><span style="color: #000000; font-weight: bold">):</span>
 +
            <span style="color: #000000">settings</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">SETTINGS_AUTO</span>
 +
        <span style="color: #204a87; font-weight: bold">else</span><span style="color: #000000; font-weight: bold">:</span>
 +
            <span style="color: #204a87; font-weight: bold">print</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;wrong camera mode&quot;</span><span style="color: #000000; font-weight: bold">)</span>
 +
 +
        <span style="color: #8f5902; font-style: italic"># switch on auto mode</span>
 +
        <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">awb_mode</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #4e9a06">&#39;auto&#39;</span>
 +
        <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">exposure_mode</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #4e9a06">&#39;auto&#39;</span>
 +
 +
        <span style="color: #8f5902; font-style: italic"># settings = dict with fields: name, ss, fps, iso, g, sleep</span>
 +
        <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">framerate</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">settings</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #4e9a06">&#39;fps&#39;</span><span style="color: #000000; font-weight: bold">]</span>
 +
        <span style="color: #204a87; font-weight: bold">if</span> <span style="color: #000000">settings</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #4e9a06">&#39;ss&#39;</span><span style="color: #000000; font-weight: bold">]:</span>
 +
            <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">shutter_speed</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">settings</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #4e9a06">&#39;ss&#39;</span><span style="color: #000000; font-weight: bold">]</span>
 +
        <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">iso</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">settings</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #4e9a06">&#39;iso&#39;</span><span style="color: #000000; font-weight: bold">]</span>
 +
 +
        <span style="color: #8f5902; font-style: italic"># Wait for the automatic gain control to settle</span>
 +
        <span style="color: #000000">time</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">sleep</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">settings</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #4e9a06">&#39;sleep&#39;</span><span style="color: #000000; font-weight: bold">])</span>
 +
 +
        <span style="color: #8f5902; font-style: italic"># Now fix the values</span>
 +
        <span style="color: #204a87; font-weight: bold">if</span> <span style="color: #204a87; font-weight: bold">not</span> <span style="color: #000000">settings</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #4e9a06">&#39;ss&#39;</span><span style="color: #000000; font-weight: bold">]:</span>
 +
            <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">shutter_speed</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">exposure_speed</span>
 +
        <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">exposure_mode</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #4e9a06">&#39;off&#39;</span>
 +
 +
        <span style="color: #204a87; font-weight: bold">if</span> <span style="color: #000000">settings</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #4e9a06">&#39;g&#39;</span><span style="color: #000000; font-weight: bold">]:</span>
 +
            <span style="color: #000000">g</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">settings</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #4e9a06">&#39;g&#39;</span><span style="color: #000000; font-weight: bold">]</span>
 +
        <span style="color: #204a87; font-weight: bold">else</span><span style="color: #000000; font-weight: bold">:</span>
 +
            <span style="color: #000000">g</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">awb_gains</span>
 +
        <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">awb_mode</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #4e9a06">&#39;off&#39;</span>
 +
        <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">awb_gains</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">g</span>
 +
 +
    <span style="color: #204a87; font-weight: bold">def</span> <span style="color: #000000">measure_slave</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #3465a4">self</span><span style="color: #000000; font-weight: bold">,</span>
 +
                      <span style="color: #000000">roi</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #000000">ROI</span><span style="color: #000000; font-weight: bold">,</span>
 +
                      <span style="color: #000000">channel_name</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #4e9a06">&quot;green&quot;</span><span style="color: #000000; font-weight: bold">,</span>
 +
                      <span style="color: #000000">threshold</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #000000">DETECTION_THRESHOLD</span><span style="color: #000000; font-weight: bold">,</span>
 +
                      <span style="color: #000000">dir_out</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #3465a4">None</span><span style="color: #000000; font-weight: bold">,</span>
 +
                      <span style="color: #000000">csv_out</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #3465a4">None</span><span style="color: #000000; font-weight: bold">,</span>
 +
                      <span style="color: #000000">postfix</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #4e9a06">&quot;&quot;</span><span style="color: #000000; font-weight: bold">):</span>
 +
 +
        <span style="color: #8f5902; font-style: italic"># check whether channel is valid</span>
 +
        <span style="color: #204a87; font-weight: bold">if</span> <span style="color: #000000">channel_name</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">lower</span><span style="color: #000000; font-weight: bold">()</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">startswith</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;r&quot;</span><span style="color: #000000; font-weight: bold">):</span>
 +
            <span style="color: #000000">channel</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #0000cf; font-weight: bold">0</span>
 +
            <span style="color: #000000">channel_name</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #4e9a06">&quot;red&quot;</span>
 +
        <span style="color: #204a87; font-weight: bold">elif</span> <span style="color: #000000">channel_name</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">lower</span><span style="color: #000000; font-weight: bold">()</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">startswith</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;g&quot;</span><span style="color: #000000; font-weight: bold">):</span>
 +
            <span style="color: #000000">channel</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #0000cf; font-weight: bold">1</span>
 +
            <span style="color: #000000">channel_name</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #4e9a06">&quot;green&quot;</span>
 +
        <span style="color: #204a87; font-weight: bold">elif</span> <span style="color: #000000">channel_name</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">lower</span><span style="color: #000000; font-weight: bold">()</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">startswith</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;b&quot;</span><span style="color: #000000; font-weight: bold">):</span>
 +
            <span style="color: #000000">channel</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #0000cf; font-weight: bold">2</span>
 +
            <span style="color: #000000">channel_name</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #4e9a06">&quot;blue&quot;</span>
 +
        <span style="color: #204a87; font-weight: bold">else</span><span style="color: #000000; font-weight: bold">:</span>
 +
            <span style="color: #204a87; font-weight: bold">print</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;wrong channel_name: &#39;{}&#39;&quot;</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">format</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">channel_name</span><span style="color: #000000; font-weight: bold">))</span>
 +
 +
        <span style="color: #8f5902; font-style: italic"># get camera settings</span>
 +
        <span style="color: #000000">time</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">sleep</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #0000cf; font-weight: bold">1</span><span style="color: #000000; font-weight: bold">)</span>
 +
        <span style="color: #000000">fps</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #204a87">float</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">framerate</span><span style="color: #000000; font-weight: bold">)</span>
 +
        <span style="color: #000000">ss</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">exposure_speed</span>
 +
        <span style="color: #000000">g</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">awb_gains</span>
 +
        <span style="color: #000000">g1</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">g</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #0000cf; font-weight: bold">0</span><span style="color: #000000; font-weight: bold">]</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">numerator</span>
 +
        <span style="color: #000000">g2</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">g</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #0000cf; font-weight: bold">0</span><span style="color: #000000; font-weight: bold">]</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">denominator</span>
 +
        <span style="color: #000000">g3</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">g</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #0000cf; font-weight: bold">1</span><span style="color: #000000; font-weight: bold">]</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">numerator</span>
 +
        <span style="color: #000000">g4</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">g</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #0000cf; font-weight: bold">1</span><span style="color: #000000; font-weight: bold">]</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">denominator</span>
 +
        <span style="color: #000000">iso</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">iso</span>
 +
        <span style="color: #000000">settings_str</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #4e9a06">&quot;ss{}_g{}-{}_{}-{}_iso{}_&quot;</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">format</span><span style="color: #000000; font-weight: bold">(</span>
 +
                <span style="color: #000000">ss</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">g1</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">g2</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">g3</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">g4</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">iso</span><span style="color: #000000; font-weight: bold">)</span>
 +
        <span style="color: #000000">csv_row</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000; font-weight: bold">[</span><span style="color: #000000">fps</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">ss</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">iso</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">g1</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">g2</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">g3</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">g4</span><span style="color: #000000; font-weight: bold">]</span>
 +
        <span style="color: #204a87; font-weight: bold">print</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;taking photos with settings: {}&quot;</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">format</span><span style="color: #000000; font-weight: bold">(</span>
 +
                <span style="color: #000000">settings_str</span><span style="color: #000000; font-weight: bold">))</span>
 +
 +
        <span style="color: #8f5902; font-style: italic"># with picamera.PiCamera(resolution=RESOLUTION) as cam:</span>
 +
        <span style="color: #8f5902; font-style: italic"># https://picamera.readthedocs.io/en/latest/</span>
 +
        <span style="color: #8f5902; font-style: italic">#        api_array.html#module-picamera.array</span>
 +
        <span style="color: #204a87; font-weight: bold">with</span> <span style="color: #000000">picamera</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">array</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">PiRGBArray</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span><span style="color: #000000; font-weight: bold">)</span> <span style="color: #204a87; font-weight: bold">as</span> <span style="color: #000000">output</span><span style="color: #000000; font-weight: bold">:</span>
 +
 +
            <span style="color: #8f5902; font-style: italic"># cam.zoom = REGION_OF_INTEREST</span>
 +
            <span style="color: #8f5902; font-style: italic"># cam.start_preview()</span>
 +
 +
            <span style="color: #8f5902; font-style: italic"># take picture</span>
 +
            <span style="color: #000000">t0</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">time</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">time</span><span style="color: #000000; font-weight: bold">()</span>
 +
            <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">capture</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">output</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">format</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #4e9a06">&quot;rgb&quot;</span><span style="color: #000000; font-weight: bold">)</span>
 +
            <span style="color: #000000">a</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">output</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">array</span>
 +
            <span style="color: #000000">t1</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">time</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">time</span><span style="color: #000000; font-weight: bold">()</span>
 +
            <span style="color: #204a87; font-weight: bold">print</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;recorded for {} sec&quot;</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">format</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #204a87">round</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">t1</span><span style="color: #ce5c00; font-weight: bold">-</span><span style="color: #000000">t0</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #0000cf; font-weight: bold">2</span><span style="color: #000000; font-weight: bold">)))</span>
 +
            <span style="color: #000000">t_pic</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #204a87">int</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #204a87">round</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">np</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">mean</span><span style="color: #000000; font-weight: bold">([</span><span style="color: #000000">t0</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">t1</span><span style="color: #000000; font-weight: bold">])))</span>
 +
            <span style="color: #8f5902; font-style: italic"># re-empty output (to reuse next iteration)</span>
 +
            <span style="color: #8f5902; font-style: italic"># output.truncate(0)</span>
 +
 +
        <span style="color: #8f5902; font-style: italic"># crop to region of interest</span>
 +
        <span style="color: #000000">roi</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">a</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #000000">ROI</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #0000cf; font-weight: bold">0</span><span style="color: #000000; font-weight: bold">]:</span><span style="color: #000000">ROI</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #0000cf; font-weight: bold">1</span><span style="color: #000000; font-weight: bold">],</span> <span style="color: #000000">ROI</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #0000cf; font-weight: bold">2</span><span style="color: #000000; font-weight: bold">]:</span><span style="color: #000000">ROI</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #0000cf; font-weight: bold">3</span><span style="color: #000000; font-weight: bold">],</span> <span style="color: #000000; font-weight: bold">:]</span>
 +
 +
        <span style="color: #000000">vals</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000; font-weight: bold">[]</span>
 +
        <span style="color: #000000">vals</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">append</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">np</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">median</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">roi</span><span style="color: #000000; font-weight: bold">[:,</span> <span style="color: #000000; font-weight: bold">:,</span> <span style="color: #0000cf; font-weight: bold">0</span><span style="color: #000000; font-weight: bold">]))</span>
 +
        <span style="color: #000000">vals</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">append</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">np</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">median</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">roi</span><span style="color: #000000; font-weight: bold">[:,</span> <span style="color: #000000; font-weight: bold">:,</span> <span style="color: #0000cf; font-weight: bold">1</span><span style="color: #000000; font-weight: bold">]))</span>
 +
        <span style="color: #000000">vals</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">append</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">np</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">median</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">roi</span><span style="color: #000000; font-weight: bold">[:,</span> <span style="color: #000000; font-weight: bold">:,</span> <span style="color: #0000cf; font-weight: bold">2</span><span style="color: #000000; font-weight: bold">]))</span>
 +
 +
        <span style="color: #204a87; font-weight: bold">print</span><span style="color: #000000; font-weight: bold">((</span><span style="color: #4e9a06">&quot;roi.shape={},\n&quot;</span> <span style="color: #ce5c00; font-weight: bold">+</span>
 +
              <span style="color: #8f5902; font-style: italic"># &quot;sum(red)={}, sum(green)={}, sum(blue)={},\n&quot; +</span>
 +
              <span style="color: #4e9a06">&quot;med(red)={}, med(green)={}, med(blue)={}&quot;</span><span style="color: #000000; font-weight: bold">)</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">format</span><span style="color: #000000; font-weight: bold">(</span>
 +
                      <span style="color: #000000">roi</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">shape</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">vals</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #0000cf; font-weight: bold">0</span><span style="color: #000000; font-weight: bold">],</span> <span style="color: #000000">vals</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #0000cf; font-weight: bold">1</span><span style="color: #000000; font-weight: bold">],</span> <span style="color: #000000">vals</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #0000cf; font-weight: bold">2</span><span style="color: #000000; font-weight: bold">]))</span>
 +
 +
        <span style="color: #000000">val</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">vals</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #000000">channel</span><span style="color: #000000; font-weight: bold">]</span>
 +
        <span style="color: #204a87; font-weight: bold">print</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;reading the {} channel...\nvalue: {}&quot;</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">format</span><span style="color: #000000; font-weight: bold">(</span>
 +
                <span style="color: #000000">channel_name</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">val</span><span style="color: #000000; font-weight: bold">))</span>
 +
 +
        <span style="color: #8f5902; font-style: italic"># checking whether threshold is crossed and</span>
 +
        <span style="color: #8f5902; font-style: italic">#  signalling the master-camera</span>
 +
        <span style="color: #204a87; font-weight: bold">if</span> <span style="color: #000000">val</span> <span style="color: #ce5c00; font-weight: bold">&gt;=</span> <span style="color: #000000">threshold</span><span style="color: #000000; font-weight: bold">:</span>
 +
            <span style="color: #000000">activated</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #3465a4">True</span>
 +
            <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">tx</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">on</span><span style="color: #000000; font-weight: bold">()</span>
 +
        <span style="color: #204a87; font-weight: bold">else</span><span style="color: #000000; font-weight: bold">:</span>
 +
            <span style="color: #000000">activated</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #3465a4">False</span>
 +
            <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">tx</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">off</span><span style="color: #000000; font-weight: bold">()</span>
 +
        <span style="color: #204a87; font-weight: bold">print</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;active={} (threshold: {})&quot;</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">format</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">activated</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">threshold</span><span style="color: #000000; font-weight: bold">))</span>
 +
 +
        <span style="color: #8f5902; font-style: italic"># debug mode:</span>
 +
        <span style="color: #8f5902; font-style: italic"># output images and csv if output directory exists</span>
 +
        <span style="color: #204a87; font-weight: bold">if</span> <span style="color: #000000">dir_out</span><span style="color: #000000; font-weight: bold">:</span>
 +
 +
            <span style="color: #000000">names</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000; font-weight: bold">[</span><span style="color: #4e9a06">&quot;1-red&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;2-green&quot;</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;3-blue&quot;</span><span style="color: #000000; font-weight: bold">]</span>
 +
 +
            <span style="color: #8f5902; font-style: italic"># whole images</span>
 +
            <span style="color: #000000">fn</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #4e9a06">&quot;full_{}{}_0-rgb{}.png&quot;</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">format</span><span style="color: #000000; font-weight: bold">(</span>
 +
                    <span style="color: #000000">settings_str</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">postfix</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">now_str</span><span style="color: #000000; font-weight: bold">())</span>
 +
            <span style="color: #000000">ffn</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">safename</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">os</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">path</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">join</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">dir_out</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">fn</span><span style="color: #000000; font-weight: bold">),</span> <span style="color: #4e9a06">&quot;file&quot;</span><span style="color: #000000; font-weight: bold">)</span>
 +
            <span style="color: #000000">plt</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">imsave</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">ffn</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">a</span><span style="color: #000000; font-weight: bold">)</span>
 +
            <span style="color: #204a87; font-weight: bold">for</span> <span style="color: #000000">i</span> <span style="color: #204a87; font-weight: bold">in</span> <span style="color: #204a87">range</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #0000cf; font-weight: bold">3</span><span style="color: #000000; font-weight: bold">):</span>
 +
                <span style="color: #000000">fn</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #4e9a06">&quot;full_{}{}_{}{}.png&quot;</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">format</span><span style="color: #000000; font-weight: bold">(</span>
 +
                        <span style="color: #000000">settings_str</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">postfix</span><span style="color: #000000; font-weight: bold">,</span>
 +
                        <span style="color: #000000">names</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #000000">i</span><span style="color: #000000; font-weight: bold">],</span> <span style="color: #000000">now_str</span><span style="color: #000000; font-weight: bold">())</span>
 +
                <span style="color: #000000">ffn</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">safename</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">os</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">path</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">join</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">dir_out</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">fn</span><span style="color: #000000; font-weight: bold">),</span> <span style="color: #4e9a06">&quot;file&quot;</span><span style="color: #000000; font-weight: bold">)</span>
 +
                <span style="color: #000000">plt</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">imsave</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">ffn</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">a</span><span style="color: #000000; font-weight: bold">[:,</span> <span style="color: #000000; font-weight: bold">:,</span> <span style="color: #000000">i</span><span style="color: #000000; font-weight: bold">],</span> <span style="color: #000000">vmin</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #0000cf; font-weight: bold">0</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">vmax</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #0000cf; font-weight: bold">255</span><span style="color: #000000; font-weight: bold">)</span>
 +
 +
            <span style="color: #8f5902; font-style: italic"># cropped to ROI</span>
 +
            <span style="color: #000000">fn</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #4e9a06">&quot;roi_{}{}_0-rgb{}.png&quot;</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">format</span><span style="color: #000000; font-weight: bold">(</span>
 +
                    <span style="color: #000000">settings_str</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">postfix</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">now_str</span><span style="color: #000000; font-weight: bold">())</span>
 +
            <span style="color: #000000">ffn</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">safename</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">os</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">path</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">join</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">dir_out</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">fn</span><span style="color: #000000; font-weight: bold">),</span> <span style="color: #4e9a06">&quot;file&quot;</span><span style="color: #000000; font-weight: bold">)</span>
 +
            <span style="color: #000000">plt</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">imsave</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">ffn</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">roi</span><span style="color: #000000; font-weight: bold">)</span>
 +
            <span style="color: #204a87; font-weight: bold">for</span> <span style="color: #000000">i</span> <span style="color: #204a87; font-weight: bold">in</span> <span style="color: #204a87">range</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #0000cf; font-weight: bold">3</span><span style="color: #000000; font-weight: bold">):</span>
 +
                <span style="color: #000000">fn</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #4e9a06">&quot;roi_{}{}_{}{}.png&quot;</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">format</span><span style="color: #000000; font-weight: bold">(</span>
 +
                        <span style="color: #000000">settings_str</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">postfix</span><span style="color: #000000; font-weight: bold">,</span>
 +
                        <span style="color: #000000">names</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #000000">i</span><span style="color: #000000; font-weight: bold">],</span> <span style="color: #000000">now_str</span><span style="color: #000000; font-weight: bold">())</span>
 +
                <span style="color: #000000">ffn</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">safename</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">os</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">path</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">join</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">dir_out</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">fn</span><span style="color: #000000; font-weight: bold">),</span> <span style="color: #4e9a06">&quot;file&quot;</span><span style="color: #000000; font-weight: bold">)</span>
 +
                <span style="color: #000000">plt</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">imsave</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">ffn</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">roi</span><span style="color: #000000; font-weight: bold">[:,</span> <span style="color: #000000; font-weight: bold">:,</span> <span style="color: #000000">i</span><span style="color: #000000; font-weight: bold">],</span> <span style="color: #000000">vmin</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #0000cf; font-weight: bold">0</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">vmax</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #0000cf; font-weight: bold">255</span><span style="color: #000000; font-weight: bold">)</span>
 +
 +
            <span style="color: #000000">csv_row</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">extend</span><span style="color: #000000; font-weight: bold">([</span><span style="color: #000000">t_pic</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">from_timestamp</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">t_pic</span><span style="color: #000000; font-weight: bold">),</span> <span style="color: #000000">postfix</span><span style="color: #000000; font-weight: bold">,</span>
 +
                            <span style="color: #000000">vals</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #0000cf; font-weight: bold">0</span><span style="color: #000000; font-weight: bold">],</span> <span style="color: #000000">vals</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #0000cf; font-weight: bold">1</span><span style="color: #000000; font-weight: bold">],</span> <span style="color: #000000">vals</span><span style="color: #000000; font-weight: bold">[</span><span style="color: #0000cf; font-weight: bold">2</span><span style="color: #000000; font-weight: bold">]])</span>
 +
            <span style="color: #204a87; font-weight: bold">with</span> <span style="color: #204a87">open</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">csv_out</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;at&quot;</span><span style="color: #000000; font-weight: bold">)</span> <span style="color: #204a87; font-weight: bold">as</span> <span style="color: #000000">csvfile</span><span style="color: #000000; font-weight: bold">:</span>
 +
                <span style="color: #000000">csvwriter</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">csv</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">writer</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">csvfile</span><span style="color: #000000; font-weight: bold">)</span>
 +
                <span style="color: #000000">csvwriter</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">writerow</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">csv_row</span><span style="color: #000000; font-weight: bold">)</span>
 +
            <span style="color: #204a87; font-weight: bold">print</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;wrote csv_row: {}&quot;</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">format</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">csv_row</span><span style="color: #000000; font-weight: bold">))</span>
 +
 +
        <span style="color: #204a87; font-weight: bold">return</span> <span style="color: #3465a4">None</span>
 +
 +
    <span style="color: #204a87; font-weight: bold">def</span> <span style="color: #000000">exit_clean</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #3465a4">self</span><span style="color: #000000; font-weight: bold">):</span>
 +
        <span style="color: #204a87; font-weight: bold">if</span> <span style="color: #204a87; font-weight: bold">not</span> <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span> <span style="color: #ce5c00; font-weight: bold">==</span> <span style="color: #4e9a06">&quot;&quot;</span><span style="color: #000000; font-weight: bold">:</span>
 +
            <span style="color: #3465a4">self</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">close</span><span style="color: #000000; font-weight: bold">()</span>
 +
 +
 +
<span style="color: #204a87; font-weight: bold">def</span> <span style="color: #000000">main</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">args</span><span style="color: #000000; font-weight: bold">):</span>
 +
    <span style="color: #204a87; font-weight: bold">global</span> <span style="color: #000000">CSV_NAME</span>
 +
    <span style="color: #204a87; font-weight: bold">global</span> <span style="color: #000000">CSV_HEADER</span>
 +
 +
    <span style="color: #8f5902; font-style: italic"># t0 = time.time()</span>
 +
    <span style="color: #000000">cam</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">ColiCam</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">mode</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #000000">args</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">mode</span><span style="color: #000000; font-weight: bold">)</span>
 +
    <span style="color: #8f5902; font-style: italic"># t_cam = time.time() - t0</span>
 +
 +
    <span style="color: #8f5902; font-style: italic"># select mode (camera settings)</span>
 +
    <span style="color: #000000">current_mode</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">args</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">mode</span>
 +
 +
    <span style="color: #8f5902; font-style: italic"># optionally create output directory for debugging</span>
 +
    <span style="color: #204a87; font-weight: bold">if</span> <span style="color: #000000">args</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">debug</span><span style="color: #000000; font-weight: bold">:</span>
 +
        <span style="color: #8f5902; font-style: italic"># setup output directory (and copy over the code?)</span>
 +
        <span style="color: #000000">dir_out</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #4e9a06">&quot;/home/pi/ColiCam_{}&quot;</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">format</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">now_str</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;%y%m%d&quot;</span><span style="color: #000000; font-weight: bold">))</span>
 +
        <span style="color: #000000">dir_out</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">safename</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">dir_out</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;dir&quot;</span><span style="color: #000000; font-weight: bold">)</span>
 +
        <span style="color: #204a87; font-weight: bold">if</span> <span style="color: #204a87; font-weight: bold">not</span> <span style="color: #000000">os</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">path</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">isdir</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">dir_out</span><span style="color: #000000; font-weight: bold">):</span>
 +
            <span style="color: #000000">os</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">mkdir</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">dir_out</span><span style="color: #000000; font-weight: bold">)</span>
 +
        <span style="color: #204a87; font-weight: bold">print</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;outputting to &#39;{}&#39;&quot;</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">format</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">dir_out</span><span style="color: #000000; font-weight: bold">))</span>
 +
        <span style="color: #8f5902; font-style: italic"># initialize csv-log</span>
 +
        <span style="color: #000000">csv_fn</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #4e9a06">&quot;{}{}{}.csv&quot;</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">format</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">CSV_NAME</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">args</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">postfix</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">now_str</span><span style="color: #000000; font-weight: bold">())</span>
 +
        <span style="color: #000000">csv_out</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">safename</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">os</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">path</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">join</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">dir_out</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">csv_fn</span><span style="color: #000000; font-weight: bold">),</span> <span style="color: #4e9a06">&#39;file&#39;</span><span style="color: #000000; font-weight: bold">)</span>
 +
        <span style="color: #8f5902; font-style: italic"># write header</span>
 +
        <span style="color: #204a87; font-weight: bold">with</span> <span style="color: #204a87">open</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">csv_out</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #4e9a06">&quot;wt&quot;</span><span style="color: #000000; font-weight: bold">)</span> <span style="color: #204a87; font-weight: bold">as</span> <span style="color: #000000">csvfile</span><span style="color: #000000; font-weight: bold">:</span>
 +
            <span style="color: #000000">csvwriter</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">csv</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">writer</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">csvfile</span><span style="color: #000000; font-weight: bold">)</span>
 +
            <span style="color: #000000">csvwriter</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">writerow</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">CSV_HEADER</span><span style="color: #000000; font-weight: bold">)</span>
 +
        <span style="color: #204a87; font-weight: bold">print</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;initialized {} with header {}&quot;</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">format</span><span style="color: #000000; font-weight: bold">(</span>
 +
                <span style="color: #000000">csv_out</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">CSV_HEADER</span><span style="color: #000000; font-weight: bold">))</span>
 +
    <span style="color: #204a87; font-weight: bold">else</span><span style="color: #000000; font-weight: bold">:</span>
 +
        <span style="color: #000000">dir_out</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #3465a4">None</span>
 +
        <span style="color: #000000">csv_out</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #3465a4">None</span>
 +
 +
    <span style="color: #8f5902; font-style: italic"># it = 0</span>
 +
    <span style="color: #204a87; font-weight: bold">try</span><span style="color: #000000; font-weight: bold">:</span>
 +
        <span style="color: #204a87; font-weight: bold">while</span> <span style="color: #3465a4">True</span><span style="color: #000000; font-weight: bold">:</span>
 +
            <span style="color: #8f5902; font-style: italic"># it += 1</span>
 +
 +
            <span style="color: #8f5902; font-style: italic"># update mode</span>
 +
            <span style="color: #000000">new_mode</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">args</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">mode</span>
 +
            <span style="color: #204a87; font-weight: bold">if</span> <span style="color: #204a87; font-weight: bold">not</span> <span style="color: #000000">current_mode</span> <span style="color: #ce5c00; font-weight: bold">==</span> <span style="color: #000000">new_mode</span><span style="color: #000000; font-weight: bold">:</span>
 +
                <span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">set_cam</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">mode</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #000000">new_mode</span><span style="color: #000000; font-weight: bold">)</span>
 +
            <span style="color: #8f5902; font-style: italic"># cam.set_cam(mode=args.mode)</span>
 +
            <span style="color: #204a87; font-weight: bold">print</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;measuring in {} mode (default):&quot;</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">format</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">args</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">mode</span><span style="color: #000000; font-weight: bold">))</span>
 +
 +
            <span style="color: #8f5902; font-style: italic"># measure with both cams</span>
 +
            <span style="color: #000000">val</span> <span style="color: #ce5c00; font-weight: bold">=</span> <span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">measure</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">dir_out</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #000000">dir_out</span><span style="color: #000000; font-weight: bold">,</span> <span style="color: #000000">csv_out</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #000000">csv_out</span><span style="color: #000000; font-weight: bold">,</span>
 +
                              <span style="color: #000000">postfix</span><span style="color: #ce5c00; font-weight: bold">=</span><span style="color: #000000">args</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">postfix</span><span style="color: #000000; font-weight: bold">)</span>
 +
            <span style="color: #204a87; font-weight: bold">if</span> <span style="color: #000000">val</span> <span style="color: #ce5c00; font-weight: bold">==</span> <span style="color: #ce5c00; font-weight: bold">-</span><span style="color: #0000cf; font-weight: bold">1</span><span style="color: #000000; font-weight: bold">:</span>
 +
                <span style="color: #204a87; font-weight: bold">print</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;wall on the left\n&quot;</span><span style="color: #000000; font-weight: bold">)</span>
 +
            <span style="color: #204a87; font-weight: bold">elif</span> <span style="color: #000000">val</span> <span style="color: #ce5c00; font-weight: bold">==</span> <span style="color: #0000cf; font-weight: bold">0</span><span style="color: #000000; font-weight: bold">:</span>
 +
                <span style="color: #204a87; font-weight: bold">print</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;no wall detected\n&quot;</span><span style="color: #000000; font-weight: bold">)</span>
 +
            <span style="color: #204a87; font-weight: bold">elif</span> <span style="color: #000000">val</span> <span style="color: #ce5c00; font-weight: bold">==</span> <span style="color: #0000cf; font-weight: bold">1</span><span style="color: #000000; font-weight: bold">:</span>
 +
                <span style="color: #204a87; font-weight: bold">print</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;wall on the right\n&quot;</span><span style="color: #000000; font-weight: bold">)</span>
 +
 +
    <span style="color: #204a87; font-weight: bold">except</span> <span style="color: #cc0000; font-weight: bold">KeyboardInterrupt</span><span style="color: #000000; font-weight: bold">:</span>
 +
        <span style="color: #204a87; font-weight: bold">print</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;manually interrupted program&quot;</span><span style="color: #000000; font-weight: bold">)</span>
 +
 +
    <span style="color: #204a87; font-weight: bold">finally</span><span style="color: #000000; font-weight: bold">:</span>
 +
        <span style="color: #000000">cam</span><span style="color: #ce5c00; font-weight: bold">.</span><span style="color: #000000">exit_clean</span><span style="color: #000000; font-weight: bold">()</span>
 +
        <span style="color: #204a87; font-weight: bold">print</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #4e9a06">&quot;camera closed, done!&quot;</span><span style="color: #000000; font-weight: bold">)</span>
 +
 +
 +
<span style="color: #204a87; font-weight: bold">if</span> <span style="color: #000000">__name__</span> <span style="color: #ce5c00; font-weight: bold">==</span> <span style="color: #4e9a06">&quot;__main__&quot;</span><span style="color: #000000; font-weight: bold">:</span>
 +
    <span style="color: #000000">main</span><span style="color: #000000; font-weight: bold">(</span><span style="color: #000000">args</span><span style="color: #000000; font-weight: bold">)</span>
 +
</pre></div>
 
         </div>
 
         </div>
 
     </div>
 
     </div>

Revision as of 18:21, 1 November 2017

FLOURESCENCE MEASUREMENT CHAMBER


[fmc parts labelled]
[fmc assembled labelled]
Bacteria are moved into a UV-cuvette inside the measurement chamber of the fluorescence detector. The chamber is a 3D-printed enclosure (see Fig. Xy) with two walls facing each other that house a row of three LED sockets each. In the current setup, we only placed three [XXX UV?] LEDs in one wall. The other two opposing walls host camera sockets, to one one of which we have attached a RPi-camera, that is controlled by the RPi server. Two optical filters are placed inside. A [XXX] filter [do we show their spectral characteristics?] between the UV-LEDs and the cuvette, to filter out wavelengths from [XX] to [XX] nm (peak activation of eGFP at ~ XX nm). Between the cuvette and the camera a [XX] filter is inserted to allow only light emitted from activated bacteria through while holding back the rest of the LED-light.
The camera is controlled via the Python picamera library and calibrated to maximize the difference between idle and activated bacteria @allFromHof: (see table “camera-settings” or Supplemental Stuff, Zenodo, or nowhere?). The raw RGB-data is recorded, the green channel is kept and cropped to our region of interest---the bacterial suspension. The median green intensity of this region is then compared to a threshold [XX] to decipher the bacterial command.

Casing

3D-printed bla..
[messkammer/render_1.png]
[messkammer/render_2.png]
[messkammer/render_3.png]

LEDs and Optical Filters

because of the expressed fluorescent protein’s spectral characteristics [explain shortly and link to molbio parts], we employ [XXX] nm LEDs to excite [XXX/proteins/chromophores?] and filter… images of LED’s emission spectrum and filter’s absorption curves for temperature experiment… ???

Camera

… see “colicam_nu.py” on github/daniel_moser/colibot/server/cam/ … 1 second shutterspeed..

Software

Camera Master:
#!/usr/bin/env python
"""
Code for the master-camera.

It is connected to the slave-camera via 2 GPIO pins
and outputs the total detected bacterial state (aggregated
from both cameras).

@author: Daniel Hofstadler, 2017
"""
import os
import csv
import time
import argparse
import gpiozero
from datetime import datetime
from fractions import Fraction

import numpy as np
import picamera
import picamera.array

from matplotlib import pyplot as plt

# import warnings
# warnings.filterwarnings('error', category=DeprecationWarning)

# globals
# LOCAL_TZ = pytz.timezone("Etc/UTC")  # read from cams.csv
OUT_APPEND = "_coli"
CSV_NAME = "colicam"
CSV_HEADER = ["framerate", "exposure_time_us", "iso",
              "g1", "g2", "g3", "g4",
              "timestamp", "time_utc", "tag",
              "red", "green", "blue"]
# RESOLUTION = (2592, 1944)
RESOLUTION = (1280, 720)
# REGION_OF_INTEREST = (0.35, 0.4, 0.5, 0.7)
ROI = [200, 520, 480, 800]  # Y0, Y1, X0, X1
DETECTION_THRESHOLD = 150
PIN_RX = 17
PIN_TX = 18

SETTINGS_FIXED = {
        'name': "fixed",
        'ss': 1000000,  # 1000 milliseconds = 1 sec
        'fps': Fraction(1, 2),  # (1, 2)
        'iso': 800,  # 800
        'g': (Fraction(2, 1), Fraction(1, 1)),
        # 'g': (Fraction(345, 256), Fraction(167, 128)),
        'sleep': 15}  # 10
SETTINGS_SENSITIVE = {
        'name': "sensitive",
        'ss': 6000000,  # 6 seconds
        'fps': Fraction(1, 6),
        'iso': 800,
        'g': None,
        'sleep': 30}
SETTINGS_AUTO = {
        'name': "auto",
        'ss': None,
        'fps': 30,
        'iso': 0,
        'g': None,
        'sleep': 2}

SETTINGS_DEFAULT = "fixed"

# argument parsing
parser = argparse.ArgumentParser(
        description="Colibot Photometer Camera.")
parser.add_argument("-d", "--debug", action="store_true",
                    help="debug mode")
parser.add_argument("-m", "--mode", type=str, default="fixed",
                    choices=["f", "fixed", "s", "sensitive", "a", "auto"],
                    help="set the camera mode")
parser.add_argument("-p", "--postfix", type=str, default="",
                    help="add string to filename")
# args = vars(ap.parse_args())
args = parser.parse_args()
if not args.postfix == "" and not args.postfix.startswith("_"):
    args.postfix = "_" + args.postfix


def now_str(pattern="_%y%m%d-%H%M%S_utc"):
    # return time.strftime(pattern, time.gmtime())
    return datetime.utcnow().strftime(pattern)


def from_timestamp(ts, pattern="%y%m%d-%H%M%S_utc"):
    return datetime.utcfromtimestamp(ts).strftime(pattern)


def safename(s, s_type):
    """Check whether a given file or folder 's' exists, return a non-existing
    filename.
    s ........ (full) filename or directory
    s_type ... 'file' or 'f' for files,
               'directory' or 'dir' or 'd' for folders
    Returns a file- or pathname that is supposedly safe to save
    without overwriting data.
    """
    low_type = str.lower(s_type)
    if low_type == 'file' or low_type == 'f':
        if os.path.isfile(s):
            s2 = s.split('.')
            s_base = s2[0]
            s_ext = s2[-1]

            counter = 0
            while os.path.isfile(s):
                s = s_base + "-{:02d}.".format(counter) + s_ext
                counter += 1

    elif low_type == 'directory' or low_type == 'dir' or low_type == 'd':
        if os.path.isdir(s):
            s_base = s

            counter = 0
            while os.path.isdir(s):
                s = s_base + "-{:02d}".format(counter)
                counter += 1
    return s


class ColiCamMaster:
    global RESOLUTION
    global ROI  # REGION_OF_INTEREST
    global DETECTION_THRESHOLD
    global SETTINGS_FIXED
    global SETTINGS_SENSITIVE
    global SETTINGS_AUTO
    global DEF_SETTINGS_NAME
    global PIN_RX
    global PIN_TX

    def __init__(self, resolution=RESOLUTION, mode=DEF_SETTINGS_NAME):
        try:
            self.cam = picamera.PiCamera(resolution=resolution)
            self.set_cam(mode)
        except Exception as err:
            self.cam = ""
            print("couldn't initialize camera, error: {}".format(err))
        self.rx = gpiozero.InputDevice(PIN_RX)
        self.tx = gpiozero.OutputDevice(PIN_TX)

    def set_cam(self, mode="fixed"):

        if mode.lower().startswith("f"):
            settings = SETTINGS_FIXED
        elif mode.lower().startswith("s"):
            settings = SETTINGS_SENSITIVE
        elif mode.lower().startswith("a"):
            settings = SETTINGS_AUTO
        else:
            print("wrong camera mode")

        # switch on auto mode
        self.cam.awb_mode = 'auto'
        self.cam.exposure_mode = 'auto'

        # settings = dict with fields: name, ss, fps, iso, g, sleep
        self.cam.framerate = settings['fps']
        if settings['ss']:
            self.cam.shutter_speed = settings['ss']
        self.cam.iso = settings['iso']

        # Wait for the automatic gain control to settle
        time.sleep(settings['sleep'])

        # Now fix the values
        if not settings['ss']:
            self.cam.shutter_speed = self.cam.exposure_speed
        self.cam.exposure_mode = 'off'

        if settings['g']:
            g = settings['g']
        else:
            g = self.cam.awb_gains
        self.cam.awb_mode = 'off'
        self.cam.awb_gains = g

    def measure(self,
                roi=ROI,
                channel_name="green",
                threshold=DETECTION_THRESHOLD,
                dir_out=None,
                csv_out=None,
                postfix=""):

        # notify other camera to take a picture
        self.tx.on()

        # check whether channel is valid
        if channel_name.lower().startswith("r"):
            channel = 0
            channel_name = "red"
        elif channel_name.lower().startswith("g"):
            channel = 1
            channel_name = "green"
        elif channel_name.lower().startswith("b"):
            channel = 2
            channel_name = "blue"
        else:
            print("wrong channel_name: '{}'".format(channel_name))

        # get camera settings
        time.sleep(1)
        fps = float(self.cam.framerate)
        ss = self.cam.exposure_speed
        g = self.cam.awb_gains
        g1 = g[0].numerator
        g2 = g[0].denominator
        g3 = g[1].numerator
        g4 = g[1].denominator
        iso = self.cam.iso
        settings_str = "ss{}_g{}-{}_{}-{}_iso{}_".format(
                ss, g1, g2, g3, g4, iso)
        csv_row = [fps, ss, iso, g1, g2, g3, g4]
        print("taking photos with settings: {}".format(
                settings_str))

        # with picamera.PiCamera(resolution=RESOLUTION) as cam:
        # https://picamera.readthedocs.io/en/latest/
        #         api_array.html#module-picamera.array
        with picamera.array.PiRGBArray(self.cam) as output:

            # cam.zoom = REGION_OF_INTEREST
            # cam.start_preview()

            # take picture
            t0 = time.time()
            self.cam.capture(output, format="rgb")
            a = output.array
            t1 = time.time()
            print("recorded for {} sec".format(round(t1-t0, 2)))
            t_pic = int(round(np.mean([t0, t1])))
            # re-empty output (to reuse next iteration)
            # output.truncate(0)

        # crop to region of interest
        roi = a[ROI[0]:ROI[1], ROI[2]:ROI[3], :]

        vals = []
        vals.append(np.median(roi[:, :, 0]))
        vals.append(np.median(roi[:, :, 1]))
        vals.append(np.median(roi[:, :, 2]))

        print(("roi.shape={},\n" +
               # "sum(red)={}, sum(green)={}, sum(blue)={},\n" +
               "med(red)={}, med(green)={}, med(blue)={}").format(
                       roi.shape, vals[0], vals[1], vals[2]))

        val = vals[channel]
        print("reading the {} channel...\nvalue: {}".format(
                channel_name, val))
        if val >= threshold:
            activated = True
        else:
            activated = False
        print("active={} (threshold: {})".format(activated, threshold))

        # debug mode:
        # output images and csv if output directory exists
        if dir_out:

            names = ["1-red", "2-green", "3-blue"]

            # whole images
            fn = "full_{}{}_0-rgb{}.png".format(
                    settings_str, postfix, now_str())
            ffn = safename(os.path.join(dir_out, fn), "file")
            plt.imsave(ffn, a)
            for i in range(3):
                fn = "full_{}{}_{}{}.png".format(
                        settings_str, postfix,
                        names[i], now_str())
                ffn = safename(os.path.join(dir_out, fn), "file")
                plt.imsave(ffn, a[:, :, i], vmin=0, vmax=255)

            # cropped to ROI
            fn = "roi_{}{}_0-rgb{}.png".format(
                    settings_str, postfix, now_str())
            ffn = safename(os.path.join(dir_out, fn), "file")
            plt.imsave(ffn, roi)
            for i in range(3):
                fn = "roi_{}{}_{}{}.png".format(
                        settings_str, postfix,
                        names[i], now_str())
                ffn = safename(os.path.join(dir_out, fn), "file")
                plt.imsave(ffn, roi[:, :, i], vmin=0, vmax=255)

            csv_row.extend([t_pic, from_timestamp(t_pic), postfix,
                            vals[0], vals[1], vals[2]])
            with open(csv_out, "at") as csvfile:
                csvwriter = csv.writer(csvfile)
                csvwriter.writerow(csv_row)
            print("wrote csv_row: {}".format(csv_row))

        # read state of the slave-camera
        other_activated = False
        # impossible that both are active!
        if not activated:
            timeout = time.time() + 2  # seconds
            while not other_activated and time.time() < timeout:
                other_activated = self.rx.is_active
        self.tx.off()

        # determine final state
        if activated:
            output = 1
        elif other_activated:
            output = -1
        else:
            output = 0

        return output

    def exit_clean(self):
        if not self.cam == "":
            self.cam.close()


def main(args):
    global CSV_NAME
    global CSV_HEADER

    # t0 = time.time()
    cam = ColiCam(mode=args.mode)
    # t_cam = time.time() - t0

    # select mode (camera settings)
    current_mode = args.mode

    # optionally create output directory for debugging
    if args.debug:
        # setup output directory (and copy over the code?)
        dir_out = "/home/pi/ColiCam_{}".format(now_str("%y%m%d"))
        dir_out = safename(dir_out, "dir")
        if not os.path.isdir(dir_out):
            os.mkdir(dir_out)
        print("outputting to '{}'".format(dir_out))
        # initialize csv-log
        csv_fn = "{}{}{}.csv".format(CSV_NAME, args.postfix, now_str())
        csv_out = safename(os.path.join(dir_out, csv_fn), 'file')
        # write header
        with open(csv_out, "wt") as csvfile:
            csvwriter = csv.writer(csvfile)
            csvwriter.writerow(CSV_HEADER)
        print("initialized {} with header {}".format(
                csv_out, CSV_HEADER))
    else:
        dir_out = None
        csv_out = None

    # it = 0
    try:
        while True:
            # it += 1

            # update mode
            new_mode = args.mode
            if not current_mode == new_mode:
                cam.set_cam(mode=new_mode)
            # cam.set_cam(mode=args.mode)
            print("measuring in {} mode (default):".format(args.mode))

            # measure with both cams
            val = cam.measure(dir_out=dir_out, csv_out=csv_out,
                              postfix=args.postfix)
            if val == -1:
                print("wall on the left\n")
            elif val == 0:
                print("no wall detected\n")
            elif val == 1:
                print("wall on the right\n")

    except KeyboardInterrupt:
        print("manually interrupted program")

    finally:
        cam.exit_clean()
        print("camera closed, done!")


if __name__ == "__main__":
    main(args)

Camera Slave:
#!/usr/bin/env python
"""
Code for the slave-camera

It is connected to the master-camera via 2 GPIO pins
and outputs the detected bacterial state via the
GPIO-connection to the master-camera.

In order to constantly listen for commands from the
master camera, it needs to start a background-
thread.

@author: Daniel Hofstadler, 2017
"""
import os
import csv
import time
import argparse
import gpiozero
import threading
from datetime import datetime
from fractions import Fraction

import numpy as np
import picamera
import picamera.array

from matplotlib import pyplot as plt

# import warnings
# warnings.filterwarnings('error', category=DeprecationWarning)

# globals
# LOCAL_TZ = pytz.timezone("Etc/UTC")  # read from cams.csv
OUT_APPEND = "_coli"
CSV_NAME = "colicam"
CSV_HEADER = ["framerate", "exposure_time_us", "iso",
              "g1", "g2", "g3", "g4",
              "timestamp", "time_utc", "tag",
              "red", "green", "blue"]
# RESOLUTION = (2592, 1944)
RESOLUTION = (1280, 720)
# REGION_OF_INTEREST = (0.35, 0.4, 0.5, 0.7)
ROI = [200, 520, 480, 800]  # Y0, Y1, X0, X1
DETECTION_THRESHOLD = 150
PIN_RX = 17
PIN_TX = 18

SETTINGS_FIXED = {
        'name': "fixed",
        'ss': 1000000,  # 1000 milliseconds = 1 sec
        'fps': Fraction(1, 2),  # (1, 2)
        'iso': 800,  # 800
        'g': (Fraction(2, 1), Fraction(1, 1)),
        # 'g': (Fraction(345, 256), Fraction(167, 128)),
        'sleep': 15}  # 10
SETTINGS_SENSITIVE = {
        'name': "sensitive",
        'ss': 6000000,  # 6 seconds
        'fps': Fraction(1, 6),
        'iso': 800,
        'g': None,
        'sleep': 30}
SETTINGS_AUTO = {
        'name': "auto",
        'ss': None,
        'fps': 30,
        'iso': 0,
        'g': None,
        'sleep': 2}

SETTINGS_DEFAULT = "fixed"

# argument parsing
parser = argparse.ArgumentParser(
        description="Colibot Photometer Camera.")
parser.add_argument("-d", "--debug", action="store_true",
                    help="debug mode")
parser.add_argument("-m", "--mode", type=str, default="fixed",
                    choices=["f", "fixed", "s", "sensitive", "a", "auto"],
                    help="set the camera mode")
parser.add_argument("-p", "--postfix", type=str, default="",
                    help="add string to filename")
# args = vars(ap.parse_args())
args = parser.parse_args()
if not args.postfix == "" and not args.postfix.startswith("_"):
    args.postfix = "_" + args.postfix


def now_str(pattern="_%y%m%d-%H%M%S_utc"):
    # return time.strftime(pattern, time.gmtime())
    return datetime.utcnow().strftime(pattern)


def from_timestamp(ts, pattern="%y%m%d-%H%M%S_utc"):
    return datetime.utcfromtimestamp(ts).strftime(pattern)


def safename(s, s_type):
    """Check whether a given file or folder 's' exists, return a non-existing
    filename.
    s ........ (full) filename or directory
    s_type ... 'file' or 'f' for files,
               'directory' or 'dir' or 'd' for folders
    Returns a file- or pathname that is supposedly safe to save
    without overwriting data.
    """
    low_type = str.lower(s_type)
    if low_type == 'file' or low_type == 'f':
        if os.path.isfile(s):
            s2 = s.split('.')
            s_base = s2[0]
            s_ext = s2[-1]

            counter = 0
            while os.path.isfile(s):
                s = s_base + "-{:02d}.".format(counter) + s_ext
                counter += 1

    elif low_type == 'directory' or low_type == 'dir' or low_type == 'd':
        if os.path.isdir(s):
            s_base = s

            counter = 0
            while os.path.isdir(s):
                s = s_base + "-{:02d}".format(counter)
                counter += 1
    return s


def thread_listener(cam):
    """Background thread listening on the receive-pin
    whether to make a measurement."""
    try:
        while cam.active:
            if cam.rx.is_active:
                cam.measure_slave()
            time.sleep(0.5)
    finally:
        print("listener thread shutting down")


class ColiCamSlave:
    global RESOLUTION
    global ROI  # REGION_OF_INTEREST
    global DETECTION_THRESHOLD
    global SETTINGS_FIXED
    global SETTINGS_SENSITIVE
    global SETTINGS_AUTO
    global DEF_SETTINGS_NAME
    global PIN_RX
    global PIN_TX

    def __init__(self, resolution=RESOLUTION, mode=DEF_SETTINGS_NAME):
        try:
            self.cam = picamera.PiCamera(resolution=resolution)
            self.set_cam(mode)
        except Exception as err:
            self.cam = ""
            print("couldn't initialize camera, error: {}".format(err))
        self.rx = gpiozero.InputDevice(PIN_RX)
        self.tx = gpiozero.OutputDevice(PIN_TX)
        self.active = True

        # start the listening thread
        listener = threading.Thread(
                target=thread_listener, args=(self))
        listener.daemon = True
        listener.start()
        self.listener = listener

    def set_cam(self, mode="fixed"):

        if mode.lower().startswith("f"):
            settings = SETTINGS_FIXED
        elif mode.lower().startswith("s"):
            settings = SETTINGS_SENSITIVE
        elif mode.lower().startswith("a"):
            settings = SETTINGS_AUTO
        else:
            print("wrong camera mode")

        # switch on auto mode
        self.cam.awb_mode = 'auto'
        self.cam.exposure_mode = 'auto'

        # settings = dict with fields: name, ss, fps, iso, g, sleep
        self.cam.framerate = settings['fps']
        if settings['ss']:
            self.cam.shutter_speed = settings['ss']
        self.cam.iso = settings['iso']

        # Wait for the automatic gain control to settle
        time.sleep(settings['sleep'])

        # Now fix the values
        if not settings['ss']:
            self.cam.shutter_speed = self.cam.exposure_speed
        self.cam.exposure_mode = 'off'

        if settings['g']:
            g = settings['g']
        else:
            g = self.cam.awb_gains
        self.cam.awb_mode = 'off'
        self.cam.awb_gains = g

    def measure_slave(self,
                      roi=ROI,
                      channel_name="green",
                      threshold=DETECTION_THRESHOLD,
                      dir_out=None,
                      csv_out=None,
                      postfix=""):

        # check whether channel is valid
        if channel_name.lower().startswith("r"):
            channel = 0
            channel_name = "red"
        elif channel_name.lower().startswith("g"):
            channel = 1
            channel_name = "green"
        elif channel_name.lower().startswith("b"):
            channel = 2
            channel_name = "blue"
        else:
            print("wrong channel_name: '{}'".format(channel_name))

        # get camera settings
        time.sleep(1)
        fps = float(self.cam.framerate)
        ss = self.cam.exposure_speed
        g = self.cam.awb_gains
        g1 = g[0].numerator
        g2 = g[0].denominator
        g3 = g[1].numerator
        g4 = g[1].denominator
        iso = self.cam.iso
        settings_str = "ss{}_g{}-{}_{}-{}_iso{}_".format(
                ss, g1, g2, g3, g4, iso)
        csv_row = [fps, ss, iso, g1, g2, g3, g4]
        print("taking photos with settings: {}".format(
                settings_str))

        # with picamera.PiCamera(resolution=RESOLUTION) as cam:
        # https://picamera.readthedocs.io/en/latest/
        #         api_array.html#module-picamera.array
        with picamera.array.PiRGBArray(self.cam) as output:

            # cam.zoom = REGION_OF_INTEREST
            # cam.start_preview()

            # take picture
            t0 = time.time()
            self.cam.capture(output, format="rgb")
            a = output.array
            t1 = time.time()
            print("recorded for {} sec".format(round(t1-t0, 2)))
            t_pic = int(round(np.mean([t0, t1])))
            # re-empty output (to reuse next iteration)
            # output.truncate(0)

        # crop to region of interest
        roi = a[ROI[0]:ROI[1], ROI[2]:ROI[3], :]

        vals = []
        vals.append(np.median(roi[:, :, 0]))
        vals.append(np.median(roi[:, :, 1]))
        vals.append(np.median(roi[:, :, 2]))

        print(("roi.shape={},\n" +
               # "sum(red)={}, sum(green)={}, sum(blue)={},\n" +
               "med(red)={}, med(green)={}, med(blue)={}").format(
                       roi.shape, vals[0], vals[1], vals[2]))

        val = vals[channel]
        print("reading the {} channel...\nvalue: {}".format(
                channel_name, val))

        # checking whether threshold is crossed and
        #   signalling the master-camera
        if val >= threshold:
            activated = True
            self.tx.on()
        else:
            activated = False
            self.tx.off()
        print("active={} (threshold: {})".format(activated, threshold))

        # debug mode:
        # output images and csv if output directory exists
        if dir_out:

            names = ["1-red", "2-green", "3-blue"]

            # whole images
            fn = "full_{}{}_0-rgb{}.png".format(
                    settings_str, postfix, now_str())
            ffn = safename(os.path.join(dir_out, fn), "file")
            plt.imsave(ffn, a)
            for i in range(3):
                fn = "full_{}{}_{}{}.png".format(
                        settings_str, postfix,
                        names[i], now_str())
                ffn = safename(os.path.join(dir_out, fn), "file")
                plt.imsave(ffn, a[:, :, i], vmin=0, vmax=255)

            # cropped to ROI
            fn = "roi_{}{}_0-rgb{}.png".format(
                    settings_str, postfix, now_str())
            ffn = safename(os.path.join(dir_out, fn), "file")
            plt.imsave(ffn, roi)
            for i in range(3):
                fn = "roi_{}{}_{}{}.png".format(
                        settings_str, postfix,
                        names[i], now_str())
                ffn = safename(os.path.join(dir_out, fn), "file")
                plt.imsave(ffn, roi[:, :, i], vmin=0, vmax=255)

            csv_row.extend([t_pic, from_timestamp(t_pic), postfix,
                            vals[0], vals[1], vals[2]])
            with open(csv_out, "at") as csvfile:
                csvwriter = csv.writer(csvfile)
                csvwriter.writerow(csv_row)
            print("wrote csv_row: {}".format(csv_row))

        return None

    def exit_clean(self):
        if not self.cam == "":
            self.cam.close()


def main(args):
    global CSV_NAME
    global CSV_HEADER

    # t0 = time.time()
    cam = ColiCam(mode=args.mode)
    # t_cam = time.time() - t0

    # select mode (camera settings)
    current_mode = args.mode

    # optionally create output directory for debugging
    if args.debug:
        # setup output directory (and copy over the code?)
        dir_out = "/home/pi/ColiCam_{}".format(now_str("%y%m%d"))
        dir_out = safename(dir_out, "dir")
        if not os.path.isdir(dir_out):
            os.mkdir(dir_out)
        print("outputting to '{}'".format(dir_out))
        # initialize csv-log
        csv_fn = "{}{}{}.csv".format(CSV_NAME, args.postfix, now_str())
        csv_out = safename(os.path.join(dir_out, csv_fn), 'file')
        # write header
        with open(csv_out, "wt") as csvfile:
            csvwriter = csv.writer(csvfile)
            csvwriter.writerow(CSV_HEADER)
        print("initialized {} with header {}".format(
                csv_out, CSV_HEADER))
    else:
        dir_out = None
        csv_out = None

    # it = 0
    try:
        while True:
            # it += 1

            # update mode
            new_mode = args.mode
            if not current_mode == new_mode:
                cam.set_cam(mode=new_mode)
            # cam.set_cam(mode=args.mode)
            print("measuring in {} mode (default):".format(args.mode))

            # measure with both cams
            val = cam.measure(dir_out=dir_out, csv_out=csv_out,
                              postfix=args.postfix)
            if val == -1:
                print("wall on the left\n")
            elif val == 0:
                print("no wall detected\n")
            elif val == 1:
                print("wall on the right\n")

    except KeyboardInterrupt:
        print("manually interrupted program")

    finally:
        cam.exit_clean()
        print("camera closed, done!")


if __name__ == "__main__":
    main(args)