2012-06-18 1 views

Répondre

6

C'est probablement pas l'endroit idéal pour poser une question précise sur ce cadre, mais je peux vous répondre à ce sujet. Le GPUImageMedianFilter est un filtre médian codé en dur 3x3 basé sur l'article «Un filtre médian GPU à petit rayon de courbure» de Morgan McGuire dans le livre ShaderX6. Plus à ce sujet peut être trouvé here, y compris les versions à plus grand rayon de ce. En dépit de l'implémentation la plus rapide que j'ai trouvée, il est incroyablement lent de fonctionner sur tous les appareils iOS, à l'exception des appareils iOS les plus rapides, donc l'augmentation de la zone d'échantillonnage ne fera que ralentir encore plus.

Le GPUImageGaussianBlurFilter effectue un flou gaussien simple de 9 occurrences en deux passes séparées. La propriété blurSize vous permet d'agrandir ou de contracter légèrement la zone d'échantillonnage, mais si vous allez au-delà d'un multiplicateur de 1,5, vous commencerez à voir des artefacts en raison du trop petit nombre d'échantillons utilisés pour flouter sur une grande surface. Je travaille sur quelques façons d'élargir la zone de flou d'une manière performante, mais c'est la limite de ce filtre particulier.

+2

super, merci beaucoup Brad pour la réponse et la bibliothèque génial! – vondip

0

Voici comment calculer la médiane dans le rayon pixel quartier de votre choix:

kernel vec4 medianUnsharpKernel(sampler u) { 
vec4 pixel = unpremultiply(sample(u, samplerCoord(u))); 
vec2 xy = destCoord(); 
int radius = 3; 
int bounds = (radius - 1)/2; 
vec4 sum = vec4(0.0); 
for (int i = (0 - bounds); i <= bounds; i++) 
{ 
    for (int j = (0 - bounds); j <= bounds; j++) 
    { 
     sum += unpremultiply(sample(u, samplerTransform(u, vec2(xy + vec2(i, j))))); 
    } 
} 
vec4 mean = vec4(sum/vec4(pow(float(radius), 2.0))); 
float mean_avg = float(mean); 
float comp_avg = 0.0; 
vec4 comp = vec4(0.0); 
vec4 median = mean; 
for (int i = (0 - bounds); i <= bounds; i++) 
{ 
    for (int j = (0 - bounds); j <= bounds; j++) 
    { 
     comp = unpremultiply(sample(u, samplerTransform(u, vec2(xy + vec2(i, j))))); 
     comp_avg = float(comp); 
     median = (comp_avg < mean_avg) ? max(median, comp) : median; 
    } 
} 

return premultiply(vec4(vec3(abs(pixel.rgb - median.rgb)), 1.0)); 
} 

Une brève description des étapes 1. Calculer la moyenne des valeurs des pixels entourant le pixel source un quartier 3x3; 2. Recherchez la valeur de pixel maximale de tous les pixels d'un même voisinage inférieure à la moyenne. 3. [FACULTATIF] Soustrayez la valeur du pixel médian de la valeur du pixel source pour la détection du bord. Si vous utilisez la valeur médiane pour la détection des contours, il existe plusieurs façons de modifier le code ci-dessus pour de meilleurs résultats, à savoir le filtrage médian hybride et le filtrage de média tronqué (un substitut et un meilleur filtrage de mode)). Si vous êtes intéressé, s'il vous plaît demander.

Questions connexes