Colorier une image - Algo

guillaumech

Expert
Bonjour à tous,

Me revoilà, pour une autre question :)

Je suis sur ce problème :
Une image (1000*800)
Des valeurs quadrillé dessus (tous les 36 pixels en largeur et les 26 pixels en hauteur)
Chaque valeurs à une couleur associé

Il me reste à trouver un bon algo pour colorier correctement toute l'image avec ces valeurs. Comment feriez-vous ?
J'ai essayé beaucoup de méthode déjà, mais aucun n'est vraiment parfaite ...

Découpé en carré, puis en sous carré, avec des moyennes pondérés pour faire des dégradés :

v1.................................. v2


(sous carré ...)



v3.................................. v4

Chaque pixel a comme valeur la moyenne pondéré (selon sa distance) des 4 valeurs autour. Mais on voit trop les bords des carrés ...
J'ai essayer avec une triangulation (delaunay), mais c'est idem, on voit trop les jonctions des triangles.

Le mieux serait surement de colorier selon un cercle, en prenant les x valeurs autour :

Le tout est de colorier les pixels entre chaque valeur, et de façon parfaite, sans coupure de couleur, tout en dégradé, aussi bien haut, droit, gauche, bas ... Et c'est pas tout simple à vrai dire ! :(

Merci pour votre aide ;)

Guich
 

zeb

Modérateur
Salut Guich :hello:

En voilà un problème intéressant !

Ce que tu fais s'appelle un filtre graphique. Il s'agit en général de l'application d'une matrice, caractérisée par ses dimensions et par chacun de ces coefficients.

Il n'y a pas de matrice idéale. Teste différentes dimensions (quoique je pense que 36x26 soit une bonne idée), et différents coeffs.

Tu peux commencer par remplir tes rectangles de 36 par 26 avec la valeur nominale. Puis tu passes un filtre adoucisseur, plus ou moins fort, et/ou plus ou moins de fois.
 

guillaumech

Expert
Coucou Zeb !

Les mots magiques pour réaliser ça sont : Bilinear, Bicubic, Trilinear ... Interpolation
Il serait complexe de les décrire ici, je vous laisse aller regarder sur wikipedia.

Mais en gros, on prend 4 points, on interpole les valeurs en fonction de leurs distances au point à colorier, puis on fait la moyenne des 4. Et on obtient donc la couleur souhaité. Sauf qu'il faut faire attention, car tout ça est inversé. En effet, plus la distance est grande, moins la couleur du point aura de poids sur le pixel à colorier. Et si on se trouve sur un bord, le poids des 2 points les plus éloignés est nul !

Vous devez être connecté pour voir les images.


Vous devez être connecté pour voir les images.


Ceci dis, il y a plusieurs manières de faire ... Cette technique est utilisée dans le redimensionnement d'image, et c'est de loin la meilleur (bilinear interpolation). Le débat est ouvert pour tous ceux qui souhaitent ajouter des choses, des avis, des questions ...

Je peux vous donner mon algo en pseudo code si sa intéresse qqun ...

:hello:
 

zeb

Modérateur
Yepeeee!

filtre, transformation, produit de convolution, fourrier, toussa :o
:D

En fait, tu veux qu'on te règle tes paramètres ou qu'on te propose d'autres fonctions ?
 

guillaumech

Expert
Je veux rien, j'ai trouvé la solution :) (bilinear interpolation)
Mais si qqun veut que je développe et tout'ça, pas de soucis ;)
 

guillaumech

Expert


Me revoilà Zeb, j'avais souvenir que tu parlais de convultion, et j'ai vu que dans la méthode bicubic c'était utilisé .... Alors je te demande ;) J'ai bcp de mal à tout comprendre pour dire vrai.



J'ai un peu peur pour les temps de calculs :'( Et j'aimerai que la fonction qui réalise ça soit courte ... que ce soit pas un marteau pilon !
Je vais continuer de regarder tout ça.

Merci.

Edit :

[cpp]
function bicubicFilter(value)



if (value < 0.0)

value = -value;

end;



if (Value < 1.0)

tt = sqr(value);

result = 0.5*tt*value - tt + 2.0 / 3.0;

elseif (value < 2.0)

value = 2.0 - value;

result = 1.0/6.0 * sqr(value) * value;

else

result = 0.0;

end;



endfunction;
[/cpp]

Voilà une méthode que j'ai trouvé sur le net. Mais je trouve ça très simple pour faire une interpolation bicubique ... :( Et j'ai du mal à savoir d'où sortent les valeurs (2.0, 6.0 ...) Surtout, que j'ai toujours mes 4 points de valeurs, e que je dois colorier à l'intérieur. Or là, la mtéhode prendre une unique valeur ...
 

zeb

Modérateur
Eh, eh. Cékiki regrette maintenant les cours de maths où il n'écoutait pas ? :o


Le but du jeu est de transformer de savants calculs très compliqués en opérations simples par transformée de Fourrier (tu as déjà dû croiser ce type dans tes études, au chapitre réseau ou traitement du signal, n'est-ce pas ?). Alors abandonne l'idée de tout comprendre, et laisse ses considérations aux mathématiciens.

Par contre, tu peux appliquer un truc tout fait. Ce que tu nous proposes me paraît bizarre. Tu devrais avoir un calcul matriciel, plutôt.
 

guillaumech

Expert
Non je n'ai jamais vu ça Zeb ... on ne fait pas de traitement de signal dans ma section :) Et même en math, jamais vu ... et vouii :)

J'ai déjà regardé ton lien ... :( (é rien compris !)

Je rappelle la situation, j'ai un carré, où chaque angle a une valeur, et je dois colorier l'intérieur. Bien sûr, je n'ai pas un seul carré, mais une multitude de carré (grille).

v1-------v2
|
|
v3-------v4

J'aimerai bien qu'on dégrossisse ensemble le problème, et qu'on crée ensemble l'aglo Zeb ;) (ou d'autre :))

Voici une base :
[cpp]
/**
* Interpolation par Spline Cubique
*
* @author Xavier Philippeau
*
*/
public class Interpolate {

// spline factor in the range [-1,0]
private double a = -0.5;

// original image
private Channel channel = null;

public Interpolate(Channel c) {
this.channel = c;
}

// --- Spline coefficients ----------------------------------------------------

// C0(t) = -at3 + at2
private double C0(double t) {
return -a*t*t*t + a*t*t;
}

// C1(t) = -(a+2)t3 + (2a+3)t2 - at
private double C1(double t) {
return -(a+2)*t*t*t + (2*a+3)*t*t - a*t;
}

// C2(t) = (a+2)t3 - (a+3)t2 + 1
private double C2(double t) {
return (a+2)*t*t*t - (a+3)*t*t + 1;
}

// C3(t) = at3 - 2at2 + at
private double C3(double t) {
return a*t*t*t - 2*a*t*t + a*t;
}

// --- Continous interpolation from discrete values ---------------------------

// discret value for pixel of coordinates: i (integer) , j (integer)
private double f(int i, int j) {
return this.channel.getValue(i, j);
}

// compute interpolated value for pixel of coordinates: x (real) , j (integer)
private double H(int j, double x) {
int i = (int)x;
return f(i-1,j)*C3(x-i) + f(i,j)*C2(x-i) + f(i+1,j)* C1(x-i) + f(i+2,j)*C0(x-i);
}

// compute interpolated value for pixel of coordinates: x (real) , y (real)
public double value(double x, double y) {
int j = (int)y;
return H(j-1,x)*C3(y-j) + H(j,x)*C2(y-j) + H(j+1,x)*C1(y-j) + H(j+2,x)*C0(y-j);
}
}
[/cpp]

Avec les matrices :
[cpp]
Fonctions de base:

C3(t) = at3 - 2at2 + at
C2(t) = (a+2)t3 - (a+3)t2 + 1
C1(t) = -(a+2)t3 + (2a+3)t2 - at
C0(t) = -at3 + at2


Forme matricielle

| a , a+2 , -(a+2) , -a | | P(i-1) |
|t3 t2 t 1| x | -2a , -(a+3) , 2a+3 , a | x | P(i) |
| a , 0 , -a , 0 | | P(i+1) |
| 0 , 1 , 0 , 0 | | P(i+2) |
[/cpp]

Le truc, c'est que j'ai beau essayer de comprendre, je n'y arrive pas :( et encore moins à l'appliquer à mon problème
 

zeb

Modérateur
Eh ! c'est des maths.

[fixed]C3(t) = at3 - 2at2 + at[/fixed]
C'est un polygone. t3 signifie t puissance 3.
Ou en C :
Code:
a*t*t*t - 2*a*t*t + a*t;
C'est le produit matricielle entre la ligne [t3, t2, t1, 1] et la première colonne de la matrice [a, -2a, a, 0] (<-- en ligne, mais c'est une colonne).

Je savais bien que tu allais te prendre la tête avec une matrice et ces coeffs ! Ton interpolation est cubique, parce qu'une te faut 4 points de référence. Tiens, 4x4, c'est justement la taille de ta matrice.

Bon, je vais regarder d'un peu plus près. Qu'en dit M. Xavier Philippeau ?

En attendant, un petit cours :
 

guillaumech

Expert
J'avance un peu :)
Je re-formule mon énoncé :

[cpp]
(0,800)
|
| [x,y,v] [x,y,v] [x,y,v] [x,y,v] [x,y,v] [x,y,v] [x,y,v]
|
| [x,y,v] [x,y,v] [x,y,v] [x,y,v] [x,y,v] [x,y,v] [x,y,v]
|
| [x,y,v] [x,y,v] [x,y,v] [x,y,v] [x,y,v] [x,y,v] [x,y,v]
|
| [x,y,v] [x,y,v] [x,y,v] [x,y,v] [x,y,v] [x,y,v] [x,y,v]
|
| [x,y,v] [x,y,v] [x,y,v] [x,y,v] [x,y,v] [x,y,v] [x,y,v]
|
| [x,y,v] [x,y,v] [x,y,v] [x,y,v] [x,y,v] [x,y,v] [x,y,v]
|
| [x,y,v] [x,y,v] [x,y,v] [x,y,v] [x,y,v] [x,y,v] [x,y,v]
| ___________________
| [x,y,v] [x,y,v] [x,y,v] [x,y,v] [x,y,v] | [x,y,v] [x,y,v] |
| | | <------- (Zoom sur ce carré)
| [x,y,v] [x,y,v] [x,y,v] [x,y,v] [x,y,v] | [x,y,v] [x,y,v] |
___________________
(0,0) _____________________________________________________________ (700,0)
[/cpp]

[cpp]
[x,y, v] [x,y,v]
^
|______________________________ V = valeur du pixel, soit : Color(r,g,b)

o <------------------------------- Pixel à calculer


[x,y,v] [x,y,v]
[/cpp]

Je prend donc la valeur (Color) des 4 angles, et j'applique la matrice ... c'est ça ?
Donc :
[cpp]
# C3(t) = at3 - 2at2 + at
# C2(t) = (a+2)t3 - (a+3)t2 + 1
# C1(t) = -(a+2)t3 + (2a+3)t2 - at
# C0(t) = -at3 + at2
[/cpp]
t = x,y ?
a = ? :(
Et quand j'ai calculer C0...3, celà me donne quoi ? La valeur (Color) du pixel o ? Mais où est-ce que les valeurs des 4 points autour entrent-ils en compte ? :pt1cable:

Je reprend la méthode cubique (wikipedia)
[cpp]
double interpolationCubique(double y0,double y1,double y2,double y3,double mu)
{
double a0,a1,a2,a3,mu2;

mu2 = mu*mu;
a0 = y3 - y2 - y0 + y1;
a1 = y0 - y1 - a0;
a2 = y2 - y0;
a3 = y1;

return (a0*mu*mu2+a1*mu2+a2*mu+a3);
}

[/cpp]
Quelle est la différence entre la "bi"cubique ?
Il y a ici 4y, qui doivent correspondre surement à mes 4 valeurs de couleur non ? Si c'est le cas, où gère t'on les coordonnées ? Car la couleur dépend aussi des coordonnées du pixel pour pouvoir l'interpoler (plus il est loin de telle ou telle valeur, moins cette valeur aura d'impact sur le pixel en question et vice versa ...)

C'est un grand cafouillage :( je sais pas si c'est moi, ou si c'est dure à comprendre, mais j'ai du mal, pfouaa
Je vais me replonger dedans,
En tout cas merci pour vos réponses, et futures réponses ;)
 

guillaumech

Expert
Me revoilà. J'ai cherché, en vain ... J'ai utilisé la méthode bilinéaire (selon les 4 points autours), puis une matrice (gauss) de convultion pour casser les formes carrés. Mais le résultat n'est pas satisfaisant :(

Je reformule le problème, si défois qqun tombe dessus et arrive à trouver une réponse ;)

[a] [?] [?] [?] [?] [?] [b] [?] [?] [?] [?] [?] [c] [?] [?] [?] [?] [?] [d] [?] [?] [?] [?] [?] [e]
[?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?]
[?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?]
[?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?]
[?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?]
[?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?]
[f ] [?] [?] [?] [?] [?] [g] [?] [?] [?] [?] [?] [h] [?] [?] [?] [?] [?] [i ] [?] [?] [?] [?] [?] [j ]
[?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?]
[?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?]
[?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?]
[?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?]
[?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?]
[k] [?] [?] [?] [?] [?] [l] [?] [?] [?] [?] [?] [m] [?] [?] [?] [?] [?] [n] [?] [?] [?] [?] [?] [o]
[?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?]
[?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?]
[?] [?] [?] [?] [?] [?] [?] [?] [z] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?]
[?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?]
[?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?]
[p] [?] [?] [?] [?] [?] [q] [?] [?] [?] [?] [?] [r ] [?] [?] [?] [?] [?] [s] [?] [?] [?] [?] [?] [t ]
[?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?]
[?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?]
[?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?]
[?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?]
[?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?] [?]
[u] [?] [?] [?] [?] [?] [v] [?] [?] [?] [?] [?] [w] [?] [?] [?] [?] [?] [x] [?] [?] [?] [?] [?] [y]

Tout les points [a.....y] sont connus et fixes. Il me faut calculer les points intermédiaires (comme le [z]).
Color z = ??????


Merci beaucoup pour vos réponses.
Guich
 
Vous devez vous inscrire ou vous connecter pour répondre ici.
Derniers messages publiés
Statistiques globales
Discussions
730 098
Messages
6 717 071
Membres
1 586 286
Dernier membre
petitangebleu1977
Partager cette page
Haut