killgore
Legacy Member
Hallo
Ik moet momenteel in java nogal intensieve operaties doen op afbeeldingen.
Korte situatieschets:
We krijgen een afbeelding binnen via een netwerkconnectie (om deze reden in jpeg). Deze wordt momenteel ingelezen via ImageIO.read() van jpeg->bufferedImage.
In ons algoritme wordt hieruit dan van een aantal lijnen de Y-component (luminantie) gehaald, hierop wordt een detectiealgoritme uitgevoerd (dat vrij snel gaat).
Daarna wordt uit die originele BufferedImage een specifiek stuk uitgeknipt die weer door een algoritme wordt gestuurd die informatie haalt uit dat stuk afbeelding.
Dit werkte vrij goed voor de resoluties waarmee we momenteel werken (iets van: alles gaat onder de seconde). Nu echter zou dit veel vlotter moeten om meerdere requests tegelijkertijd aan te kunnen (en iets van een 500ms is dan niet aanvaardbaar). Na verscheidene optimalisaties ben ik tot de conclusie gekomen dat onze voornaamste vertraging in de afbeeldingsoperaties zit. Zo neemt dat eerste detectiealgoritme op mijn pc gemiddeld een 75ms in beslag, waarvan 65ms gaan naar een loop die de luminantiecomponenten berekent uit de buffered image. fyi: ligt niet aan float-operaties, maar aan de getRGB() functies.
Analoog voor het 2e algoritme wordt ongeveer 4/5e van de tijd verspild aan het clippen & knippen van de juiste data.
Als oplossing hadden we verscheidene ideeën:
1) Alles omzetten naar C++ -> gewoon de tijd niet voor momenteel. Voor iemand begint te zagen: dit had je onmiddellijk in C++ moeten doen, we hadden goede redenen het niet te doen
. Zelfs van in het begin was het duidelijk dat dit puur in C++ doen gewoon niet haalbaar was met de gegeven tijdslimiet. Bepaalde bibliotheken die we gebruiken in java zijn niet beschikbaar en gewoon niet op een week te herschrijven in C/C++.
2) Bepaalde operaties in C++ uitvoeren -> De afbeeldingsverwerkingsoperaties (en eventueel zware algoritmen) in c++ laten gebeuren. Hier zit ik met het probleem dat ik geen idee heb hoe je pakweg een BufferedImage object aanspreekt vanuit C++. ik heb al zitten prutsen met javah, maar veel hielp me dat niet voor native jre klasses. Het voornaamste is dat ik eigenlijk rechtstreeks aan rgb-data zou kunnen, want een copy van de rgb-array in java zelf duurt véél te lang. In c++ zou ik dan mijn afbeeldingsoperaties véél sneller kunnen uitvoeren met behulp van libs (en assembler) die gebruik maken van multimedia extensies van IA32 processoren (spijtig genoeg geen GPU beschikbaar).
3) Zoeken naar geoptimaliseerde java image libraries, het zou me sterk verbazen moesten deze niet bestaan, maar ik vind niet direct iets deftig op internet. Dit zou voor ons de optimale oplossing zijn. Deze mogen gerust beperkt zijn tot IA32-compatible machines.
Een bijkomende vraag: een volgende stap is dat we geen jpeg maar mpeg ontvangen, waarbij deze operatie bv. bij elk I-frame moet worden uitgevoerd. Zelfde vraag ivm snelheid hiervoor.
In de hoop dat er toch iemand hiervan iets weet.
Ik moet momenteel in java nogal intensieve operaties doen op afbeeldingen.
Korte situatieschets:
We krijgen een afbeelding binnen via een netwerkconnectie (om deze reden in jpeg). Deze wordt momenteel ingelezen via ImageIO.read() van jpeg->bufferedImage.
In ons algoritme wordt hieruit dan van een aantal lijnen de Y-component (luminantie) gehaald, hierop wordt een detectiealgoritme uitgevoerd (dat vrij snel gaat).
Daarna wordt uit die originele BufferedImage een specifiek stuk uitgeknipt die weer door een algoritme wordt gestuurd die informatie haalt uit dat stuk afbeelding.
Dit werkte vrij goed voor de resoluties waarmee we momenteel werken (iets van: alles gaat onder de seconde). Nu echter zou dit veel vlotter moeten om meerdere requests tegelijkertijd aan te kunnen (en iets van een 500ms is dan niet aanvaardbaar). Na verscheidene optimalisaties ben ik tot de conclusie gekomen dat onze voornaamste vertraging in de afbeeldingsoperaties zit. Zo neemt dat eerste detectiealgoritme op mijn pc gemiddeld een 75ms in beslag, waarvan 65ms gaan naar een loop die de luminantiecomponenten berekent uit de buffered image. fyi: ligt niet aan float-operaties, maar aan de getRGB() functies.
Analoog voor het 2e algoritme wordt ongeveer 4/5e van de tijd verspild aan het clippen & knippen van de juiste data.
Als oplossing hadden we verscheidene ideeën:
1) Alles omzetten naar C++ -> gewoon de tijd niet voor momenteel. Voor iemand begint te zagen: dit had je onmiddellijk in C++ moeten doen, we hadden goede redenen het niet te doen
. Zelfs van in het begin was het duidelijk dat dit puur in C++ doen gewoon niet haalbaar was met de gegeven tijdslimiet. Bepaalde bibliotheken die we gebruiken in java zijn niet beschikbaar en gewoon niet op een week te herschrijven in C/C++.2) Bepaalde operaties in C++ uitvoeren -> De afbeeldingsverwerkingsoperaties (en eventueel zware algoritmen) in c++ laten gebeuren. Hier zit ik met het probleem dat ik geen idee heb hoe je pakweg een BufferedImage object aanspreekt vanuit C++. ik heb al zitten prutsen met javah, maar veel hielp me dat niet voor native jre klasses. Het voornaamste is dat ik eigenlijk rechtstreeks aan rgb-data zou kunnen, want een copy van de rgb-array in java zelf duurt véél te lang. In c++ zou ik dan mijn afbeeldingsoperaties véél sneller kunnen uitvoeren met behulp van libs (en assembler) die gebruik maken van multimedia extensies van IA32 processoren (spijtig genoeg geen GPU beschikbaar).
3) Zoeken naar geoptimaliseerde java image libraries, het zou me sterk verbazen moesten deze niet bestaan, maar ik vind niet direct iets deftig op internet. Dit zou voor ons de optimale oplossing zijn. Deze mogen gerust beperkt zijn tot IA32-compatible machines.
Een bijkomende vraag: een volgende stap is dat we geen jpeg maar mpeg ontvangen, waarbij deze operatie bv. bij elk I-frame moet worden uitgevoerd. Zelfde vraag ivm snelheid hiervoor.
In de hoop dat er toch iemand hiervan iets weet.

.
. En detectie zelf zit aan minimum idd, zoals gezegd is dat algoritme eigenlijk méér dan snel genoeg.
.