martedì 27 agosto 2013

Motion Detection su Raspberry

Per valutare la potenza di calcolo di Raspberry per un eventuale sistema di controllo, ho ricompilato il programma presentato in questo post modificandolo leggermente (non volevo usare il monitor ma solo una connessione di rete via SSH per interagire con la Raspberry) eliminando il namedWindow

Per compilare il programma non ci sono problemi in quanto le libopencv-dev sono disponibili nei repository senza la necessita' di ricompilare da zero le OpenCV

Il sistema ha funzionato bene



anche se in alcuni casi vi sono artefatti



ecco il video completo



Fauna caldinese

Ribaltato giusto davanti al portone di casa, gentilmente accompagnato in un prato



Errore stray ‘\342’ in program

copiando un mio sorgente direttamente da questo blog e compilandolo su un'altra macchina e' comparso l'errore

 error: stray ‘\342’ in program

ovviamente non si tratta di un errore del programma dato che funziona su un'altra macchina
in realta' nella fase di copia incolla dal browser verso il text editor sono stati copiati dei codici UNICODE e non ASCII per cui, per esempio, quelle che io vedo come virgolette il calcolatore non le vede come tali e blocca la compilazione

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;
}

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...