Devo applicare un filtro sferico su un'immagine in Android, ho allegato l'input e l'immagine di uscita prevista. L'immagine di output verrà elaborata dalla regione al centro quadrata dell'immagine di input e mappata alla sfera. Qualche idea su come farlo in Android. Dovrò usare openGL per fare questo o solo la trasformazione 2D farà il compito.Filtro sferico in android
risposta
il seguente codice Fish Eye lens per creare la Sfera e applicare alcune modifiche per ridimensionare la sfera e la generazione dello sfondo, funzionerà principalmente per immagini quadrate.
Questo è un problema ray-tracing. Probabilmente, OpenGL non ti sarà di aiuto in questo caso dato che OpenGL non fornisce il 3D basato su raggi. Tuttavia, questo potrebbe essere quello che stai cercando.
http://www1.cs.columbia.edu/CAVE/publications/pdfs/Garg_TR04.pdf
Sono d'accordo con Tim. Trasformare una bitmap in un'altra non richiede punti 3D, né Ray-trace, dimenticalo del tutto, è semplicemente 2d. Non so se opengl ha qualcosa di costruito, ma ho abbastanza esperienza 3D per indicarti la giusta direzione. Devi iterare tutti i punti all'interno della * regione del cerchio che scegli * questa è la chiave e trovare il colore usando la trasformazione FISH-EYE. Hai un sacco in rete. spero che questo aiuti
L'esempio mostrato dalla persona mostra riflessione speculare, rifrazione e una vera circolare legata all'acqua/vetro ecc ... Anche se si guarda il collegamento fornito da Brad Larson (ottimo collegamento tra l'altro +1) i bordi al limite circolare si passa gradualmente all'immagine stessa. È un effetto, non NECESSARIAMENTE di ciò che questo utente sta chiedendo. Se l'immagine sopra è veramente ciò che stanno cercando, allora potrebbe essere un po 'più complesso delle funzioni di tipo shader un po' più semplici. Non hanno ancora risposto molto dal richiedente per la loro interpretazione però ??? – trumpetlicks
Ho appena ricevuto un'implementazione di questo lavoro utilizzando OpenGL ES 2.0 su iOS:
Mentre questo è su iOS, lo shader frammento ho usato può essere portato dritto ad Android. La porzione rifrazione sferica viene eseguita utilizzando il seguente frammento Shader:
varying highp vec2 textureCoordinate;
uniform sampler2D inputImageTexture;
uniform highp vec2 center;
uniform highp float radius;
uniform highp float aspectRatio;
uniform highp float refractiveIndex;
void main()
{
highp vec2 textureCoordinateToUse = vec2(textureCoordinate.x, (textureCoordinate.y * aspectRatio + 0.5 - 0.5 * aspectRatio));
highp float distanceFromCenter = distance(center, textureCoordinateToUse);
lowp float checkForPresenceWithinSphere = step(distanceFromCenter, radius);
distanceFromCenter = distanceFromCenter/radius;
highp float normalizedDepth = radius * sqrt(1.0 - distanceFromCenter * distanceFromCenter);
highp vec3 sphereNormal = normalize(vec3(textureCoordinateToUse - center, normalizedDepth));
highp vec3 refractedVector = refract(vec3(0.0, 0.0, -1.0), sphereNormal, refractiveIndex);
gl_FragColor = texture2D(inputImageTexture, (refractedVector.xy + 1.0) * 0.5) * checkForPresenceWithinSphere;
}
il center
è un normalizzata coordinate per il centro della sfera (da uno spazio 0,0 - 1.0 entrambe le dimensioni), il radius
è il raggio normalizzato , lo refractiveIndex
è l'indice aria/materiale della tua sfera e lo aspectRatio
è il rapporto di aspetto dell'immagine (per assicurarsi che la sfera sia rotonda e non ellittica nello spazio delle coordinate normalizzato).
Questo calcola le normali di superficie per una sfera con il centro e il raggio forniti e utilizza la funzione GLSL refract()
per rifrattare un vettore in entrata e fornire coordinate di ricerca nella trama dell'immagine.
Lo sfondo è sfocato utilizzando una sfocatura gaussiana separabile che descrivo in this answer.
Questo filtro è abbastanza veloce da filtrare i video live in tempo reale su un iPhone, quindi dovrebbe essere abbastanza performante sulla maggior parte dei dispositivi Android. Il codice sorgente per esso può essere trovato all'interno di GPUImageSphereRefractionFilter nel mio framework open source GPUImage.
L'ho usato in openGL e ha funzionato perfettamente. Tuttavia ho difficoltà a capire la matematica. Durante il calcolo di y textureCoordinateToUse, capisco perché aspectRatio viene moltiplicato, ma perché è necessario il resto del calcolo? – tanvi
Non penso che sia necessariamente un problema di raytracing difficile purché lo sfondo sia solo una trama. Puoi semplicemente mappare la texture alla sfera con qualche tipo di sistema di coordinate sferiche o cubemap. Se riflettesse una scena 3D dinamica sarei d'accordo con te, ma solo riflettere una trama non è troppo difficile. – Tim
L'esempio non-raytracing è ciò che il documento che ho fornito è (sono abbastanza sicuro) !!! Un altro modo per farlo (anche se lo sfondo è una trama) potrebbe comunque usare il ray-tracing. – trumpetlicks
"OpenGL non fornisce ray based 3D" - lo è sicuramente quando si usano gli shader.Ho fatto una distorsione che era vicina a questo usando uno shader OpenGL ES 2.0: http://stackoverflow.com/a/9896856/19679 e GLSL definisce anche una funzione 'refract()' per la rifrazione della luce attraverso gli oggetti. Fammi vedere se riesco a creare uno shader per replicare questo effetto specifico. –