Operácie

MEMS Cvičenie 5

Z SensorWiki

  • 11.3.2020 pridané materiály na samoštúdium
  • 15.3.2020 pridané cvičenie s kamerou a detekciou farby
ColorLegoCubes.jpg

Detekcia farieb CMOS senzorom

Úloha: zdetekujte a rozlíšte aspon 6 základných druhov farieb na rozličných vzorkách. Naprogramujte aplikáciu, ktorá zdetekuje farbu predloženej vzorky (RGB) a určí, ku ktorej z naučených farieb má najbližšie.


Teoretický úvod - Basics of colorimetry. Guide for industrial color measurement.


Príklad priemyselných snímačov farby - uE Product broschure (str. 26-27)


Na cvičeniach v škole by sme použili špeciálny senzor farby, ktorý eliminuje vplyv okolitého osvetlenia tým, že si vzorku sám nasvieti. Pozostáva, podobne ako CMOS kamera z niekoľkých (16) pixelov, ktoré majú filtre R, G a B zložky. Výstupom senzora sú hodnoty R, G, B a I - celkovej intenzity. Vyhodnotením I môžeme čiastočne vylúčiť vplyv okolitého osvetlenia.

Doma senzor pravdepodobne nemáme, preto využijeme to, čo sa dá - kameru na notebooku, alebo v mobile.

Program napíšeme v prostredí Processing, ktoré už máte z minulej domácej úlohy. Pripomínam len, že Processing existuje aj vo verzii pre Linux a iOS. Príprava spočíva len v doinštalovaní knižnice (library) video. Z menu Sketch -> Import Library... -> Add Library... vyhľadáme a dáme nainštalovať Video | GStreamer-based library for Processing

VideoLibraryImport.png

Potom si nahráte nižšie uvedený ukážkový program. Ak máte na notebooku kameru, tak sa vyberie najjednoduchší režim 160x120px a z obrazu vezmeme stredý pixel. Hodnoty R, G a B zložiek uložíme do premenných red[0], green[0] a blue[0]. Hodnoty vypíšeme do okienka a vytvoríme obdĺžnik vo farbe, ktorú sme zdetekovali. Okrem toho sa v okienku nakreslí zameriavací bod, aby bolo zrejmé, kde určujeme farbu. Obraz z kamery samotnej môžeme zapnúť klávesou 'c' (alebo vypnúť).


SmallVideoWindow.png

import processing.video.*;

Capture cam;

int[]   red = new int[9];  
int[] green = new int[9];
int[]  blue = new int[9];

boolean videoOnScreen;


void setup() 
{
  size(160, 120);  // velkost okna prisposobime videu
  
  // tato cast tu nemusi byt, je tu len na zobrazenie vsetkych dostupnych videosluzieb
  String[] cameras = Capture.list();
  if (cameras.length == 0) 
  {
    println("There are no cameras available for capture.");
    exit();
  } 
  else 
  {
    println("Available cameras:");
    for (int i = 0; i < cameras.length; i++) 
      println("[" + i + "] " +cameras[i]);
  }
  // potom si vyberiem bud zo zoznamu, napr. takto
  // cam = new Capture(this, cameras[23]);  
  // alebo priamo urcim rozlisenie takto:  
  cam = new Capture(this, 160, 120);  // 160x120 / 30fps
  
  // Start capturing the images from the camera
  cam.start();  
  
 }




void draw() 
{
  if (cam.available()) 
  {
    cam.read();
    cam.loadPixels();
    
   // pixels je jednorozmerne dlhe pole po riadkoch ulozene
   // stredny pixel je tento:
    int j = cam.height / 2;
    int i = cam.width / 2;
    int pixelColor = cam.pixels[j*cam.width + i];

 
     // farba v pixelColor je ulozena ako jeden dlhy int, 
     // ktory rozlozime na tri RGB zlozky:
     red[0] = (pixelColor >> 16) & 0xff;
     green[0] = (pixelColor >> 8) & 0xff;
     blue[0] = pixelColor & 0xff;

    /* ***************************************************** */
    /*                                                       */  
    /* Tu zacina praca pre vas, mili studenti:               */
    /* ja som si vybral len stredny pixel, na vas je spravit */
    /* okienko 3x3 a vypocitat priemernu hodnotu z tychto    */
    /* 9 pixelov. Polia red, green a blue uz mate pripravene */
    /*                                                       */  
    /* ***************************************************** */
   


    // a tu uz len vsetko vykreslime do okna

    background(0);  // cierne pozadie
    noStroke();   
    
    if (videoOnScreen)   // zalezi ci stlacim klavesu 'c' 
    {
      set(0, 0, cam); 
    }

    noFill();
    stroke(255, 255, 0);  // yellow
    ellipse(80,60,40,40); // kruzok
    line(80,40,80,80);    // krizik v strede
    line(60,60,100,60);
    
    
    fill(red[0], green[0], blue[0]);  // farebny obdlznicek vpravo hore   
    rect(120,5,35,10);

    // takto sa zobrazi v obrazku text:
    String message = "R: " + red[0] + "  G: " + green[0] + "  B: " + blue[0];
    fill(255,255,0);
    text(message, 5, 15);

    
     }   /* end of if */
}     /* end of draw() */


void keyPressed() 
{
  if  (key == 'c') 
    videoOnScreen = !videoOnScreen;
}


Ak vám vzorový program funguje, nasleduje samostatná práca:

  1. namiesto málo spoľahlivého merania v jednom jedinom pixeli, spravte meranie vo štvorci 3x3 (nemusia to byť nevyhnutne tie bezprostredne vedľa seba), aby ste vylúčili to, že meranie rozličných farieb robíte napr. práve cez pixel s červeným filtrom. V programe už máte pripravené pole red[9], green[9] a blue[9]. Výsledná R, G, B trojica bude daná priemerom z tých deviatich políčok.
  2. naučte program detekovať niekoľko základných farieb. Predložte mu napríklad červenú vzorku, zapamätajte si R,G a B súradnice a uložte si ich. Pri meraní neznámej vzorky potom vypočítajte farebnú vzdialenosť (pozri domácu úlohu na Repl.it) a ak je menšia ako nejaká rozhodovacia úroveň (treshold), tak ju vyhlásite tiež za červenú. Takýchto farieb by ste mali spoznať aspoň 6 (určite červená, modrá, zelená, biela a čierna).
  3. zdokumentujte svoje riešenie: predložte niekoľko napr. červených vzoriek a ukážte, že všetky boli správne klasifikované


Ak si trúfate, môžete riešenie vyšperkovať, napríklad učenie bude prebiehať poloautomaticky, na klasifikáciu použijete neurónovú sieť a pod. Nemusíte riešenie robiť v Processingu, použite to čo viete a čo máte doma k dispozícii.

Laboratórne cvičenie

Tieto úlohy sa týkajú LEN merania na cvičeniach.

Návod na cvičenia: (kliknutím rozbaliť / zbaliť)


Úloha 1:

pripojte senzor QTI k mikroprocesoru, zobrazte aktuálnu hodnotu výstupného signálu a pokúste sa pomocou senzora rozpoznať základné farby


Úloha 2:

zoznámte sa so senzorom farby ColorPAL (fotodióda TAOS TSL12T), pripojte ho k mikropočítaču a rozpoznajte základné farby

Porovnajte dosiahnuté výsledky s kvalitnejším senzorom TCS230


Použite softvér uvedený v príkladoch:


Odovzdať:

  • Nameranú závislosť od vzdialenosti
  • Nameranú závislosť farby pri konštantnej vzdialenosti
  • Ten kúsok programu, ktorý realizoval rozpoznanie farby


Doplnkové informácie

Rozpoznávanie farieb

Trocha hlbšia a vtipná analýza ako vnímame a rozpoznáva farby človek nájdete v článku Randall P. Munroe: Color survey - results.

ColorNamesBoysVsGirls.png

Tu zasa nájdete viac ďalších informácií k téme Senzory na rozpoznávanie farieb


Testovací obrázok

Tento obrázok si môžete vytlačiť a použiť ho pri učení farieb.

ColorReferenceCard.png

Externá kamera

Ak nemáte na notebooku kameru, alebo sa vám s ňou zle pracuje, môžete použiť DroidCam - nainštalujete appku na Android telefón, po spustení sa začne obraz z telefónu streamovať cez WiFi. Na PC nainštalujete klienta, ktorý potom vytvorí zdanie, že daná kamera je priamo na notebooku. Mne to nefungovalo veľmi spľahlivo, ale je to riešiteľné.


DroidCamWindow.png


Celkom iné riešenie je v tomto návode - Detekcia farieb. Využíva Android Caputre.



Návody pre Processing


Farebná vzdialenosť

Spravte si najprv na domácu úlohu https://repl.it/teacher/assignments/4866124 potom bude všetko jasnejšie.


Lepšia vzdialenosť farieb

Keďže farby sú dané troma súradnicami (napr. RGB), je celkom prirodzené použiť na meranie vzdialenosti medzi farbami euklidovskú vzdialenosť v 3D priestore. Lenže ukazuje sa, že vzhľadom na fyziológiu ľudského vnímania farieb nie je celkom vhodné merať to v priesotre RGB, tam to nekorešponduje s ľudskou skúsenosťou. Preto sa na tento účel používa farebný priestor CIE Lab

CIE L*a*b* (CIELAB) je farebný priestor, ktorý zadefinovala CIE (International Commission on Illumination). Je to referenčný model, ktorý opisuje všetky ľudským okom viditeľné farby. Jeho tri súradnice reprezentujú intenzitu farby (L* = 0 je čierna a L* = 100 je rozptýlené biele svetlo), jej polohu na medzi červeno/fialovou a zelenou (a*, záporné čísla pre zelenú, kladné pre fialovú) a jej polohu medzi žltou a modrou (b*, záporné čísla pre modrú, kladné pre žltú).


Konverzia

There is no single simple equation for this conversion; you would need to know the specific RGB primaries in question, expressed in some standard system such as (preferably) XYZ tristimulus values, along with the intended white point and transfer function(s) (“gamma” curves). From this information, you could calculate the correct XYZ values given any RGB code, and then it would be a (relatively) simple conversion from XYZ to Lab. But in many cases no RGB specification is provided, in which case many assume sRGB: sRGB - Wikipedia. Using that transformation to CIE XYZ, then to CIE Lab: Lab color space - Wikipedia

Pre konverziu z jedného farebného modelu do iného sa používajú štandardizované CIE vzťahy. Neexistuje jednoduchý prevod medzi RGB a Lab priestormi, pretože ten prvý je závislý od zariadenia, ten druhý je device independent. Preto sa používa medziprevod RGB -> sRGB -> XYZ -> Lab

Prvý prevod je teda z RGB do priestoru XYZ:



\begin{bmatrix}
X_{D65}\\
Y_{D65}\\
Z_{D65}
\end{bmatrix}
=
\begin{bmatrix}
0.4124 & 0.3576 &0.1805 \\
0.2126 & 0.7152 &0.0722 \\
0.0193 & 0.1192 &0.9505
\end{bmatrix}
\begin{bmatrix}
R_\mathrm{linear}\\ 
G_\mathrm{linear}\\ 
B_\mathrm{linear}\end{bmatrix}


Nasleduje prevod do Lab priestoru,

\begin{align}
  L^\star &= 116 \  f\!\left(\frac{Y}{Y_{\mathrm{n}}}\right) - 16\\
  a^\star &= 500 \left(f\!\left(\frac{X}{X_{\mathrm{n}}}\right) - f\!\left(\frac{Y}{Y_{\mathrm{n}}}\right)\right)\\
  b^\star &= 200 \left(f\!\left(\frac{Y}{Y_{\mathrm{n}}}\right) - f\!\left(\frac{Z}{Z_{\mathrm{n}}}\right)\right)
\end{align}

kde

\begin{align}
  f(t) &= \begin{cases}
    \sqrt[3]{t} & \text{if } t > \delta^3 \\
    \frac{t}{3 \delta^2} + \frac{4}{29} & \text{otherwise}
  \end{cases} \\
  \delta &= \frac{6}{29}
\end{align}


A kde ďalej Xn, Yn a Zn sú hodnoty CIE XYZ tristimulov pre referenčný biely bod, pričom index n znamená normalizovaný. Tieto hodnoty sú pre štandartné osvetlenie - Illuminant D65 s normalizáciou 1= Y = 100 nasledovné:

\begin{align}
X_{\mathrm{n}}&=95.0489,\\
Y_{\mathrm{n}}&=100,\\
Z_{\mathrm{n}}&=108.8840
\end{align}


Tieto hodnoty závisia od osvetlenia, napríklad pre Illuminant D50 sú:

\begin{align}
X_{\mathrm{n}}&=96.4212,\\
Y_{\mathrm{n}}&=100,\\
Z_{\mathrm{n}}&=82.5188
\end{align}




Návrat na zoznam cvičení...