Le langage SMS est exclu sur les forums ProgBoards, tout message ne respectant pas la charte sera déplacé, modifié, ou supprimé par nos modérateurs.

Forum Informatique » Algorithmes » Interpolation bilinéaire

Amwus
ProgBoarder
Citer Linux Firefox 3 - Posté le 06/10/2008 à 20:45
Salut à tous !

Depuis plus d'une semaine, je cherche à implémenter en Java un algorithme d'interpolation bilinéaire d'une image donnée, afin de la redimensionner. Mais le probleme est que je n'ai aucune connaissance dans ce domaine et je ne parviens pas à mettre au point cet algorithme !

Je dispose donc d'un tableau de pixels image[x][y] et j'aimerais agrandir cette image à une taille supérieure ou inférieure.

Je calcule donc le ratio pour chaque pixel en x et en y mais je n'arrive pas à aller plus loin...

Y aurait il une bonne âme qui aurait quelques connaissances dans ce domaine et qui pourrait éclairer ma lanterne ?

Merci beaucoup d'avance ! (sourire)
"Engl Amps are the best i've ever used... Not only are they powerfull, but they have charachter too..." R. Blackmore
neamar
Modérateur
RemonterCiter Linux Firefox 3 - Posté le 06/10/2008 à 20:59
Beuah...Deux règles de trois successives ?

Plus sérieusement, mon copain Wikipedia a l'air d'en connaitre un rayon : http://en.wikipedia.org/wiki/Resampling#Bitmap (sourire)
Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it.

http://neamar.fr
Amwus
ProgBoarder
RemonterCiter Linux Firefox 3 - Posté le 06/10/2008 à 21:30
Ha mais j'ai déja consulté le copain wiki, et d'autres memes... J'en suis arrivé à la conclusion suivante : Forcément, pour une image agrandie, on se retrouve avec des pixels vides. L'astuce pour ces pixels, c'est de les remplir avec la moyenne des 4 pixels les plus proches les entourant.

Mais voila, comment trouver facilement ces pixels... Je dois dire que ce n'est vraiment pas évident !
"Engl Amps are the best i've ever used... Not only are they powerfull, but they have charachter too..." R. Blackmore
Fred
ProgBoarder
RemonterCiter Windows XP Firefox 3 - Posté le 06/10/2008 à 22:24
Salut Amwus,
si je me rappelle bien.

Appelons x1, y1, x2, y2 les coordonnées du point supérieur droit
et inférieur gauche du rectangle de destination.

On cherche à remplir ce rectangle de largeur l = x2 - x1 + 1 pixels
et de hauteur h = y2 - y1 + 1 pixels
avec une image de largeur l' et de hauteur h'.

Le principe, tu parcours ce cadre avec deux boucles de style FOR,
exemple :

FOR y = y1 TO y2
FOR x = x1 TO x2

PSET (x, y), c

NEXT
NEXT

Reste à déterminer c.

En fait c'est assez évident, on va chercher le c qui se rapproche
le plus de la 'case' équivalente dans ton tableau d'image
moyennant, une moyenne pondérée.

Je te propose ici un truc simple, non optimisé.

On change de repère : (x', y' nombres à virgule flottante)

x' = x * (l' -1) / l + 0.5
y' = y * (h' - 1) / h + 0.5

(Règle de trois, puis on centre au milieu des cases (+0.5),
on enlève aussi une case en hauteur et largeur afin de ne pas dépasser à cause du + 0.5)

Évidemment, à moins d'un coup de bol la case (x', y') n'éxiste
pas dans ton tableau.

On calcule maintenant des coefficients couleur,
q1 = x' - floor (x')
q2 = ceil (x') - x'
q3 = y' - floor (y')
q4 = ceil (y') - y'

(floor est l'arrondi par défaut et ceil l'arrondi par excès)

Chaque q est compris entre 0 et 1 non compris
et q1 + q2 = 1, q3 + q4 = 1 (fais le calcul (sourire))

On pose : xt = ceil(x') : yt = ceil(y')
On peut donc écrire :
c = (q1 * Table (xt, yt) + q2 * Table (xt + 1, yt) + q3 * Table (xt, yt) + q4 * Table (xt, yt + 1)) / 2

Je divise par 2 à cause du fait que q1+ q2 + q3 + q4 = 2

Attention : le calcul de c ne marche que dans l'hypothèse
ou ton image est constituée d'une seule composante
et en représentation virgule flottante.

Tu auras sûrement à calculer crouge, cbleu, et cvert
et a tout reconvertir et regrouper pour former un c 24 bits.

Voilà si ça a pu t'aider, voici l'algo final :
(TableR, TableV, et TableB sont des nombres flottants compris entre 0 et 255)

FOR y = y1 TO y2
FOR x = x1 TO x2

x' = x * (l' -1) / l + 0.5
y' = y * (h' - 1) / h + 0.5

q1 = x' - floor (x')
q2 = ceil (x') - x'
q3 = y' - floor (y')
q4 = ceil (y') - y'

cR = (q1 * TableR (xt, yt) + q2 * TableR (xt + 1, yt) + q3 * TableR (xt, yt) + q4 * TableR (xt, yt + 1)) / 2

cV = (q1 * TableV (xt, yt) + q2 * TableV (xt + 1, yt) + q3 * TableV (xt, yt) + q4 * TableV (xt, yt + 1)) / 2

cB = (q1 * TableB (xt, yt) + q2 * TableB (xt + 1, yt) + q3 * TableB (xt, yt) + q4 * TableB (xt, yt + 1)) / 2

If cR > 255 then cR=255 (Peuvent pas être plus petits que 0,
If cV > 255 then cV=255 les q sont positifs)
If cB > 255 then cB=255

c = ceil (cR) + ceil(cV) * 256 + ceil(cB) * 65536
PSET (x, y), c

NEXT
NEXT

PS : Dis moi si ça marche, et si tu l'appliques, peux tu m'envoyer
le résultat, image, code ou application ?
A +


Edité par Fred ( 06/10/2008 22:27:10 )
Purée faut que je change d'avatar !
Amwus
ProgBoarder
RemonterCiter Linux Firefox 3 - Posté le 06/10/2008 à 22:30
Salut Fred ! Merci beaucoup ! Je vais tester ça demain !

Si ça marche tu me sauves (héhé ! Mais même, c'est une très bonne base pour le perfectionner par la suite (sourire)

Je te tiens au courant !
"Engl Amps are the best i've ever used... Not only are they powerfull, but they have charachter too..." R. Blackmore
Amwus
ProgBoarder
RemonterCiter Linux Firefox 3 - Posté le 07/10/2008 à 18:23
Salut !

Alors j'ai quelques difficultés à implémenter cet algo... Déjà, je ne comprend pas très bien tes coefficients couleurs... A quoi servent ils exactement ?

Autre chose, TableR,V,B sont les valeurs des pixels de l'image originale je suppose ?

Et sinon, j'ai des out of bounds exceptions notamment lors du calcul des cR, cV, cB... Je vais continuer à creuser !

Merci !
"Engl Amps are the best i've ever used... Not only are they powerfull, but they have charachter too..." R. Blackmore
Fred
ProgBoarder
RemonterCiter Windows XP Firefox 3 - Posté le 08/10/2008 à 22:27
J'ai oublié la ligne :

xt = ceil(x') : yt = ceil(y')

après :

x' = x * (l' -1) / l + 0.5
y' = y * (h' - 1) / h + 0.5

Les coefficients q correspondent à la distance
verticale et horizontale entre le point d'impact et
les deux pixels sources les plus proches.

Je veux bien débugger ton code si c'est dans un langage
que je connais.
Purée faut que je change d'avatar !
Amwus
ProgBoarder
RemonterCiter Linux Firefox 3 - Posté le 09/10/2008 à 16:15
Mais TableR, V, B, correspond au tableau de pixels de l'image d'origine ? Ou c'est déja la nouvelle image ?

Parce que techniquement, on ne peut pas encore aller chercher xt+1 dans la nouvelle image...

"Engl Amps are the best i've ever used... Not only are they powerfull, but they have charachter too..." R. Blackmore
Fred
ProgBoarder
RemonterCiter Windows XP Firefox 3 - Posté le 09/10/2008 à 18:11
C'est bien la table d'origine.
Purée faut que je change d'avatar !
Amwus
ProgBoarder
RemonterCiter Linux Firefox 3 - Posté le 09/10/2008 à 18:24
Je t'ai envoyé un message en mp... (sourire)
"Engl Amps are the best i've ever used... Not only are they powerfull, but they have charachter too..." R. Blackmore
Amwus
ProgBoarder
RemonterCiter Linux Firefox 3 - Posté le 14/10/2008 à 21:16
Salut les gens ! Je relance mon problème d'interpolation... J'ai revu tout le bazard mais j'ai encore un petit probleme.

En fait, j'isole les composantes RGB de chaque point nécessaire à mon interpolation. Pour le point (x0,y0), j'utilise pour l'interpolation les points (x0,y0), (x0 + 1, y0), (x0 + 1, y0 + 1), (x0, y0 + 1). Pour tous ces points, j'arrive à récupérer dans des entiers les composantes R,G,B, comprises entre 0 et 255.

Pour chaque point, j'ai donc 3 valeurs. Ma question est la suivante. Comment combiner toutes ces valeurs pour au final me donner la bonne valeur du pixel recherché ?

Je coince la dessus...

Je sais, je suis chiant avec mon interpolation (héhé

Merci d'avance !8)
"Engl Amps are the best i've ever used... Not only are they powerfull, but they have charachter too..." R. Blackmore

Poster une réponse

STOP aux fautes volontaires !
Message
Formatage
Note: pour partager du code source, merci d'utiliser le wall !
Smileys (sourire) (yekyek) (clein d'oeil) (désapprouve) (triste) (cool) (langue) (confus) (gêné) (neutre) (eek) (surpris) (diable) (flèche) (exclamation) (question) (diable) (idée) (méchant)
Pseudonyme
Recopiez le code
v6 © Computaid SPRL 2005-2012 - Tous droits réservés - Hébergé par eTigris - Page générée en 0,037 s - Crédits - Stats
1 connecté