Pages

Sunday

Détection d'œil avec MATLAB 2016

La reconnaissance faciale par ordinateur:

La reconnaissance de visage est le processus d'identification d'une ou plusieurs personnes dans des images ou des vidéos en analysant et en comparant des modèles. Les algorithmes pour la reconnaissance faciale extraient typiquement les caractéristiques faciales et les comparent à une base de données pour trouver la meilleure correspondance. La reconnaissance faciale est une partie importante de nombreux systèmes biométriques, de sécurité et de surveillance, ainsi que des systèmes d'indexation d'image et de vidéo.

Étapes du processus de reconnaissance de visage.



Notions de base


La détection d'objets à l'aide des classificateurs en cascade Haar est une méthode de détection d'objet efficace proposée par Paul Viola et Michael Jones dans son article "Détection Rapide d'Objets utilisant une Cascade de Fonctions Simples". Cascade est formée à partir d'un grand nombre d'images positives et négatives. Il est ensuite utilisé pour détecter des objets dans d'autres images.

Ici, nous allons travailler avec la détection de l'eye. Initialement, l'algorithme a besoin de beaucoup d'images positives (images des yeux) et d'images négatives (images sans yeux) pour former le classificateur. Ensuite, nous devons extraire des fonctionnalités de celui-ci. Pour cela, les caractéristiques de haar indiquées dans l'image ci-dessous sont utilisées. Ils sont comme notre noyau convolutionnel. Chaque caractéristique est une valeur unique obtenue en soustrayant la somme des pixels sous le rectangle blanc de la somme des pixels sous le rectangle noir.

Détection d'œil a base de Matlab:


Eye detection using MATLAB



Code MATLAB:



faceDetector = vision.CascadeObjectDetector('C:\Users\Imed\Desktop\Projet_sign_detection_matlab\eye.xml');
pointTracker = vision.PointTracker('MaxBidirectionalError', 8);
cam = webcam();
videoFrame = snapshot(cam);
frameSize = size(videoFrame);

videoPlayer = vision.VideoPlayer('Position', [100 100 [frameSize(2), frameSize(1)]+30]);
runLoop = true;
numPts = 0;
frameCount = 0;
while runLoop && frameCount < 800
    videoFrame = snapshot(cam);
    videoFrameGray = rgb2gray(videoFrame);
    frameCount = frameCount + 1;

    if numPts < 10
        bbox = faceDetector.step(videoFrameGray);

        if ~isempty(bbox)
            % Find corner points inside the detected region.
            points = detectMinEigenFeatures(videoFrameGray, 'ROI', bbox(1, :));

            % Re-initialize the point tracker.
            xyPoints = points.Location;
            numPts = size(xyPoints,1);
            release(pointTracker);
            initialize(pointTracker, xyPoints, videoFrameGray);

            % Save a copy of the points.
            oldPoints = xyPoints;
            bboxPoints = bbox2points(bbox(1, :));

            % Convert the box corners into the [x1 y1 x2 y2 x3 y3 x4 y4]
            % format required by insertShape.
            bboxPolygon = reshape(bboxPoints', 1, []);

            % Display a bounding box around the detected face.
            videoFrame = insertShape(videoFrame, 'Polygon', bboxPolygon, 'LineWidth', 3);

            % Display detected corners.
            videoFrame = insertMarker(videoFrame, xyPoints, '+', 'Color', 'white');
        end

    else
        % Tracking mode.
        [xyPoints, isFound] = step(pointTracker, videoFrameGray);
        visiblePoints = xyPoints(isFound, :);
        oldInliers = oldPoints(isFound, :);

        numPts = size(visiblePoints, 1);

        if numPts >= 10
            % Estimate the geometric transformation between the old points
            % and the new points.
            [xform, oldInliers, visiblePoints] = estimateGeometricTransform(...
                oldInliers, visiblePoints, 'similarity', 'MaxDistance', 4);

            % Apply the transformation to the bounding box.
            bboxPoints = transformPointsForward(xform, bboxPoints);

            % Convert the box corners into the [x1 y1 x2 y2 x3 y3 x4 y4]
            % format required by insertShape.
            bboxPolygon = reshape(bboxPoints', 1, []);

            % Display a bounding box around the face being tracked.
            videoFrame = insertShape(videoFrame, 'Polygon', bboxPolygon, 'LineWidth', 3);
            position =  [1 50; 100 50];
value = [111 pi];text_str = 'eye';position =xyPoints;
box_color = {'red'};
hh=[bboxPoints(4,1) bboxPoints(4,2)];
videoFrame= insertText(videoFrame,hh,text_str,'FontSize',14,'BoxColor',...
    box_color,'BoxOpacity',0.6,'TextColor','white');
            % Display tracked points.
            videoFrame = insertMarker(videoFrame, visiblePoints, '+', 'Color', 'white');

            % Reset the points.
            oldPoints = visiblePoints;
            setPoints(pointTracker, oldPoints);
        end

    end

    % Display the annotated video frame using the video player object.
    step(videoPlayer, videoFrame);

    % Check whether the video player window has been closed.
    runLoop = isOpen(videoPlayer);
end

% Clean up.
clear cam;
release(videoPlayer);
release(pointTracker);
release(faceDetector);


Telechargement :

eye.xml 



Plus d'informations : imedelmottakel@gmail.com





Interfacing LCD with PIC Microcontroller – CCS PIC C



Je donne dans cet article une bibliothèque C pour les modules LCD basés sur le driver hd44780. Cette bibliothèque est également disponible pour la famille de microcontrôleurs AVR.  Cette bibliothèque est conçue pour être compilée et utilisée avec le compilateur CCS PIC C.




//LCD Module Connections
#define LCD_RS_PIN PIN_D1
#define LCD_RW_PIN PIN_D2
#define LCD_ENABLE_PIN PIN_D3
#define LCD_DATA4 PIN_D4
#define LCD_DATA5 PIN_D5
#define LCD_DATA6 PIN_D6
#define LCD_DATA7 PIN_D7
//End LCD Module Connections


Flex_lcd.c


//#define USE_RW_PIN   0      // donc't use RW PIN 
// These are the line addresses for most 4x20 LCDs. 
#define LCD_LINE_1_ADDRESS 0x00 
#define LCD_LINE_2_ADDRESS 0x40 
#define LCD_LINE_3_ADDRESS 0x14 
#define LCD_LINE_4_ADDRESS 0x54 
#define lcd_type 2   // 0=5x7, 1=5x10, 2=2 lines(or more) 
int8 lcd_line; 
int8 const LCD_INIT_STRING[4] = 
{ 
 0x20 | (lcd_type << 2),  // Set mode: 4-bit, 2+ lines, 5x8 dots 
 0xc,                     // Display on 
 1,                       // Clear display 
 6                        // Increment cursor 
 }; 
                             
//------------------------------------- 
void lcd_send_nibble(int8 nibble) 
{ 
// Note:  !! converts an integer expression 
// to a boolean (1 or 0). 
 output_bit(LCD_DB4, !!(nibble & 1)); 
 output_bit(LCD_DB5, !!(nibble & 2));  
 output_bit(LCD_DB6, !!(nibble & 4));    
 output_bit(LCD_DB7, !!(nibble & 8));    

 delay_cycles(1); 
 output_high(LCD_E); 
 delay_us(2); 
 output_low(LCD_E); 
} 

#ifdef USE_RW_PIN 
int8 lcd_read_nibble(void) 
{ 
int8 retval; 
// Create bit variables so that we can easily set 
// individual bits in the retval variable. 
#bit retval_0 = retval.0 
#bit retval_1 = retval.1 
#bit retval_2 = retval.2 
#bit retval_3 = retval.3 

retval = 0; 
    
output_high(LCD_E); 
delay_us(1); 

retval_0 = input(LCD_DB4); 
retval_1 = input(LCD_DB5); 
retval_2 = input(LCD_DB6); 
retval_3 = input(LCD_DB7); 
  
output_low(LCD_E); 
delay_us(1); 
    
return(retval);    
}    
#endif 

//--------------------------------------- 
// Read a byte from the LCD and return it. 

#ifdef USE_RW_PIN 
int8 lcd_read_byte(void) 
{ 
int8 low; 
int8 high; 

output_high(LCD_RW); 
delay_cycles(1); 

high = lcd_read_nibble(); 

low = lcd_read_nibble(); 

return( (high<<4) | low); 
} 
#endif 

//---------------------------------------- 
// Send a byte to the LCD. 
void lcd_send_byte(int8 address, int8 n) 
{ 
output_low(LCD_RS); 

#ifdef USE_RW_PIN 
while(bit_test(lcd_read_byte(),7)) ; 
#else 
delay_us(60);  
#endif 

if(address) 
   output_high(LCD_RS); 
else 
   output_low(LCD_RS); 
      
 delay_cycles(1); 

#ifdef USE_RW_PIN 
output_low(LCD_RW); 
delay_cycles(1); 
#endif 

output_low(LCD_E); 

lcd_send_nibble(n >> 4); 
lcd_send_nibble(n & 0xf); 
} 
//---------------------------- 

void lcd_init(void) 
{ 
int8 i; 

lcd_line = 1; 

output_low(LCD_RS); 

#ifdef USE_RW_PIN 
output_low(LCD_RW); 
#endif 

output_low(LCD_E); 

// Some LCDs require 15 ms minimum delay after 
// power-up.  Others require 30 ms.  I'm going 
// to set it to 35 ms, so it should work with 
// all of them. 
delay_ms(35);          

for(i=0 ;i < 3; i++) 
   { 
    lcd_send_nibble(0x03); 
    delay_ms(5); 
   } 

lcd_send_nibble(0x02); 

for(i=0; i < sizeof(LCD_INIT_STRING); i++) 
   { 
    lcd_send_byte(0, LCD_INIT_STRING[i]); 
    
    // If the R/W signal is not used, then 
    // the busy bit can't be polled.  One of 
    // the init commands takes longer than 
    // the hard-coded delay of 50 us, so in 
    // that case, lets just do a 5 ms delay 
    // after all four of them. 
    #ifndef USE_RW_PIN 
    delay_ms(5); 
    #endif 
   } 

} 
                                
//---------------------------- 

void lcd_gotoxy(int8 x, int8 y) 
{ 
int8 address; 


switch(y) 
  { 
   case 1: 
     address = LCD_LINE_1_ADDRESS; 
     break; 

   case 2: 
     address = LCD_LINE_2_ADDRESS; 
     break; 

   case 3: 
     address = LCD_LINE_3_ADDRESS; 
     break; 

   case 4: 
     address = LCD_LINE_4_ADDRESS; 
     break; 

   default: 
     address = LCD_LINE_1_ADDRESS; 
     break; 
      
  } 

address += x-1;                            
lcd_send_byte(0, 0x80 | address); 
} 
                                              
//----------------------------- 
void lcd_putc(char c) 
{                                    
 switch(c) 
   { 
    case '\f': 
      lcd_send_byte(0,1); 
      lcd_line = 1; 
      delay_ms(2); 
      break; 
    
    case '\n': 
       lcd_gotoxy(1, ++lcd_line); 
       break; 
    
    case '\b': 
       lcd_send_byte(0,0x10); 
       break; 
    
    default: 
       lcd_send_byte(1,c); 
       break; 
   } 
} 

//------------------------------ 
#ifdef USE_RW_PIN 
char lcd_getc(int8 x, int8 y) 
{ 
char value; 

lcd_gotoxy(x,y); 

// Wait until busy flag is low. 
while(bit_test(lcd_read_byte(),7));  

output_high(LCD_RS); 
value = lcd_read_byte(); 
output_low(LCD_RS); 

return(value); 
} 
#endif


Pour plus d'informations : imedelmottakel@gmail.com







Thursday

Application pour le calcul du bruit thermique



Bonjour tous le monde,

Dans ce monde, il n'y a pas de parfait ! Ce que mène la vie dure aux traiteurs de signaux.
Car pratiquement il est impossible de trouver un signal parfait, ou signal sans
bruit.
Comme qu'il est un facteur très important dans la conception de nombreux appareils électroniques / applications et circuits RF, il est important d'être en mesure de calculer les valeurs de bruit dans les conditions de travail de ces appareils..

Je m’intéresse dans cette article au calcul du bruit Thermique 



Phénomène d'agitation thermique



Vous pouvez consulter Wikipédia pour plus d'informations a propos le bruit thermique.


Les calculs de bruit thermique peuvent être très utiles lors de la phase de conceptions des circuits électroniques a faible puissance ou les circuits de haute fréquence. Alors que certains intégration peut être nécessaire dans certains cas, il existe des équations simples pour la plupart des calculs requis.

Calcul du bruit thermique de base et les équations.

Le bruit thermique est un bruit blanc qui se trouve sur un spectre très large. La puissance du bruit est proportionnel à la largeur de bande. Il est donc possible de définir une équation généralisée pour la tension de bruit à l'intérieur d'une bande passante donnée ci-dessous:


Où: 
V = tension efficace intégrée entre les fréquences f1 et f2 
R = composante résistive de l'impédance (ou résistance) Ω 
T = température en degrés Kelvin 
(Kelvin est absolue échelle zéro donc Kelvin = Celsius + 273,16) 
f1 & f2 = inférieur et supérieur limites de la bande passante requise

Pour la plupart des cas, la composante résistive de l'impédance reste constante sur la bande passante requise. Il donc possible de simplifier l'équation de bruit thermique à:

Où: 
B = largeur de bande en Hz

Calculs de bruit thermique pour la température ambiante

Il est possible de calculer les niveaux de bruit thermique pour la température ambiante, 20 ° C ou 290 ° K. Ceci est le plus couramment calculé pour une bande passante de 1 Hz, comme il est facile de mettre à l'échelle à partir d'ici en tant que puissance de bruit est proportionnelle à la bande passante. L'impédance la plus courante est de 50 Ω.


Application développé:


Cette application permet de calculer la valeur estimé du bruit thermique dans une résistance.


Calculatrice du bruit thermique 


Vous pouvez télécharger cette application d'ici.


Plus d'informations: imedelmottakel@gmail.com














Friday

Comment mesurer des températures négatives avec un capteur LM35 et un PIC 16F877 ?






J'ai remarqué que la plupart des projets réalisés en titre "Projet Fin d'Etudes" ont une partie d'acquisition de la température.
La plupart entre eux oubliaient de mesurer la température négative ( température < 0 °C ) ce que provoque un mal-fonctionnement en hiver.
Je veut présenter par cet article comment mesurer une température négative en utilisant le célèbre capteur LM35 et un microcontrôleur PIC 16F877.




Le capteur LM35 supporte des températures assez extrêmes (jusqu'à -55°C / +150°C), mais il n'en est pas de même pour les microcontrôleurs PIC.

Si vous soumettez un microcontrôleur PIC "classique" à ces températures extrêmes, elle va purement et simplement cesser de fonctionner ou se dégrader très rapidement. Cela est valable pour les microcontrôleurs PIC, mais aussi pour tous autres circuits électroniques fabriqués suivant les standards "grand public" (et non "industriels").
Pour information, les gammes de températures classiques en électronique sont les suivantes :
  • grand public : 0°C ~ 70°C 
  • industrie : -40°C ~ 85°C 
  • militaire : -55°C ~ 125°C

Mesurer des températures négatives


Le montage


Pour réaliser ce montage, il va nous falloir :


  • Un microcontrôleur PIC 16F877 
  • Un capteur LM35 (attention, il faut bien prendre une version CZ ou CAZ, pas DZ !) 
  • Un condensateur de 100nF (optionnel, mais recommandé) 
  • Deux diodes 1N4148 
  • Une résistance de 18K ohms (marron / gris / orange
Montage du capteur LM35 pour mesurer une température négative

Le principe 


Les deux diodes 1N4148 induisent une chute de tension d'environ +0.6 volt à leur borne chacune (c'est une caractéristique physique des diodes, appelée "Forward Voltage", soit +1.2 volt au total entre la masse réelle du montage et la broche GND du capteur.

Avec une masse à +1.2 volt au niveau du capteur, il est possible pour le capteur d'aller en dessous de "leur" 0 volt vu qu'il n'est pas en réalité à 0 volt, mais à +1.2 volt.

Il y a cependant un petit souci avec ce montage : la tension aux bornes des diodes varie en fonction de la température … Ce qui est embêtant pour un montage censé mesurer des températures. C'est un comportement normal pour une diode, c'est même un comportement qui est utilisé pour mesurer des températures. Sauf que dans notre cas, c'est un comportement parasite.

L'astuce pour "Annuler" cette variation de tension parasite en fonction de la température consiste à mesurer la tension au niveau de la broche GND du capteur, puis de corriger la mesure finale en faisant une soustraction dans le code pour les mésures.


Vue schématique du montage et code:



Pour commencer notre montage, nous allons câbler la broche VCC du capteur à l'alimentation 5V. On relie ensuite la broche GND du capteur en série avec les deux diodes 1N4148, puis à la broche GND.

N.B. Les diodes sont polarisées ! Elles ont un "sens". Le trait noir sur la diode indique l'emplacement de la barre verticale sur le schéma.

On continue le montage en reliant la broche GND du capteur (juste après les deux diodes), à la broche Ra0 de PIC.

Toujours pour faire les choses bien, on va venir câbler un condensateur de 100nF entre les broches VCC et GND du capteur. Il faut que le condensateur soit câblé le plus près possible du capteur pour être efficace.

On termine en reliant la sortie du capteur à la broche Ra0 avec un fil et en câblant la résistance de 18K ohms entre la sortie du capteur et la broche GND.



Le code


=> Code C pour CCS PIC C Compiler V4.12

Le code complet avec commentaires :
 
#include <16F877.h>
#device adc=10
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES RESERVED                 //Used to set the reserved FUSE bits
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6,rcv=PIN_C7, timeout=2000)  
#include <math.h> 
#define LCD_ENABLE_PIN  PIN_B0                                    ////
#define LCD_RS_PIN      PIN_B1                                    ////
#define LCD_RW_PIN      PIN_B2                                    ////
#define LCD_DATA4       PIN_B4                                    ////
#define LCD_DATA5       PIN_B5                                    ////
#define LCD_DATA6       PIN_B6                                    ////
#define LCD_DATA7       PIN_B7  
#define LCD_TYPE 2
#include "LCD420.C" 
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>

void main()
{  
lcd_init();
setup_adc_ports(AN0_an1_an3);
setup_adc(ADC_CLOCK_DIV_8);
delay_us(20);

while(1){
set_adc_channel(0); // calculer tension1
delay_ms (10);
int16 tension1 = read_adc();
set_adc_channel(1); // calculer tension2
delay_ms (10);
int16 tension2 = read_adc();
signed int16 temperature = tension1 - tension2; // mesurer la difference
lcd_gotoxy(1,1);
printf(lcd_putc,"temp= %2.1f",temperature*5.*100./1023.); // afficher la temperature
lcd_putc(223); //afficher la signe du C
printf(lcd_putc,"C   ");
}}//end void main() 

Le résultat


Simulation du circuit : PIC 16F877 + LCD + LM35 (température négative)


Simulation du circuit : PIC 16F877 + LCD + LM35 (température positive)




Conclusion


Il faut toujours penser à faire une circuit électrique qui fonctionne dans tous les conditions climatiques.

N'oublier jamais la signe "-"  pour l'unité °C !


=> Plus d'informations : imedelmottakel@gmail.com
=> https://www.facebook.com/Imed.Elmottakel






Tuesday

MPU6050 avec PIC





1. Introduction MPU6050.

MPU-6050 est le premier capteur de mouvement dans le monde a à 6 (extensible à 9) axe sentir les variables intégrées dans une seule puce.

MPU-6050 utilise une technologie brevetée d'InvenSense MotionFusion peut fonctionner sur des appareils mobiles, le contrôle de la main ... Il est géré hors une alimentation 3,3V / 5V, et communiquer à travers I2C avec une vitesse maximale de 400 kHz. Cette puce est également disponible dans un paquet appelé MPU6000 SPI pour la vitesse de communication jusqu'à 10Mbs.



*Notez également que InvenSense a combiné la MPU-6050 avec un magnétomètre (boussole) en une seule puce appelée MPU-9150 ..

Paramètres de mouvement:


-Possibilité de choisir + -2/4 / 8 / 16 g plage d'accélération
-Possibilité de choisir + -250 / 500/1000/2000 degrés / s gamme gyro
-Sortie sur 16 bits
-la sensibilité du gyroscope de l'accélérateur linéaire 0,1 / s, une énorme amélioration par rapport au gyroscope tri-axe d'autres sociétés.
-Faible niveau de bruit sur les deux sorties.
-La proportion des données de sortie jusqu'à 1000 Hz, bien que construite par un filtre passe-bas de fréquence d'angle numérique jusqu'à 256 Hz.
-3 axes gyroscope (3 axes gyroscope MEMS)
-Accéléromètre 3D 
-l'intégration des données d'un compas externe I2C.

MPU-6050 peut être combiné avec un capteur de champ magnétique (externe) pour former le capteur d'angle plein 9 via l'interface I2C.


2: "Pinout" de MPU6050:








VCC5V / 3V3
GND0V
SCLPin SCL I2C
SDA Pin SDA dans l'interface I2C
XDABroches de données (se connecter avec d'autres capteurs)
XCLImpulsion d'horloge (connecté à d'autres capteurs)
AD0Bit0 de l'adresse I2C
INTInitialiser

3: Lire les données de MPU6050:

Principe de protocole i2c:

Avec MPU6050-GY521: MCU est le maître, les capteurs esclaves
Adresse de communication:
 #define MPU6050_ADDRESS 0xD0
Transfert de données:

Exemple de code pour le transfert des données :

Obtenir les données:


Exemple de code pour la réception des données :


Tableau  I2C pour MPU6050

4: microcontrôleur de communication et bibliothèques:

Téléchargez dans le document ci-joint:

*( modifier le code selon votre besoin )



Code CCS PIC C du jeux : 
        





Pour plus d'informations : imedelmottakel@gmail.com
Merci pour le site  http://laptrinhpc.info/

Top 10 common Software Architectural Patterns

Introduction: Did you ever posed the question:  How large software in industrial scale systems are designed ? Here I'll explai...