lunedì 26 agosto 2013

Individuazione di volti con OpenCV

Sempre giocando con OpenCV e' divertente effettuare il riconoscimento automatico dei volti...una operazione di per se complessa si puo' svolgere sostanzialmente in realtime con poca potenza di calcolo

Prendendo l'esempio dei tutorial (con poche modifiche marginali) si puo' ottenere il risultato sottostante (e' stato modificato un parametro rispetto a quelli di default)

per il corretto funzionamento del programma si deve copiare il file haarcascade_frontalface_alt.xml nella directory del programma
---------------------------------------------------------
 #include "opencv2/objdetect/objdetect.hpp"
 #include "opencv2/highgui/highgui.hpp"
 #include "opencv2/imgproc/imgproc.hpp"

 #include <iostream>
 #include <stdio.h>

 using namespace std;
 using namespace cv;

 /** Function Headers */
 void detectAndDisplay( Mat frame );

 /** Global variables */
 String face_cascade_name = "haarcascade_frontalface_alt.xml";
 CascadeClassifier face_cascade;

 string window_name = "Capture - Face detection";
 RNG rng(12345);

 /** @function main */
 int main( int argc, const char** argv )
 {
   if( !face_cascade.load( face_cascade_name ) ){ printf("--(!)Error loading\n"); return -1; };
   Mat img = imread("immagine.jpg", CV_LOAD_IMAGE_UNCHANGED);
   detectAndDisplay(img); 
   waitKey(0); 
   return 0;
 }

void detectAndDisplay(Mat frame)
{
  std::vector<Rect> faces;
  Mat frame_gray;

  cvtColor( frame, frame_gray, CV_BGR2GRAY );
  equalizeHist( frame_gray, frame_gray );

  //-- Detect faces
  face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(20, 20) );

  for( int i = 0; i < faces.size(); i++ )
  {
    Point center( faces[i].x + faces[i].width*0.5, faces[i].y + faces[i].height*0.5 );
    ellipse( frame, center, Size( faces[i].width*0.5, faces[i].height*0.5), 0, 0, 360, Scalar( 255, 0, 255 ), 4, 8, 0 );
    Mat faceROI = frame_gray( faces[i] );
  }
  imshow( window_name, frame );

  vector<int> compression_params; 
  compression_params.push_back(CV_IMWRITE_JPEG_QUALITY); 
  compression_params.push_back(98);
  bool bSuccess = imwrite("elaborata2.jpg", frame, compression_params); 

 }

Motion Detection in OpenCV

sempre per fare un po' di esperienza per rendere la Raspberry un sistema di controllo video, un esempio di motion detection con OpenCV ripreso da questo link e leggermente modificato per salvare il video su disco
(il video e' accelerato)


per adesso il programma e' stato testato su un portatile. Presto provero' se Raspberry e' in grado di gestire il flusso dati video ed il relativo calcolo in realtime

--------------------------------------------
#include<opencv2/opencv.hpp>
#include<iostream>
#include<vector>

using namespace std;

int main(int argc, char *argv[])
{
    cv::Mat frame;
    cv::Mat back;
    cv::Mat fore;
    cv::VideoCapture cap(0);
    cv::BackgroundSubtractorMOG2 bg;
    bg.nmixtures = 3;
    bg.bShadowDetection = false;

    std::vector<std::vector<cv::Point> > contours;

    cv::namedWindow("Frame");


   double dWidth = cap.get(CV_CAP_PROP_FRAME_WIDTH); 
   double dHeight = cap.get(CV_CAP_PROP_FRAME_HEIGHT);
   cout << "Frame Size = " << dWidth << "x" << dHeight << endl;
   Size frameSize(static_cast<int>(dWidth), static_cast<int>(dHeight));
   VideoWriter oVideoWriter ("video.avi", CV_FOURCC('M','P','4','2'), 20, frameSize, true);
   if ( !oVideoWriter.isOpened() ) 
   {
        cout << "ERROR: Failed to write the video" << endl;
        return -1;
   }

    for(;;)
    {
        cap >> frame;
        bg.operator ()(frame,fore);
        bg.getBackgroundImage(back);
        cv::erode(fore,fore,cv::Mat());
        cv::dilate(fore,fore,cv::Mat());
        cv::findContours(fore,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE);
        cv::drawContours(frame,contours,-1,cv::Scalar(0,0,255),2);
        cv::imshow("Frame",frame);

oVideoWriter.write(frame); 

        if(cv::waitKey(30) >= 0) break;
    }
    return 0;
}

domenica 25 agosto 2013

Login automatico con GDM3

Per abilitare il login in automatico di un utente con GDM3 si editi il file
/etc/gdm3/daemon.conf


modificando le seguenti righe
-----------------------------------------
# GDM configuration storage
#
# See /usr/share/gdm/gdm.schemas for a list of available options.

[daemon]
# Enabling automatic login
  AutomaticLoginEnable = true
  AutomaticLogin = luca
------------------------------------------
e riavviando con

dpkg-reconfigure gdm3

OpenCV in C++

Per tentare in futuro di usare il riconoscimento real-time degli oggetti ho convertito lo script in Python visto in questo post in questa versione in C++

si compila, come gia' indicato, mediante

g++ `pkg-config --cflags --libs opencv` opencv.cpp -o opencv
-------------------------------------------------------------
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
#include <sstream>
#include <iomanip>
#include <stdlib.h>


using namespace cv;
using namespace std;


int msleep(unsigned long milisec)  
{  
    struct timespec req={0};  
    time_t sec=(int)(milisec/1000);  
    milisec=milisec-(sec*1000);  
    req.tv_sec=sec;  
    req.tv_nsec=milisec*1000000L;  
    while(nanosleep(&req,&req)==-1)  
        continue;  
    return 1;  
}

int main(int argc, char* argv[])
{
    VideoCapture cap(0); // open the video camera no. 0

    if (!cap.isOpened())  // if not success, exit program
    {
        cout << "Cannot open the video file" << endl;
        return -1;
    }

   double dWidth = cap.get(CV_CAP_PROP_FRAME_WIDTH); //get the width of frames of the video
   double dHeight = cap.get(CV_CAP_PROP_FRAME_HEIGHT); //get the height of frames of the video

    vector<int> compression_params;
    compression_params.push_back(CV_IMWRITE_JPEG_QUALITY); 
    compression_params.push_back(98); /
    cout << "Frame size : " << dWidth << " x " << dHeight << endl;
    namedWindow("MyVideo",CV_WINDOW_AUTOSIZE); //create a window called "MyVideo"
    int i = 0;
   while (1)
    {
        Mat frame;
i++;
        bool bSuccess = cap.read(frame);
         if (!bSuccess) 
        {
             cout << "Cannot read a frame from video file" << endl;
             break;
        }
        stringstream ss;
ss << std::setfill('0') << std::setw(5) << i;
      bool bSuccess2 = imwrite("a_"+ss.str()+".jpg", frame, compression_params); 
msleep(1000);
    }
    return 0;
}

venerdì 23 agosto 2013

Raspberry + Webcam + Python + OpenCV = Camera Car

Riprendendo l'idea precedente (e grazie alla batteria) e' possibile anche fare dei CameraCar


La webcam era posta diretta davanti al volante


in questo caso, data la velocita', avrei dovuto ridurre il tempo di ripresa tra due fotogrammi per rendere il tutto piu' fluido. Sarebbe carino aggiungere un modulo Bluetooth, un GPS bluetooth ed una antenna Wireless per crearsi un piccolo una Google Car

Raspberry + Webcam + Python + OpenCV = tramonto in TimeLapse

Per questo progettino da un giorno ho provato ad usare la Raspberry per catturare dei time lapse


La base hardware e' quella presente in foto ovvero una Raspberry, una batteria esterna da 10000 mAh per essere autonomi dalle prese di corrente ed una comune webcam Logitech C310



La Raspberry e' configurata con un indirizzo statico ed un DHCP server e SSH Server per collegarsi con un portatile ed un cavo cross in modo da poter interagire in caso di necessita' mediante portatile

Per la configurazione software per prima cosa e' necessario installare OpenCV per Python mediante

apt-get install python-opencv

lo script e' il seguente (molto banale)
------------------------------------------
import cv
import time

nome = 0
capture = cv.CaptureFromCAM(0)

while True:
nome = nome + 1
frame = cv.QueryFrame(capture)
indice = ("%04d")%nome
cv.SaveImage("/home/luca/a_"+indice+".jpg",frame)
time.sleep(20)
------------------------------------------

per mandare in esecuzione in automatico lo script e' stato modificato il file /etc/rc.local come segue aggiungendo
python /home/luca/camera.py

una volta ottenute le immagini queste sono state montate in file mpg mediante il comando
ffmpeg  -f image2 -i a_%03d.jpg tramonto.mpg


(attenzione che gli indici di ffmpeg devono iniziare da 1. Le immagini sono denominati come a_001.jpg, a_002,jpg ed a seguire)

giovedì 22 agosto 2013

OpenCV2 con Eclipse in Ubuntu

Update
-------------------------------------
altrimenti in modo piu' semplice e senza installare Eclipse
g++ `pkg-config --cflags --libs opencv` opencv.cpp -o opencv
-------------------------------------

Per utilizzare la libreria OpenCV in C++  in ambiente Eclipse si deve prima di tutto aver installato Eclipse con il plugin CDT
Successivamente si puo' installare la libreria con il comando

apt-get install libopencv-dev

A questo punto si crea un nuovo progetto C++ dal wizard di Eclipse e si configurano i puntamenti alle directory di include e lib


nell'esempio sono riportate sono alcune librerie di base di OpenCV2. Se si usano funzioni avanzate sara' necessario aggiungere le corrispondenti librerie



a questo punto si puo' compilare un semplice esempio che mostra una immagine passata come argomento dalla linea di comando

-------------------------------------------------
#include "opencv2/highgui/highgui.hpp"
#include <iostream>


using namespace cv;
using namespace std;

int main(int argc, char** argv)
{
  Mat im;
  if (argc == 2) im = imread(argv[1]);

  if (im.empty())
  {
    cout << "Cannot open image!" << endl;
    return -1;
  }
  imshow("image", im);
  waitKey(0);
  return 0;
}



Debugger integrato ESP32S3

Aggiornamento In realta' il Jtag USB funziona anche sui moduli cinesi Il problema risiede  nell'ID USB della porta Jtag. Nel modulo...