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