Planul de recunoaștere a obiectelor afișat în opencv python. Vizualizare computer pe openCV

Planul de recunoaștere a obiectelor afișat în opencv python. Vizualizare computer pe openCV

Ei bine, practic, trebuie să arăți cola. Ai descărcat cvHoughCircles()? Este permis să tse vikoristuvati?

Pe partea asta găna informații despre cum să generați discursuri pentru ajutor OpenCV. Ați putea fi interesat de secțiunea 2.5.

Aceasta este o mică demonstrație, așa cum am scris cu atenție pentru a afla monedele din această imagine. Sper că puteți folosi o parte din cod pentru a se potrivi propriilor interese.

Log in :

Vihodi :

// compilat cu: g++ circles.cpp -o circles `pkg-config --cflags --libs opencv` #include #include #include #include int main(int argc, char** argv) ( IplImage* img = NULL; if ((img = cvLoadImage(argv))== 0) ( printf("cvLoadImage a eșuat\n"); ) IplImage* grey = cvCreateImage( cvGetSize(img), IPL_DEPTH_8U, 1), CvMemStorage* stocare = cvCreateMemStorage(0); , CV_GAUSSIAN, 7, 7), IplImage* canny = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U,1); 3);CvSeq* cercuri = cvHoughCircles(gri, stocare;< circles->total; i++) (// float float int float* p = (float*)cvGetSeqElem( cercuri, i); cv::Point center(cvRound(p), cvRound(p)); int radius = cvRound(p) // desen centrul cercului cvCircle(rgbcanny, center, 3, CV_RGB(0,255,0), -1, 8, 0); // desenează conturul cercului cvCircle(rgbcanny, center, radius+1, CV_RGB(0, 0,255), 2 , 8, 0); cvShowImage(„cercuri”, rgbcanny); cvSaveImage(„out.png”, rgbcanny); cvWaitKey(0); return 0; )

Manifestările cercului se află în mare măsură în parametrii cvHoughCircles() . Vă rugăm să rețineți că în această demonstrație sunt și un învingător Canny.

Sunt vinovat de codificarea detectorului de obiecte (la la acest tip geantă) pentru mai mult ajutor OpenCV. Problema este că căutarea pe piele de la Google se bazează pe DETECȚIA FEȚEI. De aceea am nevoie de ajutor cu ce să încep, cu ce să încep etc.

Informații despre melodie:

  • Mingea nu are o culoare fixă, dar probabil va fi albă, dar se poate schimba.
  • Sunt vinovat de vikorystvuvaty machine learning, nefiind neapărat pliabil și de încredere, propunerea KNN (este din ce în ce mai simplă).
  • După toate căutările mele, am descoperit că calculul histogramelor ochilor corpului și începutul lui ML poate fi maro, dar principala mea preocupare aici este că dimensiunea corpului se poate schimba (mai aproape și mai departe de camera) și nu înțeleg ce trece ML să clasific pentru mine, respect... nu pot (dar pot?) pur și simplu verific pixelul pielii imaginii pentru dimensiunea posibilă a pielii (să zicem, 5x5 la WxH ) și sperăm să găsiți un rezultat pozitiv.
  • Poate exista o lume neuniformă acolo, de exemplu, oameni, țesătură în spatele mingii etc.
  • După cum am spus deja, sunt vinovat de vikorizarea algoritmului ML, ceea ce înseamnă prezența algoritmilor Haar și Violi.
  • În plus, mă gândeam la vicorizarea contururilor, pentru a cunoaște cola în imaginea lui Canny"ed, trebuie doar să știu o modalitate de a transforma conturul într-un rând de date pentru a porni KNN.

    Oz... rechennya?

    În spatele scenelor. ;)

Cele mai importante informații despre lumina externă pentru robot sunt senzorii optici și camerele sale. După capturarea imaginii, este necesară o prelucrare ulterioară pentru a analiza situația sau a lua o decizie. După cum am spus mai devreme, steaua computerului introduce metode nedureroase de lucru cu imagini. Când robotul funcționează, informațiile video de la camere sunt transferate și procesate de programul care rulează pe controler. În loc să scrieți cod de la zero, puteți utiliza rapid soluții software gata făcute. În acest moment, există o serie de biblioteci de computere gata făcute:

  • Biblioteca de imagini Matrox
  • Biblioteca Camellia
  • Deschideți eVision
  • HALCON
  • libCVD
  • OpenCV
  • etc…
Aceste SDK-uri pot fi supuse unor diferențe de funcționalitate, licențiere și limbaje de programare. Raportăm înapoi la OpenCV. Este gratuit atât pentru scopurile inițiale, cât și pentru vikoristannya comercială. Scris în C/C++ optimizat, acceptă interfețe C, C++, Python, Java și include implementări a peste 2500 de algoritmi. Cremă funcții standard Procesarea imaginii (filtrare, reeșantionare, transformare geometrică etc.) SDK-ul vă permite să creați setări complexe care indică prezența unui obiect într-o fotografie și „recunoașterea” acestuia. Este clar că detectarea și recunoașterea inițială pot fi foarte diferite:
  • căutarea și recunoașterea unui obiect specific,
  • căutarea obiectelor dintr-o categorie (fără recunoaștere),
  • doar recunoașterea obiectului (deja imagine gata cu el).
Pentru a identifica semnul din imagine și a verifica dacă există erori, OpenCV are următoarele metode:
  • Histogram of Oriented Gradients HOG (Histogram of Oriented Gradients) poate fi compilată pentru a identifica pietonii
  • Algoritmul Violi-Jones – stagnare pentru o căutare specială
  • Algoritm pentru identificarea semnului SIFT (Scale Invariant Feature Transform).
  • Algoritm pentru identificarea semnului SURF (Speeded Up Robust Features).
De exemplu, SIFT dezvăluie un set de puncte care pot fi selectate pentru un anumit obiect. Pe lângă îndrumarea tehnicilor în OpenCV, există și alți algoritmi de detectare și recunoaștere, precum și un set de algoritmi care sunt îmbunătățiți de mașină, cum ar fi metoda k-nearest neighbors, măsuri neuronale, suport vector machines etc. Cea mai importantă sarcină pentru supravegherea computerizată. Deoarece algoritmul nu este disponibil în SDK, atunci, de regulă, poate fi programat fără probleme. În plus, nu există versiuni proprietare ale algoritmilor scrise de dezvoltatori pe baza OpenCV. De asemenea, rețineți ce Pe lângă stâncile rămase OpenCV s-a extins foarte mult și a devenit incredibil de important. În legătură cu aceste diferite grupuri de entuziaști, sunt create biblioteci „ușoare”, bazate pe OpenCV. Aplica: SimpleCV, liuliu ccv, tinycv... Site-uri Korisny
  1. http://opencv.org/ - Site-ul web principal al proiectului
  2. http://opencv.willowgarage.com/wiki/ - Vechi site de proiect cu documentație pentru versiunile vechi

Acest articol are o interfață C++, FREAK și detectarea obiectelor impersonale. Fiabilitatea detectării obiectelor folosind FREAK este mai mică decât SURF, acest robot este bogat superior, ceea ce vă permite să utilizați algoritmul pe sisteme mobile și desktop. Reprezentarea robotului cu fundul micuțului:

Hai să aruncăm o privire codul de ieșire ceea ce permite cuiva atingerea. Codul este postat aici, astfel încât să îl puteți introduce în proiect.
#include #include #include #include #include #include #include #include keypointsImageTemple, keypointsImage; Mat descriptoriImagineTemplu, descriptoriImagine; std::vector chibrituri; // Inițializarea clasei detector de caracteristici, 1000 - valoare de prag pentru adăugarea // caracteristici nesemnificative SurfFeatureDetector detector(1000); //Clasă pentru caracteristicile FREAK. Puteți configura moduri și nivelarea caracteristicilor: // FREAK extractor(true, true, 22, 4, std::vector potrivire; // Detectare dublu t = (dublu) getTickCount (); detector.detect(ImageTemple, keypointsImageTemple); detector.detect(Imagine, puncte cheieImagine); t = ((dublu)getTickCount() - t)/getTickFrequency(); std::cout<< "detection time [s]: " << t/1.0 << std::endl; // Извлечение особенностей t = (double)getTickCount(); extractor.compute(ImageTemple, keypointsImageTemple, descriptorsImageTemple); extractor.compute(Image, keypointsImage, descriptorsImage); t = ((double)getTickCount() - t)/getTickFrequency(); std::cout << "extraction time [s]: " << t << std::endl; // Сравнение t = (double)getTickCount(); matcher.match(descriptorsImageTemple, descriptorsImage, matches); t = ((double)getTickCount() - t)/getTickFrequency(); std::cout << "matching time [s]: " << t << std::endl; // Отобразить на изображении Mat imgMatch; drawMatches(ImageTemple, keypointsImageTemple, Image, keypointsImage, matches, imgMatch); imwrite("matches.jpeg", imgMatch); std::vectorObj; std::vector Scenă; for(int i = 0; i< matches.size(); i++) { obj.push_back(keypointsImageTemple[ matches[i].queryIdx ].pt); scene.push_back(keypointsImage[ matches[i].trainIdx ].pt); } Mat H = findHomography(obj, scene, CV_RANSAC); std::vector colțuri_scenă(4); perspectiveTransform(colțuri_obj, colțuri_scenă, H); //-- Desenați linii între colțuri (obiect mapat în scenă - imagine_2) line(imgMatch, scene_corners + Point2f(ImageTemple.cols, 0), scene_corners + Point2f(ImageTemple.cols, 0), Scalar(0 , 0) , 4); line(imgMatch, colțuri_scenă + Point2f(ImageTemple.cols, 0), colț_scenă + Point2f(ImageTemple.cols, 0), Scalar(0, 255, 0), 4); line(imgMatch, colțuri_scenă + Point2f(ImageTemple.cols, 0), colț_scenă + Point2f(ImageTemple.cols, 0), Scalar(0, 255, 0), 4); line(imgMatch, colțuri_scenă + Point2f(ImageTemple.cols, 0), colț_scenă + Point2f(ImageTemple.cols, 0), Scalar(0, 255, 0), 4); imwrite("match3.jpeg", imgMatch); întoarce 0; )

Pentru orice caracteristică OpenCV, este necesar să inițializați clasa SurfFeatureDetector. Prima acțiune după diferite inițializari este detectarea caracteristicilor detector.detect pentru imaginea de referință și imaginea scenei. Prin urmare, pentru imaginile pielii, rezultatele detectorului robotic sunt calculate folosind FREAK: extractor.compute.
Asemănarea caracteristicilor poate fi verificată folosind matchr.match.
Urmează un ciclu de puncte de turnare cu caracteristici pentru ambele imagini. Pe baza punctelor se calculează omografia imaginii findHomography. Poziția și rotația obiectului sunt calculate folosind o funcție suplimentară de transformare a perspectivei. Ei bine, atunci să ne uităm la imagini.
Imagine de referință:

Imaginea scenei:


Rezultatul prezentărilor pe cob.
Totuși, nutriția este de vină aici, deoarece este necesar să se obțină pragul optim de caracteristici: detector SurfFeatureDetector(1000);. Răspunsul este experimental. Puteți sări peste toate informațiile din această dietă.
Să presupunem că avem câteva obiecte în imagine:


Rezultatul programului robotic va fi:


Este important ca această situație să nu fie una bună. Pentru a detecta toate obiectele, este necesar să împărțiți imaginile în mai multe părți. Cu toate acestea, iată o reamintire că, dacă împărțiți imaginile în blocuri care nu se deplasează (de exemplu, o imagine de 100x100 este împărțită în 4 blocuri de 50x50 fiecare), atunci situația poate apărea dacă obiectul este adesea situat în mai multe blocuri și nu vor exista detectii. Pentru a obține această unicitate, este necesar să se lucreze la blocurile care se zdrobesc pentru a oferi robotului mai multă flexibilitate, dar și să picteze vopseaua (exemplul unei imagini de 100x100 este împărțit în 9 blocuri de 50x50 fiecare, așa cum se arată în aplicația). Programul de aplicație detectează mai jos obiecte non-personale:
#include #include #include #include #include #include #include #include folosind cv spatiu de nume; int main(int argc, char** argv) ( if(argc != 3) return 1; Mat ImageTemple = imread(argv, CV_LOAD_IMAGE_GRAYSCALE); if(!ImageTemple.data) return 2; // Parse Mat Image = imread( argv, CV_LOAD_IMAGE_GRAYSCALE), if(!Image.data) return 3; // Măcinare std::vector puncte cheieImageTemple; Mat descriptorsImageTemple; std::vector chibrituri; // Inițializarea clasei detector de caracteristici, 1000 - valoare de prag pentru adăugarea // caracteristici nesemnificative SurfFeatureDetector detector(1000); detector.detect(ImageTemple, keypointsImageTemple); int maxy = 3; int maxx = 3; Mat Draw_mat = imread(argv, 1); for(int y = 0; y< maxy; y++) for(int x = 0; x < maxx; x++) { // Класс для FREAK особенностей. Можно настраивать режимы сравнения особенностей: // FREAK extractor(true, true, 22, 4, std::vector()); extractor FREAK; // Folosit pentru a evita particularitățile - lumea Hamming BruteForceMatcher potrivire; std::vector puncte cheieImagine; Mat descriptorsImagine; CvRect Rect = cvRect(x * (Imagine.cols / (maxx + 1)), y * (Imagine.rânduri / (maxy + 1)), 2 * (Imagine.cols / (maxx + 1)), 2 * ( Imagine.rânduri/(maxy + 1))); Mat ImageROI (Imagine, Rect); detector.detect(ImageROI, keypointsImage); extractor.compute(ImageTemple, puncte cheieImageTemple, descriptoriImageTemple); extractor.compute(ImageROI, keypointsImage, descriptorsImage); matchr.match(descriptorsImageTemple, descriptorsImage, potriviri); // Introduceți valorile necesare pentru (int i = 0; i< matches.size(); i++) { if(matches[i].distance >150) ( matchs.erase (matches.begin() + i); ) ) std::vector Obj; std::vector Scenă; for(int i = 0; i< matches.size(); i++) { obj.push_back(keypointsImageTemple[ matches[i].queryIdx ].pt); scene.push_back(keypointsImage[ matches[i].trainIdx ].pt); } Mat H = findHomography(obj, scene, CV_RANSAC); std::vectorcolțuri_obj(4); obj_corners = cvPoint(0,0); obj_corners = cvPoint(ImageTemple.cols, 0); obj_corners = cvPoint(ImageTemple.cols, ImageTemple.rows); obj_corners = cvPoint(0, ImageTemple.rows); std::vector colțuri_scenă(4); perspectiveTransform(colțuri_obj, colțuri_scenă, H); //-- Desenați linii între colțuri (obiect mapat în scenă - imagine_2) line(Draw_mat, scene_corners + Point2f(x * (Imagine.cols / (maxx + 1))), y * (Imagine.rânduri / (maxy) + 1))), scene_corners + Point2f(x * (Image.cols / (maxx + 1)), y * (Image.rows / (maxy + 1))), Scalar (0, 255, 0), 4) ; line(Draw_mat, scene_corners + Point2f(x * (Imagine.cols / (maxx + 1)), y * (Imagine.rânduri / (maxy + 1)))), scene_corners + Point2f (x * (Imagine.cols / ( maxx + 1)), y * (Imagine.rânduri / (maxy + 1))), Scalar (0, 255, 0), 4); line(Draw_mat, scene_corners + Point2f(x * (Imagine.cols / (maxx + 1)), y * (Imagine.rânduri / (maxy + 1)))), scene_corners + Point2f (x * (Imagine.cols / ( maxx + 1)), y * (Imagine.rânduri / (maxy + 1))), Scalar (0, 255, 0), 4); line(Draw_mat, scene_corners + Point2f(x * (Imagine.cols / (maxx + 1)), y * (Imagine.rânduri / (maxy + 1)))), scene_corners + Point2f (x * (Imagine.cols / ( maxx + 1)), y * (Imagine.rânduri / (maxy + 1))), Scalar (0, 255, 0), 4); ) imwrite("draw_mat.jpeg", Draw_mat); întoarce 0; )

Rezultatul atacurilor robotice:


Evident, toate obiectele au fost detectate. Mai mult, faptele sunt două (prin cele care au consumat până la două blocuri).

În acest articol veți învăța cum să creați un script Python pentru a imprima mai multe cărți în imagine folosind OpenCV.

Ce vom face?

Să aruncăm o privire la imaginea cărții:

Important este ca în imagine să apară mai multe cărți, precum și discursuri care încântă, precum o ceașcă de cafea, o ceașcă de Starbucks, un castron cu magneți și o ventuză.

Scopul nostru este să identificăm cărțile din imagine, fără a identifica niciun alt obiect ca carte.

Ce fel de biblioteci avem nevoie?

Pentru a scrie un sistem de căutare și afișare a cărților în imagini, vom folosi OpenCV pentru roboți cu viziune computerizată și imagini. De asemenea, trebuie să instalăm NumPy pentru robotul OpenCV corect. Vezi ce ai în bibliotecile tale!

Căutați cărți pe imagini pentru ajutor suplimentar cu Python și OpenCV

Notă traducere Puteți observa că codul de ieșire al articolului nostru este diferit de codul din original. Autorul, desigur, a ales să instaleze bibliotecile necesare prin intermediul depozitelor. Vă propunem să folosiți pip, care este mult mai simplu. Pentru a vă asigura că nu apar erori, vă recomandăm să utilizați versiunea codului afișată în statisticile noastre.

Deschideți editorul de cod preferat, creați un fișier nou numit find_books.py și terminați:

# -*- codificare: utf-8 -*- # Importați pachetele necesare import numpy ca np import cv2 # Animați imaginile, schimbați culoarea în gri și schimbați claritatea imaginii = cv2.imread("example.jpg") gray = cv2. cvtColor(imagine, cv2.COLOR_BGR2GRAY) = cv2.GaussianBlur(gri, (3, 3), 0) cv2.imwrite("gray.jpg", gri)

Să terminăm cu importarea bibliotecii OpenCV. Captarea imaginilor de pe disc se realizează prin funcția cv2.imread. Aici pur și simplu îl selectăm de pe disc și apoi convertim schema de culori din RGB în nuanțe de gri.

De asemenea, estompăm ușor imaginile pentru a reduce zgomotul de înaltă frecvență și pentru a îmbunătăți acuratețea programelor noastre. După introducerea codului, imaginea poate arăta astfel:

Am capturat imaginile de pe disc, am transformat-o în nuanțe de gri și am zdrobit-o puțin.

Acum să observăm marginile (sau contururile) obiectelor din imagine:

# recunoaștere margini edge = cv2.Canny(gri, 10, 250) cv2.imwrite("edged.jpg", edge)

Acum imaginea noastră arată astfel:

Am găsit contururile obiectelor imagine. Cu toate acestea, după cum vedeți, aceste contururi nu sunt închise - există goluri între contururi. Pentru a introduce spații între pixelii albi ai imaginii, vom efectua operația de „închidere”:

# creați și blocați nucleul închis = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7)) închis = cv2.morphologyEx(edged, cv2.MORPH_CLOSE, kernel) cv2.imwrite("closed.jpg", clo

Acum, golurile din contururi sunt închise:

Următorul pas este de a dezvălui efectiv contururile obiectelor din imagine. În acest scop vom folosi funcția cv2.findContours:

# găsiți contururile imaginii și acoperiți un număr de cărți cnts = cv2.findContours(closed.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) total = 0

Să ne uităm la geometria cărții.

Cartea este simplă. Cutterul vertical are vârfuri chotiri. Pentru că ne uităm la contur și vedem clar că are multe vârfuri, putem presupune că este o carte și nu un alt obiect din imagine.

Pentru a verifica dacă conturul este o carte sau nu, trebuie să urmăm ciclul după conturul pielii:

# ciclu de-a lungul contururilor pentru c în cnts: # contur aproximativ (neted) peri = cv2.arcLength(c, True) approx = cv2.approxPolyDP(c, 0.02 * peri, True) # deoarece conturul are 4 vârfuri, se presupune că această carte dacă len(aproximativ) == 4: cv2.drawContours(image, , -1, (0, 255, 0), 4) total += 1

Pentru conturul pielii, calculăm perimetrul folosind cv2.arcLength , iar apoi aproximăm (netezim) conturul folosind cv2.approxPolyDP .

Motivul prin care aproximăm conturul constă în faptul că s-ar putea să nu fim un tăietor drept ideal. Din cauza zgomotului și umbrelor din fotografie, este puțin probabil ca cartea să aibă exact 4 vârfuri. Prin aproximarea conturului, identificăm această problemă.

Găsim și verificăm că conturul aproximativ are de fapt vârfuri. Deoarece este așa, desenăm un contur în jurul cărții și apoi creștem numărul de cărți.

Să încheiem acest exemplu arătând imaginile și numărul de cărți găsite:

# afișează imaginea rezultată print(„Cunosc (0) cărți în această imagine.” format(total) cv2.imwrite(„output.jpg”, imagine))

În acest stadiu, imaginea noastră arată astfel:

Să rezumam pungile

În acest articol, ați învățat să găsiți cărți în imagini, folosind metode simple de procesare a imaginilor și folosind Python și OpenCV.

Abordarea noastră se bazează pe aceasta:

  1. Incanta imaginile de pe disc si transforma-le in nuante de gri.
  2. Un pic din imagine.
  3. Opriți detectorul de margine Canny pentru a detecta obiecte din imagine.
  4. Închideți orice goluri din contururi.
  5. Aflați contururile obiectelor din imagine.
  6. Utilizați aproximarea conturului pentru a determina că conturul este un dreptunghi și, prin urmare, o carte.

Puteți descărca codul de ieșire al scriptului și imaginile care apar în acest articol.

Ideea principală constă sub forma unor legături statistice între distribuția punctelor antropometrice de identificare. Pe imaginea pielii, punctele faciale sunt numerotate la fel. Dezvoltarea lor reciprocă are ca rezultat o egalizare a caracteristicilor.

De dragul echilibrului, puteți utiliza aceeași poziție în fața camerei. Mai important pentru cineva.

Flux video îngropat de la cameră și dovezi video

#include folosind cv spatiu de nume; int main() ( // Încărcați cascada față (fișier .xml) CascadeClassifier face_cascade; face_cascade.load("haarcascade_frontalface_alt2.xml"); Mat img; VideoCapture cap(0); while (true) (​​​cap >> img; // cvtColor(img, img, CV_BGR2GRAY);// Detectează fețele std::vector chipuri; face_cascade.detectMultiScale(img, faces, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(30, 30)); // Desenați cercuri pe fețele detectate pentru (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(img, center, Size(faces[i].width*0.5, faces[i].height*0.5), 0, 0, 360, Scalar(255, 0, 255), 4, 8, 0); } imshow("Detected Face", img); waitKey(1); } return 0; }

Fișierele în cascadă se află în directorul c:\opencv\build\etc.... Puneți cascada necesară în directorul proiectului, în același loc cu fișierul de ieșire main.cpp.

Viziunea punctelor speciale de expunere

Programul se bazează pe codul C++ pentru OpenCV Facemark

#include #include #include #include #include #include #include „drawLandmarks.hpp” folosind namespace std; folosind cv spatiu de nume; folosind spațiul de nume cv::face; int main(int argc, char** argv) ( // Încărcare Face Detector CascadeClassifier faceDetector("haarcascade_frontalface_alt2.xml"); // Creați o instanță pentru Facemark Ptr facemark = FacemarkLBF::create(); // Încărcați detectorul de reper facemark->loadModel("lbfmodel.yaml"); // Configurați camera web pentru captura video VideoCapture cam(0); // Variabilă pentru stocarea cadrului video și a acestuia în tonuri de gri Cadrul Mat, gri; // Citește un cadru în timp ce (cam.read(frame)) ( // Găsește vectorul feței chipuri; // Convertiți cadrul în tonuri de gri deoarece // FaceDetector necesită o imagine în tonuri de gri. cvtColor(cadru, gri, COLOR_BGR2GRAY); // Detectează fețe faceDetector.detectMultiScale(gri, fețe); // Variabilă pentru repere. // Repere pentru o singură față este un vector de puncte // Pot exista mai multe fețe în imagine. Prin urmare, // folosim un vector de vector de puncte. vector< vector>repere; // Rulați landmark detector bool success = facemark->< faces.size(); i++) { cv::rectangle(frame, faces[i], Scalar(0, 255, 0), 3); } for (int i = 0; i < landmarks.size(); i++) { drawLandmarks(frame, landmarks[i]); /*for (size_t j = 0; j < landmarks[i].size(); j++) circle(frame, Point(landmarks[i][j].x, landmarks[i][j].y), 1, Scalar(255, 0, 0), 2);*/ } } // Display results imshow("Facial Landmark Detection", frame); // Exit loop if ESC is pressed if (waitKey(1) == 27) break; } return 0; }

Proiectul are un program, unde este fișierul main.cpp, prin plasarea fișierelor haarcascade_frontalface_alt2.xml, trage Repere.hppі lbfmodel.yaml asa cum este specificat in cod. Fișierele în cascadă se află în directorul de fișiere c:\opencv\build\etc... trage Repere.hppі lbfmodel.yamlîn arhiva Facemark_LBF.rar.

După introducerea codului, au apărut corecții prin numărul zilnic de biblioteci OpenCV 3.4.3-vc14-vc15 necesare rulării programelor. Compilând biblioteca dumneavoastră (instalați opencv_new.zip) și instalând-o în rădăcina unității C (C: opencv-new).

Acum, toate setările care au fost configurate trebuie șterse pentru opencv-new:

Configurare Vikonyu pentru Windows. Mă duc la fereastra „Modifică middleware” (butoanele Windows->Servicii->Panou de control -> Sistem și securitate -> Sistem -> Parametri suplimentari de sistem -> Mijloace serioase-> Cale -> Schimbare). La a cui fereastră fac o schimbare? C:\ opencv-new\x64\vc14\bin. Voi re-epoca Windows.

Autoritățile au proiectul Mă refer și la biblioteca opencv_new (înlocuirea lui opencv). Fereastra „Pagini de proprietate” conține următoarele informații:

  • C/C++ -> General -> Include directoare suplimentare -> C:\ opencv-new\include
  • Linker -> General -> Directoare suplimentare de bibliotecă -> C:\ opencv-new\x64\vc14\lib
  • Linker -> Intrare -> Dependențe suplimentare -> opencv_core400.lib; opencv_face400.lib; opencv_videoio400.lib; opencv_objdetect400.lib; opencv_imgproc400.lib; opencv_highgui400.lib

Când porniți programul, vedeți un mesaj ca în setările pentru proiectul Debug. Pentru lansare, lansare reușită.


Selectați un semn pentru a filtra imaginea și a recunoaște aspectul

Cadrul de puncte apare diferit în funcție de factorii obiectivi și subiectivi.

Oficialii obiectivi sunt formarea de indivizi în fața camerei.

Factori subiectivi - iluminare neuniformă sau slabă, conflict cu emoțiile, întunecarea ochilor etc. În aceste cazuri, cadrul punctual poate fi incorect, petele pot fi îndepărtate de pe individ:

Dacă intrarea video este blocată, astfel de imagini vor sări peste. Acestea trebuie filtrate atât atunci când sunt pornite, cât și când sunt recunoscute.

Acțiunile din punct de vedere sunt cele mai stabile și mai informative. Sunt legați crunt de expunerea lor, indiferent de poziția camerei. Pe de altă parte, duhoarea caracterizează bine specificul unui individ. Aceste puncte pot fi folosite ca bază pentru modelarea sistemului de semne.

Pentru a crește nivelul caracteristicilor, puteți selecta un cadru punct 2D din aceeași poziție a feței. Care aspect al persoanei din fața camerei este cel mai informativ? Vezi ce este în față. Nu este o idee bună ca un criminalist să facă fotografii și profiluri frontale. Deocamdată, îmi îmbrățișez fața.

Toate semnele (stand up) sunt adimensionale (normalizate), deci sunt ajustate la orice dimensiune (stand up). Presupun că cea mai potrivită mărime pentru mărimea ta este să stai între mijlocul ochilor tăi stufos. Și de ce, de exemplu, nu ochelarii tăiați moderni care sunt de fapt prezentați în gama de repere? În dreapta este că colțurile ochilor se deschid (se apropie) atunci când reacționează la o schimbare de culoare, stil, clipire etc. Stai între mijlocul ochilor și chiar mai bine.

Ce semn ar trebui să luăm ca bază de la primul nostru vecin? Presupun că ridicarea de la punctul de sus s-a mutat la punctul de ridicare de jos. Judecând după fotografie, aceste semne pot varia în funcție de oameni.

De asemenea, înainte de a forma semnele pentru început și aliniere, este necesar să se filtreze acumulările video ale cadrelor punctuale ale caracteristicilor, care, din motive subiective și obiective, nu oferă imaginile frontale corecte ale individului (fața completă). ).

Suntem lipsiți de acele cadre de puncte care trec în spatele unor astfel de semne:

  • Drept, ca trecere prin punctele extreme ale ochilor (linia ochilor), perpendicular pe drept, ca trecerea prin punctele extreme ale nasului (linia nasului).
  • Linia ochilor este paralelă cu linia dreaptă, deoarece trece prin punctele cuticulelor gurii (linia gurii).
  • Se realizează simetria valorilor punctelor superioare, aproape de linia nasului.
  • Colțurile ochilor (externe și interne) sunt situate pe aceeași linie.

Capul imaginilor frontale care urmează toate semnele:

Exemplu de imagine de filtrat:

Încercați să vă dați seama singur ce semn al imaginii nu ar trebui să treceți.

Cum sunt oficializate semnele pentru a asigura filtrarea și recunoașterea persoanelor? Practic, mirosul este cauzat de diferențele dintre puncte, paralelism și perpendicularitate. Formalizarea corespunzătoare a unor astfel de semne este discutată în subiect.

Algoritm pentru recunoașterea aspectului bazat pe un cadru 2D de puncte.

Coordonatele punctelor cadrului cu fața către fereastră sunt specificate în sistemul de coordonate, care este legat de punctul din stânga sus al ferestrei. În acest caz, întregul Y este drept în jos.

Pentru claritate, semnul desemnat este vicoristovo sistem koristuvalnitsku coordonate (UCS), tot X care trece prin tăietura dintre mijlocul ochilor și tot Y este perpendicular pe această tăietură prin mijlocul său drept în sus. Coordonatele UCS (de la -1 la +1) sunt normalizate - sunt comparate cu distanța dintre ochii din mijloc.

PSK asigură claritatea și simplitatea semnului desemnat. De exemplu, poziția unui individ în vedere frontală este indicată de simetria punctelor ochilor de-a lungul liniei nasului. Acest semn se formalizează prin evadarea liniei nasului din direcția Y, astfel încât X1 = X2 = 0, unde X1 și X2 sunt coordonatele punctelor extreme ale nasului (27 și 30) UCS.

Înseamnă că este mai bine să utilizați fereastra IC

Coordonatele punctelor mijlocii ale ochilor stângi și dreptului (stânga și dreapta):

XL = (X45 + X42) / 2; YL = (Y45 + Y42)/2; XR = (X39 + X36) /2; YR = (Y39 + Y36)/2;

PSC cob:

X0 = (XL + XR) / 2; Y0 = (YL + YR) / 2;

Stați între mijlocul ochilor și axele X și Y:

DX = XR - XL; DY = YR - YL;

Poziția activă L între punctele mijlocii ale ochilor (urmând teorema lui Pitagora):

L = sqrt (DX** 2 + DY**2)

Funcții trigonometrice pentru rotația UCS:

Să trecem de la coordonatele VKonny SK la coordonatele PSK, Parametrii Vikorist X0, Y0, L, sin AL, cos AL:

X_Utilizator_0 = 2 (X_Window - X0) / L;

Y_User_0 = - 2 (Y_Window - Y0) / L;

X_Utilizator= X_User_0 * cos_AL - Y_User_0 * sin_AL;

Y_Utilizator= X_User_0 * sin_AL + Y_User_0 * cos_AL;

Implementăm filtrarea imaginii verificarea secvențială a semnelor:

1. Semnul perpendicularității liniilor nasului și ochilor, precum și simetria punctelor cuticulei ochilor. Linia nasului este indicată de punctele 27 și 30 (div. micuții). Semnele ofensatoare sunt aliniate ca coordonatele UCS ale acestor puncte X1 = X2 = 0 (adică linia nasului se apropie de întregul Y).

2. Semn de paralelism între linia ochilor și linia gurii. Linia companiei este indicată de punctele 48 și 54 (div. mici). Semnul corespunde faptului că UCS Y1-Y2=0.

3. Semn de simetrie a punctelor de tăiere ale firmei. Linia companiei este indicată de punctele 48 și 54 (div. mici). Semnul este contiguu, deoarece UCS X1+X2 =0

4. Semnează „Colțurile ochilor sunt pe aceeași linie”. Indicat direct în perechi de puncte: (36 și 45), precum și (39 și 42). Deoarece testul pentru semnul 1 a fost deja trecut, adăugați valoarea în UCS a semnului Y2-Y1 = 0 la punctele 36 și 39.

Nu putem fi absolut egali cu zero, deci semnele sunt egale cu o valoare admisibil de mică.

Program pentru ridicarea de nivel a personalităților într-un singur semn

Ca semn, stați între puncte și mutați-vă în același loc (Repere punctele 27 și 8, div. micuții). Semnul, normalizarea, este indicat de USC pentru relațiile: (Y1 - Y2) / L, unde L - sta între centrele ochilor. La pornirea unui program, semnul pentru o anumită persoană este indicat printr-un număr, care este în ordinea individului care este detectat (această parte a codului este comentată în program). Când valoarea semnului este recunoscută, aceasta este egală cu semnul specific al individului de piele introdus în program. Dacă rezultatul verificării incriminării este pozitiv, se confirmă identificatorul dumneavoastră.

Programul recunoaște fotografia, în care sunt cu 15 ani mai tânără, și tot cu păr. Vizibilitatea din fotografie este Sutteva, nu este ușor să prinzi o persoană. Ale program de calculator Nu mă vei păcăli.

Camera de control:

  1. Cunoașteți programul.
  2. Semnificația semnelor pentru propria persoană și pentru mulți dintre colegii tăi.
  3. Protestați programul înainte de a vă identifica (colegii).

#include #include #include #include #include #include #include „drawLandmarks.hpp” folosind namespace std; folosind cv spatiu de nume; folosind spațiul de nume cv::face; int main(int argc, char** argv) ( // Încărcare Face Detector CascadeClassifier faceDetector("haarcascade_frontalface_alt2.xml"); // Creați o instanță pentru Facemark Ptr facemark = FacemarkLBF::create(); // Încărcați detectorul de reper facemark->loadModel("lbfmodel.yaml"); // Configurați camera web pentru captura video VideoCapture cam(0); // Variabilă pentru stocarea cadrului video și a acestuia în tonuri de gri Cadrul Mat, gri; // Citește un cadru în timp ce (cam.read(frame)) ( // Găsește vectorul feței chipuri; // Convertiți cadrul în tonuri de gri deoarece // FaceDetector necesită o imagine în tonuri de gri. cvtColor(cadru, gri, COLOR_BGR2GRAY); // Detectează fețe faceDetector.detectMultiScale(gri, fețe); // Variabilă pentru repere. // Repere pentru o singură față este un vector de puncte // Pot exista mai multe fețe în imagine. Prin urmare, // folosim un vector de vector de puncte. vector< vector>repere; // Run landmark detector bool success = facemark->fit(frame, faces, landmarks); if (succes) ( // Dacă are succes, redați reperele pe față pentru (size_t i = 0; i< faces.size(); i++) { cv::rectangle(frame, faces[i], Scalar(0, 255, 0), 3); } for (int i = 0; i < landmarks.size(); i++) { //if((i >=30)&&(i<= 35)) drawLandmarks(frame, landmarks[i]); for (size_t j = 0; j < landmarks[i].size(); j++) { circle(frame, Point(landmarks[i][j].x, landmarks[i][j].y), 1, Scalar(255, 0, 0), 2); } line(frame, Point(landmarks[i].x, landmarks[i].y), Point(landmarks[i].x, landmarks[i].y), Scalar(0, 0, 255), 2); float XL = (landmarks[i].x + landmarks[i].x) / 2; float YL = (landmarks[i].y + landmarks[i].y) / 2; float XR = (landmarks[i].x + landmarks[i].x) / 2; float YR = (landmarks[i].y + landmarks[i].y) / 2; line(frame, Point(XL, YL), Point(XR, YR), Scalar(0, 0, 255), 2); float DX = XR - XL; float DY = YR - YL; float L = sqrt(DX * DX + DY * DY); float X1 = (landmarks[i].x); float Y1 = (landmarks[i].y); float X2 = (landmarks[i].x); float Y2 = (landmarks[i].y); float DX1 = abs(X1 - X2); float DY1 = abs(Y1 - Y2); float L1 = sqrt(DX1 * DX1 + DY1 * DY1); float X0 = (XL + XR) / 2; float Y0 = (YL + YR) / 2; float sin_AL = DY / L; float cos_AL = DX / L; float X_User_0 = (landmarks[i].x - X0) / L; float Y_User_0 = -(landmarks[i].y - Y0) / L; float X_User27 = X_User_0 * cos_AL - Y_User_0 * sin_AL; float Y_User27 = X_User_0 * sin_AL + Y_User_0 * cos_AL; X_User_0 = (landmarks[i].x - X0) / L; Y_User_0 = -(landmarks[i].y - Y0) / L; float X_User30 = X_User_0 * cos_AL - Y_User_0 * sin_AL; float Y_User30 = X_User_0 * sin_AL + Y_User_0 * cos_AL; if (abs(X_User27 - X_User30) <= 0.1) { //putText(frame, std::to_string(abs(L1 / L)), Point(landmarks[i].x, landmarks[i].y), 1, 2, Scalar(0, 0, 255), 2); if (abs((L1 / L) - 1.6) < 0.1) { putText(frame, "Roman", Point(landmarks[i].x, landmarks[i].y), 1, 2, Scalar(0, 0, 255), 2); } if (abs((L1 / L) - 1.9) < 0.1) { putText(frame, "Pasha", Point(landmarks[i].x, landmarks[i].y), 1, 2, Scalar(0, 0, 255), 2); } if (abs((L1 / L) - 2.1) < 0.1) { putText(frame, "Svirnesvkiy", Point(landmarks[i].x, landmarks[i].y), 1, 2, Scalar(0, 0, 255), 2); } } putText(frame, "Incorrect", Point(landmarks[i].x, landmarks[i].y), 1, 2, Scalar(0, 0, 255), 2); } } // Display results imshow("Facial Landmark Detection", frame); // Exit loop if ESC is pressed if (waitKey(1) == 27) break; } return 0; }

 

 

Tse tsikavo: