
Quelques propositions concernant la facon simple et claire d'ecrire des algorithmes de traitement d'images : 1) Points, voisins et Dpoints. On voudrait acceder a un voisin particulier d'un point p. Actuellement, on peut faire : oln_type_of(I, point) p2(p.row() + 1, p.col()); -> syntaxe lourde on peut aussi faire ca plus proprement en passant par un dpoint oln_type_of(I, dpoint) dp(-1, 0); et ainsi effectuer une operation du type 'dp + p'. On aimerait peut-etre acceder a un point voisin de facon plus simple en equipant la classe 'point' du methode par exemple 'dp' qui declare le dpoint et effectue le calcul pour nous. Ex: ima[p.dp(-1,0)] -> on accede directement au point p translate du dpoint (-1, 0). 2) Sous-image. Il est parfois (souvent) genant de devoir soit rajouter un parametre de masquage a nos algorithmes soit creer une sous-image de notre image manuellement. Ex: on voudrait lancer un algorithme sous une sous-image de notre image I. Actuellement, on passe par un masque, ou on creer une sous-image manuellement. Contraintes : - La fenetre peut bien sur ne pas etre rectangulaire (c'est plus souvent une zone correspondant a un objet de notre image par exemple). - on souhaite pouvoir acceder a la bordure exterieure de notre fenetre. Ecrire une methode permettant de creer une fenetre simplement est assez difficile, pour l'instant je vois la solution de creer un masque et ainsi de creer une image morpher a partir de notre image de base et de notre masque. 3) Image de type structure. On souhaite souvent creer une image de vecteur, pour l'instant on passe par le vector de la STL puis on est oblige de passer par une methode .at('point') pour lancer une methode de notre type structure. Ex : ima.at(p).push_back(3); On aimerait avoir acces a des types vecteurs directement dans Olena, et donc ecrire la ligne du dessus plus simplement : ima[p].x = 3; 4) point-wise. On aimerait aussi pouvoir declarer un calcul sur un point de facon point-wise. Ex : pw(gradient, ima[p.dp(-1,0)] - ima[p.dp(0,1)]); //on declare la facon de calculer notre gradient dans une image. puis lorsque on fait appel a gradient[p], on calcule seulement a ce moment le gradient au point p. 5) Range des valeurs de notre image. On aimerait pouvoir modifier le range des valeurs de notre image simplement, ce qui revient effectuer un seuillage des valeurs min et max. ima.range().set_min(0); ima.range().set_max(255); ... FIXME : j'ai peut-etre oublie d'autres elements. -- Nicolas Widynski CSI 2007

Nicolas Widynski wrote:
Quelques propositions concernant la facon simple et claire d'ecrire des algorithmes de traitement d'images :
1) Points, voisins et Dpoints.
On voudrait acceder a un voisin particulier d'un point p. Actuellement, on peut faire : oln_type_of(I, point) p2(p.row() + 1, p.col()); -> syntaxe lourde
on peut aussi faire ca plus proprement en passant par un dpoint oln_type_of(I, dpoint) dp(-1, 0); et ainsi effectuer une operation du type 'dp + p'.
On aimerait peut-etre acceder a un point voisin de facon plus simple en equipant la classe 'point' du methode par exemple 'dp' qui declare le dpoint et effectue le calcul pour nous. Ex: ima[p.dp(-1,0)] -> on accede directement au point p translate du dpoint (-1, 0).
2) Sous-image.
Il est parfois (souvent) genant de devoir soit rajouter un parametre de masquage a nos algorithmes soit creer une sous-image de notre image manuellement. Ex: on voudrait lancer un algorithme sous une sous-image de notre image I.
Actuellement, on passe par un masque, ou on creer une sous-image manuellement.
Contraintes : - La fenetre peut bien sur ne pas etre rectangulaire (c'est plus souvent une zone correspondant a un objet de notre image par exemple). - on souhaite pouvoir acceder a la bordure exterieure de notre fenetre.
Ecrire une methode permettant de creer une fenetre simplement est assez difficile, pour l'instant je vois la solution de creer un masque et ainsi de creer une image morpher a partir de notre image de base et de notre masque.
3) Image de type structure.
On souhaite souvent creer une image de vecteur, pour l'instant on passe par le vector de la STL puis on est oblige de passer par une methode .at('point') pour lancer une methode de notre type structure. Ex : ima.at(p).push_back(3);
On aimerait avoir acces a des types vecteurs directement dans Olena, et donc ecrire la ligne du dessus plus simplement : ima[p].x = 3;
4) point-wise.
On aimerait aussi pouvoir declarer un calcul sur un point de facon point-wise. Ex : pw(gradient, ima[p.dp(-1,0)] - ima[p.dp(0,1)]); //on declare la facon de calculer notre gradient dans une image. puis lorsque on fait appel a gradient[p], on calcule seulement a ce moment le gradient au point p.
5) Range des valeurs de notre image.
On aimerait pouvoir modifier le range des valeurs de notre image simplement, ce qui revient effectuer un seuillage des valeurs min et max. ima.range().set_min(0); ima.range().set_max(255);
... FIXME : j'ai peut-etre oublie d'autres elements.
6) Outil de visualisation d'images Util pour le debugage. Visualisation graphique de l'image et son evolution au cours de l'algo (tracabilite) (on peut rever ;)). -- Widynski Nicolas CSI 2007

Nicolas Widynski <widyns_n@lrde.epita.fr> writes:
Quelques propositions concernant la facon simple et claire d'ecrire des algorithmes de traitement d'images :
J'ai quelques remarques, sur les points que tu présentes
1) Points, voisins et Dpoints.
On voudrait acceder a un voisin particulier d'un point p. Actuellement, on peut faire : oln_type_of(I, point) p2(p.row() + 1, p.col()); -> syntaxe lourde
on peut aussi faire ca plus proprement en passant par un dpoint oln_type_of(I, dpoint) dp(-1, 0); et ainsi effectuer une operation du type 'dp + p'.
On aimerait peut-etre acceder a un point voisin de facon plus simple en equipant la classe 'point' du methode par exemple 'dp' qui declare le dpoint et effectue le calcul pour nous. Ex: ima[p.dp(-1,0)] -> on accede directement au point p translate du dpoint (-1, 0).
Je trouve que ce n'est que du sucre syntaxique, utile pour les gens que ne codent pas d'algo de façon générique (on a plus d'abstraction de dimension dans l'exemple que tu donnes). Je pense personnellement (ca n'engage que moi bien sûr) qu'utiliser des dpoints (avec un voisinage pour les mettre dedans) reste assez propre et permet d'avoir une bonne abstraction, de plus ce n'est pas quelque chose de complètement tordu pour un utilisateur basique.
2) Sous-image.
Il est parfois (souvent) genant de devoir soit rajouter un parametre de masquage a nos algorithmes soit creer une sous-image de notre image manuellement. Ex: on voudrait lancer un algorithme sous une sous-image de notre image I.
Actuellement, on passe par un masque, ou on creer une sous-image manuellement.
Contraintes : - La fenetre peut bien sur ne pas etre rectangulaire (c'est plus souvent une zone correspondant a un objet de notre image par exemple). - on souhaite pouvoir acceder a la bordure exterieure de notre fenetre.
Ecrire une methode permettant de creer une fenetre simplement est assez difficile, pour l'instant je vois la solution de creer un masque et ainsi de creer une image morpher a partir de notre image de base et de notre masque.
J'approuve :-)
3) Image de type structure.
On souhaite souvent creer une image de vecteur, pour l'instant on passe par le vector de la STL puis on est oblige de passer par une methode .at('point') pour lancer une methode de notre type structure. Ex : ima.at(p).push_back(3);
On aimerait avoir acces a des types vecteurs directement dans Olena, et donc ecrire la ligne du dessus plus simplement : ima[p].x = 3;
J'avoue ne pas tout saisir là. Des types vecteurs sont déjà dispo dans olena (au moins la 0.10). Je ne vois pas non plus pourquoi on doit utiliser une méthode at et non pas l'opérateur [] dans le cas d'utilisation de stl (j'ai sûrement loupé quelque chose).
4) point-wise.
On aimerait aussi pouvoir declarer un calcul sur un point de facon point-wise. Ex : pw(gradient, ima[p.dp(-1,0)] - ima[p.dp(0,1)]); //on declare la facon de calculer notre gradient dans une image. puis lorsque on fait appel a gradient[p], on calcule seulement a ce moment le gradient au point p.
C'est une espèce de lazzy morpher non ? (un morpher qui prend une image et un functor)
5) Range des valeurs de notre image.
On aimerait pouvoir modifier le range des valeurs de notre image simplement, ce qui revient effectuer un seuillage des valeurs min et max. ima.range().set_min(0); ima.range().set_max(255);
Là non plus je ne comprends pas tout. C'est quoi le but de la manip ? faire un stretch ? Si oui, il existe des algo SÉPARÉ la classe image pour le faire. J'insiste sur le séparé car il se passe quoi si on est pas sur un type scalaire. Si c'est juste pour faire des checks, il y a les types integre.
... FIXME : j'ai peut-etre oublie d'autres elements.
voili voilou -- Giovanni Palma EPITA - promo 2005 - LRDE Mob. : +33 (0)6 60 97 31 74

Giovanni Palma wrote:
Nicolas Widynski <widyns_n@lrde.epita.fr> writes:
Quelques propositions concernant la facon simple et claire d'ecrire des algorithmes de traitement d'images :
J'ai quelques remarques, sur les points que tu présentes
1) Points, voisins et Dpoints.
On voudrait acceder a un voisin particulier d'un point p. Actuellement, on peut faire : oln_type_of(I, point) p2(p.row() + 1, p.col()); -> syntaxe lourde
on peut aussi faire ca plus proprement en passant par un dpoint oln_type_of(I, dpoint) dp(-1, 0); et ainsi effectuer une operation du type 'dp + p'.
On aimerait peut-etre acceder a un point voisin de facon plus simple en equipant la classe 'point' du methode par exemple 'dp' qui declare le dpoint et effectue le calcul pour nous. Ex: ima[p.dp(-1,0)] -> on accede directement au point p translate du dpoint (-1, 0).
Je trouve que ce n'est que du sucre syntaxique, utile pour les gens que ne codent pas d'algo de façon générique (on a plus d'abstraction de dimension dans l'exemple que tu donnes). Je pense personnellement (ca n'engage que moi bien sûr) qu'utiliser des dpoints (avec un voisinage pour les mettre dedans) reste assez propre et permet d'avoir une bonne abstraction, de plus ce n'est pas quelque chose de complètement tordu pour un utilisateur basique.
Exact. La solution est mauvaise. Cependant, d'un point de vue utilisateur, la syntaxe est lourde et peu intuitive. On est oblige de modifier entre chaque operation le dpoint pour acceder a un autre point voisin. Ca parait evident dit comme ca, mais ca reste tout de meme assez lourd.
[...]
3) Image de type structure.
On souhaite souvent creer une image de vecteur, pour l'instant on passe par le vector de la STL puis on est oblige de passer par une methode .at('point') pour lancer une methode de notre type structure. Ex : ima.at(p).push_back(3);
On aimerait avoir acces a des types vecteurs directement dans Olena, et donc ecrire la ligne du dessus plus simplement : ima[p].x = 3;
J'avoue ne pas tout saisir là. Des types vecteurs sont déjà dispo dans olena (au moins la 0.10). Je ne vois pas non plus pourquoi on doit utiliser une méthode at et non pas l'opérateur [] dans le cas d'utilisation de stl (j'ai sûrement loupé quelque chose).
Ca change avec le proto 1.0. ima[p] renvoie un nouvel objet, il n'y a pas de version avec reference. ima.at(p) renvoie une ref.
[...]
5) Range des valeurs de notre image.
On aimerait pouvoir modifier le range des valeurs de notre image simplement, ce qui revient effectuer un seuillage des valeurs min et max. ima.range().set_min(0); ima.range().set_max(255);
Là non plus je ne comprends pas tout. C'est quoi le but de la manip ? faire un stretch ? Si oui, il existe des algo SÉPARÉ la classe image pour le faire. J'insiste sur le séparé car il se passe quoi si on est pas sur un type scalaire. Si c'est juste pour faire des checks, il y a les types integre.
J'ai rien dit. -- Nicolas Widynski CSI Promo 2007

Nicolas Widynski <widyns_n@lrde.epita.fr> writes:
Giovanni Palma wrote:
Nicolas Widynski <widyns_n@lrde.epita.fr> writes:
Quelques propositions concernant la facon simple et claire d'ecrire des algorithmes de traitement d'images :
J'ai quelques remarques, sur les points que tu présentes
1) Points, voisins et Dpoints.
On voudrait acceder a un voisin particulier d'un point p. Actuellement, on peut faire : oln_type_of(I, point) p2(p.row() + 1, p.col()); -> syntaxe lourde
on peut aussi faire ca plus proprement en passant par un dpoint oln_type_of(I, dpoint) dp(-1, 0); et ainsi effectuer une operation du type 'dp + p'.
On aimerait peut-etre acceder a un point voisin de facon plus simple en equipant la classe 'point' du methode par exemple 'dp' qui declare le dpoint et effectue le calcul pour nous. Ex: ima[p.dp(-1,0)] -> on accede directement au point p translate du dpoint (-1, 0).
Je trouve que ce n'est que du sucre syntaxique, utile pour les gens que ne codent pas d'algo de façon générique (on a plus d'abstraction de dimension dans l'exemple que tu donnes). Je pense personnellement (ca n'engage que moi bien sûr) qu'utiliser des dpoints (avec un voisinage pour les mettre dedans) reste assez propre et permet d'avoir une bonne abstraction, de plus ce n'est pas quelque chose de complètement tordu pour un utilisateur basique.
Exact. La solution est mauvaise.
Cependant, d'un point de vue utilisateur, la syntaxe est lourde et peu intuitive. On est oblige de modifier entre chaque operation le dpoint pour acceder a un autre point voisin. Ca parait evident dit comme ca, mais ca reste tout de meme assez lourd.
Oui et non, car si tu fait un push_back (ou l'équivalent, que je n'ai plus en tête) des dpoints que tu veux utiliser dans un neighborhood, tu peut itérer sur ton voisinage pour chaque points. Pour ma part je trouve ça assez élégant et peut contraignant (une ligne par dpoint que tu veux utiliser). Enfin peut être que mon jugement est biaisé ou que je ne vois pas un exemple simple où cette méthode est mauvaise.
[...]
3) Image de type structure.
On souhaite souvent creer une image de vecteur, pour l'instant on passe par le vector de la STL puis on est oblige de passer par une methode .at('point') pour lancer une methode de notre type structure. Ex : ima.at(p).push_back(3);
On aimerait avoir acces a des types vecteurs directement dans Olena, et donc ecrire la ligne du dessus plus simplement : ima[p].x = 3;
J'avoue ne pas tout saisir là. Des types vecteurs sont déjà dispo dans olena (au moins la 0.10). Je ne vois pas non plus pourquoi on doit utiliser une méthode at et non pas l'opérateur [] dans le cas d'utilisation de stl (j'ai sûrement loupé quelque chose). Ca change avec le proto 1.0. ima[p] renvoie un nouvel objet, il n'y a pas de version avec reference. ima.at(p) renvoie une ref.
[...]
5) Range des valeurs de notre image.
On aimerait pouvoir modifier le range des valeurs de notre image simplement, ce qui revient effectuer un seuillage des valeurs min et max. ima.range().set_min(0); ima.range().set_max(255);
Là non plus je ne comprends pas tout. C'est quoi le but de la manip ? faire un stretch ? Si oui, il existe des algo SÉPARÉ la classe image pour le faire. J'insiste sur le séparé car il se passe quoi si on est pas sur un type scalaire. Si c'est juste pour faire des checks, il y a les types integre.
J'ai rien dit.
-- Giovanni Palma EPITA - promo 2005 - LRDE Mob. : +33 (0)6 60 97 31 74

"Nicolas" == Nicolas Widynski <widyns_n@lrde.epita.fr> writes:
Quelques propositions concernant la facon simple et claire d'ecrire des algorithmes de traitement d'images :
1) Points, voisins et Dpoints.
On voudrait acceder a un voisin particulier d'un point p. Actuellement, on peut faire : oln_type_of(I, point) p2(p.row() + 1, p.col()); -> syntaxe lourde
on peut aussi faire ca plus proprement en passant par un dpoint oln_type_of(I, dpoint) dp(-1, 0); et ainsi effectuer une operation du type 'dp + p'.
On aimerait peut-etre acceder a un point voisin de facon plus simple en equipant la classe 'point' du methode par exemple 'dp' qui declare le dpoint et effectue le calcul pour nous. Ex: ima[p.dp(-1,0)] -> on accede directement au point p translate du dpoint (-1, 0).
Pas bête. :) Mais comme le souligne Giovanni, ça ne peut être que du sucre pour utilisateur final : ce type d'écriture interdit toute généricité. Sinon, je me demande si on ne pourrait pas surcharger les opérateurs plus et virgule pour écrire des choses comme ça : ima[p + 1,0] ;)
2) Sous-image.
Il est parfois (souvent) genant de devoir soit rajouter un parametre de masquage a nos algorithmes soit creer une sous-image de notre image manuellement. Ex: on voudrait lancer un algorithme sous une sous-image de notre image I.
Actuellement, on passe par un masque, ou on creer une sous-image manuellement.
Contraintes : - La fenetre peut bien sur ne pas etre rectangulaire (c'est plus souvent une zone correspondant a un objet de notre image par exemple). - on souhaite pouvoir acceder a la bordure exterieure de notre fenetre.
Ecrire une methode permettant de creer une fenetre simplement est assez difficile, pour l'instant je vois la solution de creer un masque et ainsi de creer une image morpher a partir de notre image de base et de notre masque.
L'approche morpher subset/mask dont on parle souvent me semble pas mal, mais c'est vrai qu'il faut écrire pas mal de code : typedef REPLACE_THIS_WITH_THE_RIGHT_MASKED_IMAGE_TYPE masked_image_type; masked_image_type masked_ima = add_mask(ima, mask); oln_type_of(masked_image_type, piter) p (masked_ima); for_all(p) { // ... } Peut-être qu'avec le mot-clef `typeof' (dont je ne sais pas s'il est bien supporté par tous les compilateurs, au passage), on pourrait écrire une macro for_all encore plus sucrée du type: for_all(p, ima | mask) { // ... } (mais c'est vraiment hypothétique !). (Vivement que le mot-clef `auto' soit accepté dans C++ 0x !).
3) Image de type structure.
On souhaite souvent creer une image de vecteur, pour l'instant on passe par le vector de la STL puis on est oblige de passer par une methode .at('point') pour lancer une methode de notre type structure. Ex : ima.at(p).push_back(3);
On aimerait avoir acces a des types vecteurs directement dans Olena, et donc ecrire la ligne du dessus plus simplement : ima[p].x = 3;
Ah oui, c'est vrai, ce truc est relou. :( On avait un peut discuté de ce point avec Théo, en particulier du fait que la value_box puisse être une « propriété » de l'image. Mais c'est pas simple...
4) point-wise.
On aimerait aussi pouvoir declarer un calcul sur un point de facon point-wise. Ex : pw(gradient, ima[p.dp(-1,0)] - ima[p.dp(0,1)]); //on declare la facon de calculer notre gradient dans une image. puis lorsque on fait appel a gradient[p], on calcule seulement a ce moment le gradient au point p.
Un morpher devrait pouvoir faire cela. Je dis peut-être une bêtise, mais les point-wise functions sont censées travailler sur des images de support théoriques de tailles identiques ou compatibles, donc je pense qu'elles sont hors-sujet ici.
5) Range des valeurs de notre image.
On aimerait pouvoir modifier le range des valeurs de notre image simplement, ce qui revient effectuer un seuillage des valeurs min et max. ima.range().set_min(0); ima.range().set_max(255);
C'est plus qu'un seuillage, c'est un changement de contraste, non ? À moins que tu ne souhaites étirer/rétrécir les valeurs de ton image entre deux bornes (cf. fonctions stretch et stretch_balance de Olena 0.10) ? Dans les deux cas, j'ai l'impression que tu veux voir ton image à travers une fonction (qui modifie les valeurs de l'image de façon non point-wise, BTW). Donc a priori, c'est qqch que l'on veut faire avec un algo ou un morpher (éventuellement bijectif). Et Giovanni a raison : utiliser une méthode ici est anti-générique.
... FIXME : j'ai peut-etre oublie d'autres elements.
:) En tout cas, merci pour ces commentaires !
participants (3)
-
Giovanni Palma
-
Nicolas Widynski
-
Roland Levillain