2024. április 18., csütörtök

Gyorskeresés

[SVS_7] Augusztus 24-25.

Írta: | Kulcsszavak: SRV . surveyor . SVS

[ ÚJ BEJEGYZÉS ]

Augusztus 24., még 107 nap

Konzultációnak vége, a konzulens elégedett az eddig elért eredménnyel, főleg annak, hogy sikerült megoldani a jpeg dekódolást memóriában, és OpenCV-s IplImage-t csinálni.

Gyorsításra is adott pár tippet, pl. nem kell RGB->BGR, elég lenne egy IplImage headert csinálni, memória másolást kiváltani mással (bár azt hiszem csak címet másolok, egyedül akkor másolok (memcpy()), amikor összegyűjtöm a kép bytejait) és SVS esetén a két kép dekódolását külön szál végezze.

Kérése volt, hogy a kamera kalibráció, és a többiek majd külön .dll legyenek, és nem szükséges a grafikusba berakni, elég egy egyszerű konzolost megcsinálni.

Először is, tesztet kell végeznem, hogy a robot éldetektálása gyorsabb-e, vagy az, ha számítógép végzi el (sobel + canny) és milyen a minőségük. Természetesen SVS robot esetén is, két képpel.

Újabb konzultáció majd szeptemberben, addig kalibrációt, rektifikációt és sűrű illesztést meg kéne oldani opencv-s példák alapján.

Sobel

Első körben a sobelt kellett megcsinálni. Az még gyorsan ment, hogy horizontális és vertikális deriváltat (dx, dy) visszaadja az OpenCV, de nekem még átlagolni is kellett (sqrt(dx*dx+dy*dy) minden pixelre).

Itt jelentkeztek a problémák, lásd alábbi kép:

Bal felső a dx, jobb felső a dy, bal alsó az eredeti, jobb alsó meg a "sobel", jobb szélső dx+dy

screenshot

Bár felismerhető a szoba, de ez nem sobel, még a blokkos jpeg tagokat is élnek vette...

Csináltam egy egyszerű tesztet:

Ez is dx+dy, csak kézzel történt az összeadás, a felsőhöz semmi köze, itt valami konverziós bakik vannak

screenshot

Még egy olyat is megcsináltam, hogy simán egyenlővé tettem dx-szel, akkor is világosabb lett a kép.

Hát, egész délután + esti szenvedés és próbálgatás (és néhány hajtincs elvesztése) után sikerült az OpenCV beépített mátrix változójával kivitelezni, de majd megkérdezem, hogy van-e szebb megoldás, mert spórolni kell a processzoridővel:).

Máris pofásabb, ha jobban megnézzük, a jpeg blokkok továbbra is látszanak

screenshot

Ez már Q1 minőségű, blokkok már nem látszanak.

screenshot

Binarizálással is próbálkoztam, ebből született a horror malac :DDD

screenshot

Még egy fontos dologra felfigyeltem ma. C++ mindig fel kell szabadítani a nem használt változókat (és beláttam, hogy nem vicc :D). Egy IplImage változót nem szabadítottam fel, így mindig új keletkezett, ennek következtében simán elfogyott a vpc-ben lévő 500 mega üres memória :).

Augusztus 25., még 106 nap

Konzulens adott két újabb megoldást. Az egyik teljesen jó, a kép is teljesen ugyanaz, mint az enyémmel. A másodiknál sajnos ugyanaz a hiba jön elő. Ha a 2. esetre tisztán 2.1-s verziójú opencv függvényeket és típusokat használok, akkor cv::Sobel()-nél elhasal, kipróbáltam az összes mátrix fajtát, mindegyikre elhasal.

Van két működő megoldás, ideje berakni a grafikus programba, hogy lehessen tesztelni a sebességet.
Én verzióm: 1. képre még jó, 2. képre elhasal. CvMat típust használok benne, de nem bírom felszabadítani (ha megteszem, elhasal), így ez kilőve. (Egy ötletem még maradt.)
Konzulens verzió: teljesen jó.

Egy kameránál elkezdtem vizsgálni, hogy lehetne gyorsítani. Rajtahagytam a kupakot, így megismételhető a teszt és az átküldött méret is minimális, így nincs jelentősége, hogy Q1-t vagy Q8-t állítok be, ugyanaz marad a képméret. A felbontás persze továbbra is számít.

160x120 -> 33-36 FPS
320x240 -> 12-13 FPS
640x480 -> 3-4 FPS

Alábbi dolgokat próbáltam ki (160x120-n elért FPS változást tüntettem fel):
1. cvCreateImage helyett cvCreateImageHeader, mikor hozzáadom az SDL kép adatait az IplImage-hez: nincs gyorsulás
2. cvCvtColor() kihagyása: +1 FPS
3. memcpy() helyett memmove(), és TCP-ből 1 ciklusban leszedem az adatokat: +1 FPS
4. imagebuf[] méretének csökkentése: +1 FPS

Sajnos a memcpy() vagy memmove() kihagyását nem sikerült elérni, mert nélkülük marhaság lesz a bufferben (miért? nem tudom, stepbystep jó, realtime rossz) és a parser nem engedi tovább.

Sobellel is csináltam egy gyors tesztet, és tényleg gyorsabb, mint a robot saját éldetektálója. A hátránya, hogy a CPU kihasználás nőtt. Egy rendes tesztsorozatot akarok csinálni canny-val is, ezek előzetes adatok:

Normál kép 320x240Q8 10-11 FPS
Robot edgedec. 320x240Q8 5 FPS
PC sobel 320x240Q8 7 FPS

CPU kb. 25-30%-ról 50%-ra nőtt (proci az adatlapon, program vpc futott, ami csak 1 magot használ).
Ezek az eredmények 1 szál használatával születtek, tehát:
(kép fogadás és kitömörítés) -> sobel -> (kép fogadás és kitömörítés) -> sobel ...
Ki akarom próbálni még:
(kép fogadás és kitömörítés) -> sobel és (következő kép fogadás és kitömörítés) -> sobel (következő kép fogadás és kitömörítés) -> ... tehát míg sobelt számol, addig leszedi is kitömöríti a következő képet, szerencsére mutexszel kivitelezhető.

Copyright © 2000-2024 PROHARDVER Informatikai Kft.