iOS GLSL. Czy istnieje sposób na utworzenie histogramu obrazu przy użyciu shadera GLSL?
W innym miejscu Stoskoverflow zadano pytanie dotyczące histogramu depthbuffer - Utwórz teksturę histogramu bufora głębi za pomocą GLSL .
Piszę aplikację do przetwarzania obrazów na iOS i jestem zaintrygowany tym pytaniem, ale niejasna jest udzielona odpowiedź. Czy możliwe jest utworzenie histogramu obrazu za pomocą GPU przez GLSL?
2 answers
Tak, jest. Nie jest to oczywiście najlepsze podejście, ale jest to rzeczywiście najlepsze dostępne w systemie iOS, ponieważ OpenCL nie jest obsługiwany. Stracisz elegancję, a Twój kod prawdopodobnie nie będzie tak prosty, ale prawie wszystkie funkcje OpenCL można osiągnąć za pomocą shaderów.
Jeśli to pomoże, DirectX11 zawiera przykład FFT dla shaderów obliczeniowych. Zobacz informacje o wydaniu DX11 August SDK.
Tak, jest, chociaż jest to trochę trudniejsze niż myślisz na iOS. Jest to czerwony histogram wygenerowany i wykreślony w całości na GPU, działający w oparciu o transmisję wideo na żywo:
Sugestia Tommy ' ego w pytaniu, które podajesz, jest świetnym punktem wyjścia, podobnie jak ta praca Scheuermanna i Hensleya . Sugerowane jest użycie rozpraszania do tworzenia histogramu dla kanałów kolorów na obrazie. Rozpraszanie jest procesem, w którym mijasz w siatce punktów do cieniowania wierzchołków, a następnie niech ten cieniujący odczyta kolor w tym punkcie. Wartość pożądanego kanału koloru w tym punkcie jest następnie zapisywana jako współrzędna X (z 0 dla współrzędnych Y i z). Następnie moduł cieniowania fragmentów rysuje półprzezroczysty punkt o szerokości 1 piksela na tej współrzędnej w celu.
Ten cel to obraz o wysokości 1 piksela, szerokości 256 pikseli, z każdą pozycją szerokości reprezentującą jeden kolorowy Pojemnik. Pisząc punkt o niskim Alfa kanał (lub niskie wartości RGB), a następnie za pomocą mieszania addytywnego można gromadzić wyższą wartość dla każdego pojemnika na podstawie liczby wystąpień określonej wartości koloru na obrazie. Te piksele histogramu można następnie odczytać do późniejszego przetworzenia.
[4]} główny problem z robieniem tego w shaderach na iOS polega na tym, że pomimo raporty są przeciwne , Apple wyraźnie stwierdza, że Tekstura czyta w cieniowaniu wierzchołków nie będzie działać na iOS. Próbowałem tego ze wszystkimi urządzeniami z iOS 5.0 i żaden z nich były w stanie wykonywać odczyty tekstur w cieniowaniu wierzchołków (ekran po prostu robi się czarny, bez błędów GL).Aby to obejść, odkryłem, że mogę odczytać surowe piksele mojego wejściowego obrazu (poprzez glReadPixels()
lub szybsze buforowanie tekstur ) i przekazać te bajty jako dane wierzchołków z typem GL_UNSIGNED_BYTE. Poniższy kod dokonuje tego:
glReadPixels(0, 0, inputTextureSize.width, inputTextureSize.height, GL_RGBA, GL_UNSIGNED_BYTE, vertexSamplingCoordinates);
[self setFilterFBO];
[filterProgram use];
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_ONE, GL_ONE);
glEnable(GL_BLEND);
glVertexAttribPointer(filterPositionAttribute, 4, GL_UNSIGNED_BYTE, 0, (_downsamplingFactor - 1) * 4, vertexSamplingCoordinates);
glDrawArrays(GL_POINTS, 0, inputTextureSize.width * inputTextureSize.height / (CGFloat)_downsamplingFactor);
glDisable(GL_BLEND);
W powyższym kodzie zauważysz, że stosuję krok do próbkowania tylko ułamka pikseli obrazu. Dzieje się tak dlatego, że najniższy poziom krycia lub skali szarości, który można zapisać, wynosi 1/256, co oznacza, że każdy pojemnik zostanie maksymalnie wyczerpany raz więcej niż 255 pikseli na tym obrazie ma tę wartość koloru. Dlatego musiałem zmniejszyć liczbę przetwarzanych pikseli, aby wprowadzić zakres histogramu w tym ograniczonym oknie. Szukam sposobu na rozszerzenie tego zakresu dynamicznego.
Shadery używane do tego celu są następujące, zaczynając od wierzchołka shadera: attribute vec4 position;
void main()
{
gl_Position = vec4(-1.0 + (position.x * 0.0078125), 0.0, 0.0, 1.0);
gl_PointSize = 1.0;
}
I kończąc na fragment shader:
uniform highp float scalingFactor;
void main()
{
gl_FragColor = vec4(scalingFactor);
}
Działającą implementację tego można znaleźć w moim open source GPUImage frameworku. Chwyć i uruchom przykład FilterShowcase, aby zobaczyć analizę histogramu i kreślenie dla siebie.
Istnieją pewne problemy z wydajnością tej implementacji, ale był to jedyny sposób, w jaki mogłem myśleć o zrobieniu tego na GPU na iOS. Jestem otwarty na inne propozycje.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:45:33