|
flavio58
|
 |
« inserita:: Febbraio 08, 2010, 03:52:30 pm » |
|
E' uscita la nuova versione di Opencv2.0 la libreria openn source dell' INTEL per la computer vision. In pratica contienen tutte le funzioni relative ai modelli matematici utilizzati in genere per creare sistemi di riconoscimento, di tracciamento, di riconoscimento oggetti, sistemi com SURF, SIFT e STARDETECTOR per l'estrazione dei keypoint invarianti alla luce, alla scalatura, alla posizione ecc. mediante i quali è possibile trovare immagini in altre immagini anche se le seconde sono state girate, piegate ecc. Alcuni esempi del passato come l'estrazione delle facce ecc. presentate su questo sito erano state fatte con opencv 1.0. Adesso la potenza è diventata veramente elevata. Prima era solo presente su Sourceforge. Ora Barnsky, uno degli sviluppatori Intel lo ha portato su un sito dedicato: http://opencv.willowgarage.com/wiki/WelcomeSe volete usarlo avrete risultati sorprendenti anche se per capire i modelli che ci stanno alla base un briciolo di katematica... Poi di fatto ci sono talmente tanti software in giro che anche solo basandosi su di l0ro potete fare cose veramente belle.
|
|
|
|
|
Registrato
|
|
|
|
|
|
|
GiovanniD
|
 |
« Risposta #2 inserita:: Febbraio 08, 2010, 05:37:51 pm » |
|
davvero interessante! 20 righe e fa face detection...è davvero interessantissimo e da provare!
|
|
|
|
|
Registrato
|
|
|
|
|
flavio58
|
 |
« Risposta #3 inserita:: Febbraio 08, 2010, 07:41:46 pm » |
|
Ilk sistema opencv2 possiede moltissimi esempi compilati da provare. Provate ad esempio il modulo find_obj Prendete una foto più grande che contiene molte cose e poi estrete uun foto più piccola con un oggetto compreso. La foto maggiore inclinatela e modificateLA, ANCHE SE NON è NECESSARIO. Poi lanciate find_obj foto_piccola.bmp foto_grande.bmp In questo caso nojn ho variato l'immagine   Dopo l'elaboorazione  qui ho ruotato l'immagine piccola e come vedi l'ha trovata ugualmente.....  I modelli matetatici presenti in opencv2 sono SURF, SIFT, STARTDETECTOR. Le zone rosse sono quelle relative ai keypoint invarianti alla luce posizione e dimsnioni.....
|
|
|
|
|
Registrato
|
|
|
|
|
flavio58
|
 |
« Risposta #4 inserita:: Febbraio 09, 2010, 09:59:13 am » |
|
Come dicevo Opencv ha dei wraPPER per altri linguaggi come il c++. Due si chiamano Emgucv e Aforge. Un esempio fatto con il primo : Riconoscimento targhe completo : using System; using System.Collections.Generic; using System.Text; using System.Drawing; using Emgu.Util; using Emgu.CV; using Emgu.CV.Structure; using tessnet2; using System.Diagnostics; namespace LicensePlateRecognition { /// <summary> /// A license plate detector /// </summary> public class LicensePlateDetector : DisposableObject { private Tesseract _ocr; /// <summary> /// Create a license plate detector /// </summary> public LicensePlateDetector() { //create OCR _ocr = new Tesseract(); //You can download more language definition data from //http://code.google.com/p/tesseract-ocr/downloads/list //Languages supported includes: //Dutch, Spanish, German, Italian, French and English _ocr.Init("eng", false); } /// <summary> /// Detect license plate from the given image /// </summary> /// <param name="img">The image to search license plate from</param> /// <param name="licensePlateList">A list of images where the detected license plate region is stored</param> /// <param name="filteredLicensePlateList">A list of images where the detected license plate region with noise removed is stored</param> /// <param name="boxList">A list where the region of license plate, defined by an MCvBox2D is stored</param> /// <returns>The list of words for each license plate</returns> public List<List<Word>> DetectLicensePlate(Image<Bgr, byte> img, List<Image<Gray, Byte>> licensePlateList, List<Image<Gray, Byte>> filteredLicensePlateList, List<MCvBox2D> boxList) { //Stopwatch w = Stopwatch.StartNew(); List<List<Word>> licenses = new List<List<Word>>(); using (Image<Gray, byte> gray = img.Convert<Gray, Byte>()) using (Image<Gray, Byte> canny = new Image<Gray, byte>(gray.Size)) using (MemStorage stor = new MemStorage()) { CvInvoke.cvCanny(gray, canny, 100, 50, 3); Contour<Point> contours = canny.FindContours( Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_TREE, stor); FindLicensePlate(contours, gray, canny, licensePlateList, filteredLicensePlateList, boxList, licenses); } //w.Stop(); return licenses; } private void FindLicensePlate( Contour<Point> contours, Image<Gray, Byte> gray, Image<Gray, Byte> canny, List<Image<Gray, Byte>> licensePlateList, List<Image<Gray, Byte>> filteredLicensePlateList, List<MCvBox2D> boxList, List<List<Word>> licenses) { for (; contours != null; contours = contours.HNext) { Contour<Point> approxContour = contours.ApproxPoly(contours.Perimeter * 0.05, contours.Storage); if (approxContour.Area > 100 && approxContour.Total == 4) { //img.Draw(contours, new Bgr(Color.Red), 1); if (!IsParallelogram(approxContour.ToArray())) { Contour<Point> child = contours.VNext; if (child != null) FindLicensePlate(child, gray, canny, licensePlateList, filteredLicensePlateList, boxList, licenses); continue; } MCvBox2D box = approxContour.GetMinAreaRect(); double whRatio = (double)box.size.Width / box.size.Height; if (!(3.0 < whRatio && whRatio < 8.0)) { Contour<Point> child = contours.VNext; if (child != null) FindLicensePlate(child, gray, canny, licensePlateList, filteredLicensePlateList, boxList, licenses); continue; } Image<Gray, Byte> plate = gray.Copy(box); Image<Gray, Byte> filteredPlate = FilterPlate(plate); List<Word> words; using (Bitmap bmp = filteredPlate.Bitmap) words = _ocr.DoOCR(bmp, filteredPlate.ROI); licenses.Add(words); licensePlateList.Add(plate); filteredLicensePlateList.Add(filteredPlate); boxList.Add(box); } } } /// <summary> /// Check if the four points forms a parallelogram /// </summary> /// <param name="pts">The four points that defines a polygon</param> /// <returns>True if the four points defines a parallelogram</returns> private static bool IsParallelogram(Point[] pts) { LineSegment2D[] edges = PointCollection.PolyLine(pts, true); double diff1 = Math.Abs(edges[0].Length - edges[2].Length); double diff2 = Math.Abs(edges[1].Length - edges[3].Length); if (diff1 / edges[0].Length <= 0.05 && diff1 / edges[2].Length <= 0.05 && diff2 / edges[1].Length <= 0.05 && diff2 / edges[3].Length <= 0.05) { return true; } return false; } /// <summary> /// Filter the license plate to remove noise /// </summary> /// <param name="plate">The license plate image</param> /// <returns>License plate image without the noise</returns> private static Image<Gray, Byte> FilterPlate(Image<Gray, Byte> plate) { Image<Gray, Byte> thresh = plate.ThresholdBinaryInv(new Gray(120), new Gray(255)); using (Image<Gray, Byte> plateMask = new Image<Gray, byte>(plate.Size)) using (Image<Gray, Byte> plateCanny = plate.Canny(new Gray(100), new Gray(50))) using (MemStorage stor = new MemStorage()) { plateMask.SetValue(255.0); for ( Contour<Point> contours = plateCanny.FindContours( Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_EXTERNAL, stor); contours != null; contours = contours.HNext) { Rectangle rect = contours.BoundingRectangle; if (rect.Height > (plate.Height >> 1)) { rect.X -= 1; rect.Y -= 1; rect.Width += 2; rect.Height += 2; rect.Intersect(plate.ROI); plateMask.Draw(rect, new Gray(0.0), -1); } } thresh.SetValue(0, plateMask); } thresh._Erode(1); thresh._Dilate(1); return thresh; } protected override void DisposeObject() { _ocr.Dispose(); } } } Ilo sistema usa come oCR l'open source tesseract http://code.google.com/p/tesseract-ocr/
|
|
|
|
|
Registrato
|
|
|
|
|
flavio58
|
 |
« Risposta #5 inserita:: Febbraio 09, 2010, 10:54:18 am » |
|
Inoltre c'è da considerare una cosa. Dal punto di vista del modello matematico un immagine viene vista come un segnale qualsiasi come potrebbe esserlo uno audio o un uno proveniente da qualche device che riproduce interfacce sensoriali. Modelli matematici come gli hmm (hidden markov modell) permettono di riconoscere facce oppure il parlato, allo stesswo modeo. Opencv si basa su una librreria 'spaziale' che si chiama IPP (Intel Performance Primitive) le quali permettono lo streamline digital media e le applicazioni di data-processing. Le funzioni sono centinaia per cui esssendoci i sorgenti di opencv è possibile implementare funzioni di trattamento immagini, suooni, video ecc. di qualsiasi tipo.
Io oso definire che certi software sono la porta per il terzo livello dell'informatica.
iL PRIMO ERA QUELLO CHE PERMETTTEVA DI AVERE SEMPLICI RISULTATI DAI PROGRAMMI SENZA TANTE FACILIUTAZIONI NEL RAPPPPORTO TRA MACCHINA E UTENTE.
IL SECONDO LIVELLLO E QUELLO CHE GRAZIE A UI SOFFISTICATE IL RAPPORTO TRA MACCHINA E UOMO E' STATA NOTEVOLMENTE SEMPLIFICATA E LE FUNZIONI RIDOTTO LA QUANTTITA' DI DATI CHE DOVEVANO ESSEE INSERITI
IL TERZO LIVELLO E' QUELLO IN CUI MODELLI MATEMATICI CHE PRIMA ERANO SOLO PRESENTI DOVE SI FAVCEVA RICERCA SONO ENTTRATI NELL'USO COMUNE PERMETTENDO DI SCRIVERE PROGGRAMMI INTELLIGIENTI E QUINDI IN GRAN PARTE EVITARE LA PRESENZA DELL'UOMO PER GESTIRE CERTE FUNZIONALITA'.
PER DIRE UNA COSA IO CON POCA FATICA MI SONO CRREATO UNA SPECIE DI CRUSCOTTO, GESTITO SU UN PC PORTATILE DOVE ANCHE DI NOTTE MI VENGONO NSEGNALATE MACCCHINE DAVANTI A ME, MACCHINE CHE FRENANO, PERSONE, FARI DI MACCHINA IN SENSO CONTRARIO ED IN PIU DI GIORNO MI VIENE FATTA VEDERE LA STRADA . QUEST'ULTIMA FUNZIONE E' UNA DI QUELLE CHE GENTE COME BRANSKY (UNO DEI GESTORI DEL PROGETTO OPENCV) UTILIZZA PER LA CREAZIONE DI QUELLE VETTURE CHE VANNO SENZA GUIDATORE E CON LE QUALI GESTISCOONO QUELLE GARE IN CUI LE MACCHINE DEVONO ANDARE DA ... A SENZA NESSUNA GUIDA.
|
|
|
|
|
Registrato
|
|
|
|
|
flavio58
|
 |
« Risposta #6 inserita:: Febbraio 09, 2010, 02:06:51 pm » |
|
Come avevo detto Opencv2.0 è il cuore di tutti i wrapper come EMGUCV per il C# e Aforge.NET per bil C# Tutti dispongono della potenza di opencv ma in più possiedono facilitazioni fuunzionali . Ad esempio l'esempio find_obj, quello della targa è basato su : due letture immagini due ricerche sulle immagiini dei keypoint tramite la funzione SURF una ricerca dei punti comuni dentro ai file di dati restituiti dALLE FUN<ZIONI SURF // lETTTURE FILE IplImage* object = cvLoadImage( object_filename, CV_LOAD_IMAGE_GRAYSCALE ); IplImage* image = cvLoadImage( scene_filename, CV_LOAD_IMAGE_GRAYSCALE ); CvSeq *objectKeypoints = 0, *objectDescriptors = 0; CvSeq *imageKeypoints = 0, *imageDescriptors = 0; int i; CvSURFParams params = cvSURFParams(500, 1); // eSTRARRZIONE surf KEYPOINT cvExtractSURF( object, 0, &objectKeypoints, &objectDescriptors, storage, params ); cvExtractSURF( image, 0, &imageKeypoints, &imageDescriptors, storage, params ); //rICERCA PUNTI COMUNI #ifdef USE_FLANN flannFindPairs( objectKeypoints, objectDescriptors, imageKeypoints, imageDescriptors, ptpairs ); #else findPairs( objectKeypoints, objectDescriptors, imageKeypoints, imageDescriptors, ptpairs ); #endif
// uSO DEI DATI (DISEGNO LINEE ECC.)
for( i = 0; i < (int)ptpairs.size(); i += 2 ) { CvSURFPoint* r1 = (CvSURFPoint*)cvGetSeqElem( objectKeypoints, ptpairs[i] ); CvSURFPoint* r2 = (CvSURFPoint*)cvGetSeqElem( imageKeypoints, ptpairs[i+1] ); .... ....
qUESTA è SOLOO UNA PARTE DEL SOURCE OPENCV2 Lo stresso fatto com EmguCV è questo: using System; using System.Collections.Generic; using System.Windows.Forms; using System.Drawing; using Emgu.CV; using Emgu.CV.UI; using Emgu.CV.CvEnum; using Emgu.CV.Structure; namespace SURFFeatureExample { static class Program { /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Run(); } static void Run() { MCvSURFParams surfParam = new MCvSURFParams(500, false); Image<Gray, Byte> modelImage = new Image<Gray, byte>("box.png"); //extract features from the object image SURFFeature[] modelFeatures = modelImage.ExtractSURF(ref surfParam); Image<Gray, Byte> observedImage = new Image<Gray, byte>("box_in_scene.png"); // extract features from the observed image SURFFeature[] imageFeatures = observedImage.ExtractSURF(ref surfParam); //Create a SURF Tracker using k-d Tree SURFTracker tracker = new SURFTracker(modelFeatures); //Comment out above and uncomment below if you wish to use spill-tree instead //SURFTracker tracker = new SURFTracker(modelFeatures, 50, .7, .1); SURFTracker.MatchedSURFFeature[] matchedFeatures = tracker.MatchFeature(imageFeatures, 2, 20); matchedFeatures = SURFTracker.VoteForUniqueness(matchedFeatures, 0.8); matchedFeatures = SURFTracker.VoteForSizeAndOrientation(matchedFeatures, 1.5, 20); HomographyMatrix homography = SURFTracker.GetHomographyMatrixFromMatchedFeatures(matchedFeatures); //Merge the object image and the observed image into one image for display Image<Gray, Byte> res = modelImage.ConcateVertical(observedImage); #region draw lines between the matched features foreach (SURFTracker.MatchedSURFFeature matchedFeature in matchedFeatures) { PointF p = matchedFeature.ObservedFeature.Point.pt; p.Y += modelImage.Height; res.Draw(new LineSegment2DF(matchedFeature.ModelFeatures[0].Point.pt, p), new Gray(0), 1); } #endregion #region draw the project region on the image if (homography != null) { //draw a rectangle along the projected model Rectangle rect = modelImage.ROI; PointF[] pts = new PointF[] { new PointF(rect.Left, rect.Bottom), new PointF(rect.Right, rect.Bottom), new PointF(rect.Right, rect.Top), new PointF(rect.Left, rect.Top)}; homography.ProjectPoints(pts); for (int i = 0; i < pts.Length; i++) pts[i].Y += modelImage.Height; res.DrawPolyline(Array.ConvertAll<PointF, Point>(pts, Point.Round), true, new Gray(255.0), 5); } #endregion ImageViewer.Show(res); } } } 
|
|
|
|
|
Registrato
|
|
|
|
|
flavio58
|
 |
« Risposta #7 inserita:: Febbraio 09, 2010, 02:19:00 pm » |
|
Aforge.net posssiede queste classi * AForge.Imaging - library with image processing routines and filters; * AForge.Vision - computer vision library; * AForge.Video - set of libraries for video processing; * AForge.Neuro - neural networks computation library; * AForge.Genetic - evolution programming library; * AForge.Robotics - library providing support of some robotics kits; * AForge.MachineLearning - machine learning library. Ogni classe contiene un infinita di metodi, parametri ecc. cjhe gli permetteono di fare quello che fa opencv ma molto semplicemente. Anche qui si tratta di c#. Ad esempio qui ci sono alcuni esempi http://www.aforgenet.com/framework/samples/http://www.aforgenet.com/
|
|
|
|
|
Registrato
|
|
|
|
|
Redazione
|
 |
« Risposta #8 inserita:: Febbraio 10, 2010, 03:42:20 pm » |
|
Chi si offre per scrivere un articoletto in merito a OpenCV 2.0 su ioProgrammo?
|
|
|
|
|
Registrato
|
|
|
|
|
IndieAlex
|
 |
« Risposta #9 inserita:: Febbraio 10, 2010, 04:18:01 pm » |
|
sarebbe interessante scrivere qualcosa con EmguCV... per dare la possibilità a persone che usano linguaggi diversi da C e C++ di leggere lo stesso articolo senza problemi... e anche per quelli come me che usano mono visto che EmguCV lo supporta.
|
|
|
|
|
Registrato
|
|
|
|
|
flavio58
|
 |
« Risposta #10 inserita:: Febbraio 10, 2010, 06:04:34 pm » |
|
Emgucv com Aforge.net non sono altroo che wrapppe opencv e a questo punto eesendo appena uscito opencv2 non so quanto sia aggiornato. Le funzioni chhe ho riportato erano già presenti iin opencv preecedente. Non pensiate che il riconoscimento targhe sia unja funzionalità di Emgucv ma di fatto questo viene fatto segeundo una serie di funzioni , le prime per identificare la zona traga, le altre per fare l'ocr. Come puoi discutere un wrapper che si basa su uuna libreria senza discutere della libreria.
|
|
|
|
|
Registrato
|
|
|
|
|
IndieAlex
|
 |
« Risposta #11 inserita:: Febbraio 10, 2010, 06:23:17 pm » |
|
flavio, ho solo detto che sarebbe bello scrivere qualcosa usando un wrapper .net così da rendere il codice comprensibile e facilmente riutilizzabile da più persone. non credo che l'uso di un wrapper negi la possibilità di parlare del funzionamento generale della libreria principale. Comunque EmguCV, che poi è anche il wrapper migliore, supporta l'ultima versione di OpenCV 2009-10-25 Emgu.CV-2.0.1.0 is available in sourceforge. Welcome to the first .NET wrapper that is compatible with OpenCV 2.0!
|
|
|
|
|
Registrato
|
|
|
|
|
flavio58
|
 |
« Risposta #12 inserita:: Marzo 03, 2010, 01:06:05 pm » |
|
No. Il problema dell'opencv permette però di vedere alla luce del C e del C++ la cosa. Vederla alla luce de C# significa che spesso le clessi possono contenere metodi che sono composti da piu' funzioni di opencv. Infatti vedi gli esempi di prima. Il codice è ristretto in quanto spesso alcune funzioni sono composte....
|
|
|
|
|
Registrato
|
|
|
|
|
flavio58
|
 |
« Risposta #13 inserita:: Maggio 10, 2010, 01:40:35 pm » |
|
Questo è il codice dell'esempio dato con OPENCV a riguardo di HOG #include "cvaux.h" #include "highgui.h"
int main(int argc, char** argv) { cv::Mat img;
if( argc > 1 ) img = cv::imread(argv[1]);
if( !img.data ) { fprintf( stderr, argc == 1 ? "ERROR: no image was specified\n" : "ERROR: the specified image could not be loaded\n"); fprintf( stderr, "Usage: peopledetect <inputimage>\n" ); return -1; }
cv::HOGDescriptor hog; hog.setSVMDetector(cv::HOGDescriptor::getDefaultPeopleDetector()); cv::vector<cv::Rect> found; double t = (double)cv::getTickCount(); // run the detector with default parameters. to get a higher hit-rate // (and more false alarms, respectively), decrease the hitThreshold and // groupThreshold (set groupThreshold to 0 to turn off the grouping completely). hog.detectMultiScale(img, found, 0, cv::Size(8,8), cv::Size(24,16), 1.05, 2); t = (double)cv::getTickCount() - t; printf("Detection time = %gms\n", t*1000./cv::getTickFrequency()); for( int i = 0; i < (int)found.size(); i++ ) { cv::Rect r = found[i]; // the HOG detector returns slightly larger rectangles than the real objects. // so we slightly shrink the rectangles to get a nicer output. r.x += cvRound(r.width*0.1); r.y += cvRound(r.height*0.1); r.width = cvRound(r.width*0.8); r.height = cvRound(r.height*0.8); cv::rectangle(img, r.tl(), r.br(), cv::Scalar(0,255,0), 1); } cv::namedWindow("people detector", 1); cv::imshow("people detector", img); cv::waitKey(0); return 0; } 
|
|
|
|
|
Registrato
|
|
|
|
|
flavio58
|
 |
« Risposta #14 inserita:: Maggio 12, 2010, 01:24:39 pm » |
|
Non voglio fare spam verso il mio sito ma dato che opencv non cambia più versione ogni anno come faveva prima ma ogni giorno vi3ene corretta, viene aggiunta qualche funzionalità, il manuale viene cambiato ecc. vi consaiglio, se vi interessa non perdere tempo con funzioni che erano con bug ma adesso corrette ..... beh.... date un occhiata qui : http://www.bernardotti.it/portal/showthread.php?goto=newpost&t=409007
|
|
|
|
|
Registrato
|
|
|
|
|