Tout d'abord, vous convertiez inutilement (et à tort) votre résultat de Float en int à chaque cycle de la boucle. Ton red
, green
et blue
devrait être de type flottant et ne doit être remis entier qu'après la convolution (lorsqu'il est converti en RVB):
float red=0.0f, green = 0.0f, blue = 0.0f
for(int i = x;i<x+3;i++){
for(int j = y;j<y+3;j++){
int color = a.getRGB(i,j);
red += ((color >> 16) & 0xff)*matrix[(i-x)*3+j-y];
green += ((color >> 8) & 0xff)*matrix[(i-x)*3+j-y];
blue += ((color >> 0) & 0xff)*matrix[(i-x)*3+j-y];
}
}
return (a.getRGB(x, y)&0xFF000000) | (((int)red) << 16) | (((int)green) << 8) | ((int)blue);
Le saignement des couleurs dans votre résultat est causé parce que vos coefficients matrix
sont faux:
0.1710991401561097f + 0.2196956447338621f + 0.1710991401561097f + 0.2196956447338621f + 0.28209479177387814f + 0.2196956447338621f + 0.1710991401561097f + 0.2196956447338621f + 0.1710991401561097f = 1.8452741
La somme des coefficients dans une matrice de convolution floue doit être de 1,0. Lorsque vous appliquez cette matrice à une image, vous pouvez obtenir des couleurs supérieures à 255. Lorsque cela se produit, les canaux "saignent" dans le canal suivant (bleu au vert, etc.). Une image complètement verte avec cette matrice entraînerait:
green = 255 * 1.8452741 ~= 471 = 0x01D7; rgb = 0xFF01D700;
Qui est un vert moins intense avec un soupçon de rouge.
Vous pouvez résoudre ce problème en divisant les coefficients par 1.8452741
, mais vous voulez vous assurer que:
(int)(255.0f * (sum of coefficients)) = 255
Sinon, vous devez ajouter un chèque qui limite la taille des canaux à 255 et ne les laissez pas enrouler. Par exemple:
if (red > 255.0f)
red = 255.0f;
Concernant l'efficacité / optimisation:
Il se peut que la différence de vitesse puisse s'expliquer par ce casting et l'appel de mathématiques inutiles, mais un candidat plus probable est la façon dont vous accédez à l'image. Je ne suis pas assez familier avec BufferedImage et Raster pour vous conseiller sur la façon la plus efficace d'accéder au tampon d'image sous-jacent.