HORNUS, Samuel (14 rue de la Légion Etrangère, Nancy, F-54000, FR)
LASRAM, Anass (150 avenue du Général Leclerc, Vandoeuvre-les-Nancy, F-54500, FR)
LEFEBVRE, Sylvain (18 route de St Héand, La Fouillouse, F-42480, FR)
HORNUS, Samuel (14 rue de la Légion Etrangère, Nancy, F-54000, FR)
LASRAM, Anass (150 avenue du Général Leclerc, Vandoeuvre-les-Nancy, F-54500, FR)
| Revendications 1 . - Dispositif de traitement d'image, caractérisé en ce qu'il comprend : - un analyseur (4) capable de calculer, à partir de données d'image, des données de coupure et des données de différence associées, les données de coupure comprenant des coordonnées de l'image et désignant une paire de chemins parallèles dans l'image, et les données de différence étant représentatives d'une différence entre des attributs des données d'image le long de chaque paire de chemins parallèles, - un sélectionneur (6) recevant en entrée des données d'un nœud de travail et des données de coupure, et agencé pour en tirer des données de nœuds dits successeurs sur la base d'une règle de sélection, les données d'un nœud comprenant des données de coupure, des données de coût, et des données de position, - un assembleur (8) recevant en entrée des données de nœuds de travail et des données d'un nœud prédécesseur, et capable de calculer des données de nœuds mis à jour, en fonction des données de coût de certains au moins des nœuds de travail, de celles du nœud prédécesseur, et des données de différence associées aux données de coupure des nœuds de travail, - un pilote (1 1 ) agencé pour : * appeler l'analyseur (4) avec des données d'image d'une image en entrée, * appeler le sélectionneur (6) avec un nœud d'entrée comme nœud de travail et avec les données de coupure calculées par l'analyseur (4), * appeler l'assembleur (8) avec certains au moins des nœuds successeurs déterminés par le sélectionneur (6) comme nœuds de travail, et avec le nœud d'entrée comme nœud prédécesseur, et * appeler répétitivement le sélectionneur (6) et l'assembleur (8), en utilisant un des nœuds mis à jour comme nœud de travail pour le sélectionneur (6), en utilisant les nœuds successeurs résultants de cet appel comme nœuds de travail et le nœud mis à jour comme nœud prédécesseur pour l'assembleur (8), jusqu'à ce qu'une condition portant sur les données de coupure et les données de position d'un nœud mis à jour soit remplie 2. - Dispositif selon la revendication 1 , dans lequel les don nées de nœud comprennent également des données de prédécesseur, et dans lequel l'assembleur (8) est agencé pour mettre à jour les données de coût d'un nœud de travail donné lorsque les données de coût du nœud de travail donné définissent une valeur supérieure à la somme de la valeur définie par les données de coût du nœud prédécesseur ajoutée de la valeur définie par les données de différence associant le nœud de travail donné et le nœud prédécesseur. 3. - Dispositif selon la revendication 2, dans lequel lors de l'appel répété du sélectionneur et de l'assembleur, le nœud mis à jour utilisé est celui présentant les données de coût désignant le coût le plus faible. 4. - Dispositif selon la revendication 3, dans lequel la règle de sélection comprend la sélection d'un nœud successeur dont les données de coupure désignent le chemin qui forme une paire avec le chemin désigné par les données de coupure du nœud de travail, et dont les données de position sont identiques à celles du nœud de travail. 5. - Dispositif selon la revendication 4, dans lequel la règle de sélection comprend en outre la sélection d'au moins un nœud successeur dont les données de coupure désignent un chemin parmi l'ensemble des chemins frontaux du chemin désigné par les données de coupure du nœud de travail. 6. - Dispositif selon la revendication 4 ou 5, dans lequel la règle de sélection exclut la sélection d'un nœud successeur comprenant des données de coupure associées à une partie de l'image qui est déjà associée à des données de coupure d'un nœud désigné directement ou indirectement par les données de prédécesseur du nœud de travail donné lorsque les données de position respectives de ces nœuds indiquent une différence de position inférieure à un seuil choisi. 7. - Dispositif selon la revendication 6, dans lequel, pour appliquer la règle de sélection, l'assembleur (8) maintient un tableau contenant des données d'occurrences de colonnes de l'image en fonction des données de position et des données de coupure et des données de prédécesseur associées à un nœud de travail donné. 8.- Dispositif selon l'une des revendications précédentes, dans lequel les données de coupure sont associées à une direction parmi deux directions non parallèles dans l'image, et dans lequel le pilote (1 1 ) est agencé pour opérer d'abord avec les données de coupure associées à une première des deux directions jusqu'à que la condition portant sur les données de coupure et les données de position d'un nœud mis à jour soit remplie, puis pour opérer avec les données de coupure associées à une deuxième des deux directions jusqu'à ce qu'une deuxième condition portant sur les données de coupure et les données de position d'un nœud mis à jour soit remplie. 9.- Dispositif selon la revendication 8, dans lequel le pilote (1 1 ) appelle l'assembleur (8) après que la condition portant sur les données de coupure et les données de position d'un nœud mis à jour soit remplie, pour appliquer aux données de coupure associées à la deuxième direction une transformation tirée des données de coupure associées au dernier nœud mis à jour et aux nœuds désignés par ses données de prédécesseur. 10.- Procédé de traitement d'image comprenant, pour une image reçue en entrée : a. le calcul de données de coupure et de données de différence associées, les données de coupure comprenant des coordonnées de l'image et désignant une paire de chemins parallèles dans l'image, et les données de différence étant représentatives d'une différence entre des attributs des données d'image le long de chaque paire de chemins parallèles, b. la sélection, à partir de données d'un nœud d'entrée et des données de coupure issues de l'étape a., de données de nœuds dits successeurs sur la base d'une règle de sélection, les données d'un nœud comprenant des données de coupure, des données de coût, et des données de position, c. la mise à jour, à partir des données de nœuds successeurs de l'étape b. et des données du nœud d'entrée, des données de nœuds successeurs, en fonction des données de coût de certains au moins des nœuds successeurs, de celles du nœud d'entrée, et des données de différence associées aux données de coupure des nœuds successeurs, la répétition des étapes b. et c, avec un des nœuds mis à jour comme entrée pour l'étape b., et avec les nœuds successeurs résultants et ce nœud mis à jour comme entrées pour l'étape c, jusqu'à ce qu'une condition portant sur les données de coupure et les données de position d'un nœud mis à jour soit remplie. |
L'invention concerne la synthèse d'images. Dans l'informatique moderne, les capacités de calcu l ont augmenté de man ière exponentielle, jusqu'à permettre maintenant l'immersion dans des univers en trois dimensions.
La gestion de ces univers et la recherche de les rendre toujours plus réalistes pour les utilisateurs sont néanmoins en conflit avec le temps nécessaire à la création de ces univers, ainsi qu'avec les limitations techniques notamment en termes de capacité et d'accès mémoire.
Pour gérer ce problème, des systèmes ont été conçus qui utilisent des stocks limités d'images qui sont manipulées pour donner une illusion de variété, par exemple en appliquant ces images sur les surfaces tridimensionnelles pour leur donner une apparence variée.
Cependant, la qualité des images résultantes est insatisfaisante si les images sont réutilisées sur des surfaces variées. D'autre part, si l'on veut adapter chaque image à sa surface support pour améliorer la qualité, il est nécessaire de stocker individuellement toutes les images résultantes, ce qui est un gâchis manifeste d'espace de stockage.
L'invention vient améliorer la situation.
À cet effet, l'invention propose un dispositif de traitement d'image, qui comprend :
- un analyseur capable de calculer, à partir de données d'image, des données de coupure et des données de différence associées, les données de coupure comprenant des coordonnées de l'image et désignant une paire de chemins parallèles dans l'image, et les données de différence étant représentatives d'une différence entre des attributs des données d'image le long de chaque paire de chemins parallèles, - un sélectionneur recevant en entrée des données d'un nœud de travail et des données de coupure, et agencé pour en tirer des données de nœuds dits successeurs sur la base d'une règle de sélection, les données d'un nœud comprenant des données de coupure, des données de coût, et des données de position,
- un assembleur recevant en entrée des données de nœuds de travail et des données d'un nœud prédécesseur, et capable de calculer des données de nœuds mis à jour, en fonction des données de coût de certains au moins des nœuds de travail, de celles du nœud prédécesseur, et des données de différence associées aux données de coupure des nœuds de travail,
- un pilote agencé pour :
* appeler l'analyseur avec des données d'image d'une image en entrée,
* appeler le sélectionneur avec un nœud d'entrée comme nœud de travail et avec les données de coupure calculées par l'analyseur,
* appeler l'assembleur avec certains au moins des nœuds successeurs déterminés par le sélectionneur comme nœuds de travail, et avec le nœud d'entrée comme nœud prédécesseur, et
* appeler répétitivement le sélectionneur et l'assembleur, en utilisant un des nœuds mis à jour comme nœud de travail pour le sélectionneur, en utilisant les nœuds successeurs résultants de cet appel comme nœuds de travail et le nœud mis à jour comme nœud prédécesseur pour l'assembleur, jusqu'à ce qu'une condition portant sur les données de coupure et les données de position d'un nœud mis à jour soit remplie.
Ce dispositif et ce procédé sont très intéressants car ils permettent de générer de nouvelles images similaires aux images de référence, mais dont les tailles sont adaptées à leur surface support.
Par exemple, si l'on applique une image de façade de trois étages sur une face d'un bâtiment de quatre étages on observera une distorsion. Grâce à l'invention, une nouvelle image de façade, ressemblant à l'originale mais ayant le bon nombre d'étages sera générée. De plus, son stockage et son affichage se feront sous une forme très compacte. Au demeurant, l'invention ne se limite pas aux façades mais s'applique à toute image présentant suffisamment de répétitions selon des translations horizontales ou verticales. D'autres caractéristiques et avantages de l'invention apparaîtront mieux à la lecture de la description qui suit, tirée d'exemples donnés à titre illustratif et non limitatif, tirés des dessins sur lesquels
- la figure 1 représente un diagramme schématique d'un dispositif selon l'invention,
- la figure 2 représente un diagramme schématique de synthèse d'une image avec le dispositif de la figure 1 ,
- la figure 3 représente un exemple d'opérations réalisées par le dispositif de la figure 1 selon la figure 2,
- la figure 4 représente un diagramme de flux de la mise en œuvre d'une autre partie de la figure 2 par le dispositif de la figure 1 ,
- la figure 5 représente un exemple de coupures selon l'invention,
- la figure 6 représente une variante du diagramme de la figure 3, et
- la figure 7 représente une variante de la figure 1 dans laquelle le dispositif est utilisé pour créer un ensemble d'images pour simuler une ville en trois dimensions. Les dessins et la description ci-après contiennent, pour l'essentiel, des éléments de caractère certain. Ils pourront donc non seulement servir à mieux faire comprendre la présente invention, mais aussi contribuer à sa définition, le cas échéant.
La présente description est de nature à faire intervenir des éléments susceptibles de protection par le droit d'auteur et/ou le copyright. Le titulaire des droits n'a pas d'objection à la reproduction à l'identique par quiconque du présent document de brevet ou de sa description, telle qu'elle apparaît dans les dossiers officiels. Pour le reste, il réserve intégralement ses droits. La figure 1 représente un diagramme schématique d'un dispositif 2 selon l'invention. Dans l'exemple décrit ici, le dispositif 2 reçoit en entrée une image de taille MxN ainsi qu'une largeur cible W, et produit en sortie une image de taille WxN ressemblant à l'image d'entrée. Le dispositif 2 comprend un analyseur 4, un sélectionneur 6, un assembleur 8, une base de règles 10, et un pilote 1 1 pour les commander.
Comme cela apparaît sur la figure 2, le dispositif 2 reçoit une image d'entrée 12. Dans une première opération, le dispositif 2 appelle l'analyseur 4 avec l'image d'entrée 12. À l'issue de cette opération, l'analyseur 4 produit un fichier qui comprend des données définissant un plan de découpe de l'image d'entrée.
Le plan de découpe comprend une liste de suites de coordonnées dans l'image, chaque suite définissant un chemin dans l'image d'entrée. Pour matérialiser ce plan de découpe, une image 1 4 est représentée sur laquelle les chemins du plan de découpe sont représentés en superposition sur l'image d'entrée 12.
Chaque ligne brisée a au moins une autre ligne brisée qui lui est parallèle: il est possible de les superposer exactement. Cette correspondance est enregistrée dans le fichier produit par l'analyseur 4.
Ces lignes brisées seront dans ce qui suit désignées par le terme "coupure", et dans l'exemple décrit ici, elles sont orientées verticalement par rapport à l'affichage de l'image: chaque coupure sépare l'image en deux parties gauche et droite.
La figure 3 représente un exemple de mise en œuvre de l'analyseur 4.
L'analyseur 4 recherche des paires de chemins entre le bord haut et le bord bas de l'image, telles que les deux chemins soient strictement parallèles et aient des couleurs similaires. Les deux chemins recherchés étant parallèles, il est possible de les superposer exactement par une translation T. Ces chemins sont nommés "coupures" car il est possible de découper l'image le long de ces deux chemins afin d'en enlever un morceau, ou d'en répéter un morceau.
Le coût (ou qualité) du recollement, c'est-à-dire la possibilité pour un utilisateur de percevoir un défaut visuel, dépend de la similarité entre les couleurs le long de la paire de chemins. II existe un grand nombre de paires de coupures possible séparées de distances différentes et proposant des qualités de recollement variables.
Bien qu'il soit possible d'utiliser des coupures de formes quelconques, le Demandeur a choisi de restreindre la recherche des coupures à des chemins de forme simple, afin de simplifier leur stockage. En particulier, une coupure avance toujours strictement du haut vers le bas et ne peut se déplacer au plus que d'un pixel en abscisse à chaque pixel descendu en ordonnée.
La recherche des coupures est une étape importante : un nombre trop important de coupures alourdirait inutilement le traitement alors qu'un nombre trop faible de coupures empêcherait l'assembleur 8 de produire des images synthétisées de bonne qualité.
L'analyseur 4 de l'exemple décrit ici est un compromis entre l'obtention de coupures parallèles de bonne qualité (c'est-à-dire présentant une faible différence de couleurs) et l'obtention d'une bonne répartition de coupures dans l'image, afin que l'assembleur 8 ait suffisamment de choix.
L'analyseur 4 reçoit en entrée une image Img de taille MxN et produit en sortie une pluralité de coupures parallèles dans un fichier Cuts. L'analyseur 4 met en œuvre un algorithme qui exécute une boucle globale dont chaque itération exécute une pluralité de boucles locales. Pour cela, un indice de largeur T variant entre 1 et M-1 , est initialisé dans une opération 300. Dans une opération 302, il est vérifié si T vaut M-1 , ce qui signifierait que toutes les largeurs possibles ont été testées. Si c'est le cas, alors l'algorithme se termine dans une opération 304.
Les opérations 306 à 31 6 décrivent l'exécution d'une itération de la boucle globale. Chaque itération de la boucle globale trouve, pour chaque largeur T possible, un ensemble de coupures parallèles qui ne se croisent pas pour cette largeur. On notera cependant que des coupures associées à deux largeurs différentes, et donc déterminées dans des itérations distinctes de la boucle globale, peuvent se croiser. Le principe de découverte d'une paire de coupures parallèles est d'utiliser une carte de différence Diff, et de trouver dans cette carte un chemin unique. Pour cela la carte Diff est calculée dans l'opération 306 comme la différence de couleur entre les pixels de l'image Img et ceux de sa translation de T pixels vers la droite. En variante, d'autres attributs des données de l'image pourraient être retenus, comme la chrominance, ou la luminosité, ou encore la saturation.
Un chemin dans la carte Diff correspond donc à deux chemins dans l'image Img :
- un premier chemin qui a les mêmes coordonnées que le chemin de Diff, et
- un deuxième chemin, décalé de T pixels vers la gauche dans l'image Img.
Ces deux chemins sont parallèles par construction. La correspondance de couleur entre ces chemins correspond à la somme des valeurs de couleur des pixels le long du chemin dans la carte Diff. Cette somme correspond concrètement à la somme des différences entre les pixels de long du chemin, c'est à dire le coût du chemin. Chaque boucle locale est formée par les opérations 308 à 314, et vient choisir un chemin P dans la carte Diff , et stocker les coupures correspondantes dans le fichier Cuts. Pou r savoi r s' i l reste des cou pu res à trouver po u r la largeu r T cou rante , u ne fonction Pth() est appelée dans l'opération 308. Cette fonction va chercher dans la carte Diff tous les chemins possibles selon la règle décrite plus haut, c'est-à-dire toujours strictement du haut vers le bas et sans déplacement de plus d'un pixel en abscisse à chaque pixel descendu en ordonnée, et ne retient que les chemins qui n'ont pas un coût dit infini. La notion de coût infini sera clarifiée plus bas.
Si la fonction Pth() ne trouve aucun chemin, alors la boucle globale a terminé son itération courante, et l'indice T est incrémenté dans une opération 316, puis la boucle globale reprend en 302.
Sinon, dans l'opération 310, la fonction Min() renvoie le chemin P de la carte Diff qui a le coût le plus faible. Ensuite, dans une opération 314, les coupures correspondant au chemin P sont stockées dans le fichier Cuts, avec le coût associé au chemin P. Enfin, dans l'opération 316, une fonction Kill() vient modifier tous les pixels de la carte Diff compris entre le chemin P et le chemin P décalé de T pixels à droite et à gauche pour donner une valeur indiquant un coût infini. Cette valeur peut être choisie arbitrairement ou être un signe particulier. Le rôle de la fonction Kill() est de garantir que toutes les boucles locales ultérieures à la boucle locale courante produiront des coupures non sécantes à celles déterminées précédemment. Et comme dans le pire des cas, le chemin P fait T pixels de large, on élimine des boucles locales suivantes, les T pixels suivant P en leur affectant un coût infini.
Cela permet de ne pas accumuler inutilement trop de coupures parallèles dans une même région de l'image. L'opération 31 0 garantit que seule la meilleure paire de coupures possible est retenue pour la largeur T, c'est-à-dire celle qui a le plus petit coût. L'algorithme trouve donc un bon compromis entre les objectifs de qualité et de quantité des coupures. Comme on l'a vu plus haut, le coût correspond à la somme des différences entre les couleurs de pixels associés aux deux chemins parallèles (plus généralement à la différence d'attribut d'image si un autre attribut que la couleur est retenu). Deux coupures non parallèles ne sont pas superposables, et donc pas comparables. De plus, comme on le verra dans la suite, le fait d'associer deux coupures non parallèles n'induit pas de différence visuelle. Pour cette raison, le coût associant deux coupures non parallèles est défini comme nul.
Dans l'exemple décrit ici, il n'existe de données de coût que pour les coupures parallèles, et toutes les autres associations de coupure ont un coût nul implicite. En variante, cela pourrait être explicite.
On suppose que les coupures parallèles ne sont jamais de coût nul (i.e. il n'existe pas de correspondance parfaite). Ceci peut être garanti en ajoutant une faible valeur non nulle au coût de correspondance de toutes les paires de coupures parallèles. En pratique ce cas est très rare, sauf sur des images artificielles. D'autres stratégies sont possibles pour éviter ce problème.
Par coupure sécante, on entend ici le fait qu'il existe une portion de l'image originale dans laquelle l'abscisse de la première coupure est inférieure à celle de la deuxième coupure, et une autre portion de cette image dans laquelle l'abscisse de la deuxième coupure est inférieure à celle de la première coupure. En d'autres termes, lorsque l'on regarde les "chemins" associés à ces coupures, ils se coupent. Pour une coupure donnée, il existe un jeu de coupures qui est particulièrement intéressant. Ce jeu comprend des coupures dites "frontales". Une coupure est dite frontale par rapport à une coupure donnée si la coupure frontale est entièrement située à droite de la coupure donnée et s'il n'existe aucune autre coupure qui est intégralement située entre elle et la coupure donnée. Par intégralement située entre, on entend qu'il n'existe pas de coupures dont tous les points sont strictement situés entre ceux de la coupure donnée et ceux de la coupure frontale. Plusieurs coupures sécantes entre elles peuvent être frontales par rapport à une coupure don née. Comme on le verra plus bas, cette sélection de coupures frontales est importante pour trouver plus efficacement la solution. En effet, elles vont permettre de réduire le nombre de possibilités examinées, tandis que leur définition garantit qu'aucune solution possible n'est écartée.
La figure 5 permet de mieux comprendre la notion de coupure frontale. Comme on peut le voir sur cette figure, la coupure donnée est la coupure la plus à gauche.
Sur cette figure, les deux coupures qui ont l'abscisse sur le bord haut la plus proche de celui de la coupure donnée sont des coupures frontales, et pas la troisième. En effet, pour chacune d'entre elles, il n'existe pas de coupure entre elles et la coupure donnée.
Par contre la dernière coupure (la plus à droite) n'est pas frontale par rapport à la coupure donnée car la coupure frontale ayant l'abscisse sur le bord haut le plus à droite est intégralement contenue entre la coupure donnée et cette coupure.
En variante, il serait possible de chercher des chemins par trois ou par quatre au lieu de les chercher par paire. En outre, comme on vient de le voir avec la description des figures 3 et 5, on peut parler de manière équivalente de chemin ou de coupure une fois qu'un chemin a été sélectionné dans une boucle locale. Ainsi, une coupure frontale peut également être appelée chemin frontal.
Une fois que l'analyseur 4 a calculé les coupures dans l'image d'entrée 12, une boucle est lancée dans laquelle le sélectionneur 6, l'assembleur 8 et la base de règles 1 0 interagissent pour produire un jeu 16 de morceaux d'image synthétisée. Enfin, le jeu 16 de morceaux d'image synthétisée peut être assemblé pour former une image synthétisée 18.
La figure 4 représente un exemple de mise en œuvre de la boucle qui produit le jeu 16. Dans ce premier mode de réalisation, l'image synthétisée est agrandie ou réduite selon la dimension horizontale.
Le concept de fonctionnement mis en œuvre par cette boucle va maintenant être décrit.
Afin de simplifier la génération des images, et pour pouvoir les stocker à moindre coût, le Demandeur a pris le parti d'utiliser les avantages liés aux coupures. Comme on vient de le voir, une coupure est un chemin dans l'image selon une direction, ici entre les bords haut et bas de l'image, qui possède au moins un "chemin parallèle" ayant tout du long des couleurs similaires dans cette image. Ainsi, si l'on colle à la suite d'une coupure donnée la partie de l'image originale qui suit la "coupure parallèle", l'œil humain ne verra pas la différence dans la plupart des cas. Il devient alors possible d'agrandir ou de réduire la taille d'une image de base en réduisant très fortement les artefacts, tout en ajoutant de la variété. Cela est fait par la juxtaposition d'une suite de coupures de l'image originale, qui sont remplies entre elles par le contenu correspondant de l'image originale. Cela apparaît par exemple avec le jeu 16.
Cette mise en œuvre est très avantageuse, car il devient possible de créer une multitude d'images synthétisées à partir d'une seule image de base, et de les décrire uniquement avec cette image, les coupures qu'elle contient, et une pluralité de liste de coupures successives pour chaque image.
Le travail de reconstruction d'une image synthétisée à partir de sa liste de coupures est en effet très peu gourmand en temps de calcul. Il faut néanmoins faire le choix des coupures de manière judicieuse. De plus, dans la modélisation d'un immeuble en trois dimensions, il faut que les angles se correspondent, ce qui impose de garder les bords gauche et droit de l'image originale. Dans d'autres applications, cette limitation pourra être ignorée, et les bords de départ et d'arrivée pourront être choisis dans l'image par l'utilisateur.
Le travail du Demandeur l'a donc amené à étudier la manière la plus efficace de choisir la liste de coupures successives dans l'image afin d'obtenir une image finale de la taille choisie.
Comme cela apparaîtra avec la description qui suit de la boucle de génération du jeu 16, le Demandeur a mis en œuvre une version adaptée de l'algorithme de Dijkstra. Ici, le but est de partir du bord gauche de l'image, et d'arriver au bord droit de l'image, en choisissant les coupures entre les deux pour obtenir la longueur voulue pour l'image synthétisée.
Pour cela, le sélectionneur 6 choisit à chaque itération la liste des coupures qui peuvent être utilisées parmi la liste suivante :
- la ou les coupures "parallèles" à la coupure en cours,
- l'ensemble des coupures dites "frontales".
Ces conditions de sélection forment une première règle de sélection qui est stockée dans la base de règles 10. D'autres règles seront décrites plus bas. On notera que la sélection de la ou des coupures "parallèles" à la coupure en cours permet de "revenir en arrière" ou de "sauter en avant" dans l'image originale pour former l'image synthétisée, ce qui permet la génération d'images synthétisées agrandies ou réduites avec le moins d'artefact visuel possible. De plus, ce jeu est réduit, ce qui simplifie la complexité de l'algorithme, tout en n'ignorant aucune combinaison possible, grâce aux coupures frontales notamment. L'algorithme de Dijkstra est mis en œuvre comme suit :
- lorsque la ou l'une des coupures "parallèles" à la coupure en cours est choisie, le coût est augmenté de la différence entre ces coupures, et la longueur de l'image synthétisée n'est pas augmentée. Par distance entre les coupures, on entend l'erreur, la différence entre les pixels de l'image originale le long des coupures. Cette information est directement disponible à partir du travail de l'analyseur 4.
- lorsque c'est une coupure frontale qui est choisie, le coût n'est pas augmenté, car cela revient à reproduire une partie de l'image originale, et la longueur de l'image synthétisée est augmentée de la longueur qui sépare la coupure courante de la coupure frontale choisie.
- l'algorithme s'arrête lorsque le bord droit de l'image est choisi, et que la longueur de l'image synthétisée est égale à la longueur voulue. Il ne reste qu'à remonter la liste des "précédents" établie par l'algorithme pour connaître la liste des coupures, jusqu'au bord gauche.
Cependant, l'algorithme fonctionne non pas sur la base des coupures, mais sur la base de nœuds. Par nœud on entend ici le couple formé par un identifiant de coupure et une position de cette coupure dans l'image synthétisée. Comme on le verra plus bas, un nœud courant a plusieurs attributs :
- le prédécesseur de ce nœud, c'est-à-dire le nœud qui est considéré comme le moins coûteux pour atteindre le nœud courant,
- le coût qui est associé à ce nœud, c'est-à-dire la somme des différences entre toutes les coupures rencontrées avant d'atteindre ce nœud.
La boucle commence dans une opération 400 par l'appel d'une fonction lnit() par le pilote 1 1 .
La fonction l nit() a pour rôle de réaliser les initialisations des variables et des paramètres globaux de la boucle de synthèse de l'image.
Parmi ces paramètres, on compte la longueur W souhaitée pour l'image synthétisée. Comme on le verra avec la figure 6, cette longueur peut être spécifiée par l'utilisateur pour chaque image qu'il souhaite synthétiser. Elle peut également être générée automatiquement en fonction d'autres paramètres spécifiés par l'utilisateur et/ou de modèles de répartition.
Un autre paramètre est le fichier Cuts, qui reçoit l'ensemble des coupures identifiées dans l'image 12 par l'analyseur 4, et qui sert de point de départ à l'algorithme. Dans le fichier Cuts, les coupures sont décrites par la liste des coordonnées des points qui les définissent, et les coupures sont ordonnées par abscisses croissantes, c'est-à-dire que le bord gauche de l'image est la première coupure, puis suit la coupure qui contient le point dont l'abscisse est la plus basse, et ainsi de suite.
Dans une opération 402, la coupure qui correspond au bord gauche de l'image est choisie comme point de départ. Le nœud correspondant est ici noté N0 et a une abscisse nulle dans l'image synthétisée, un coût associé nul, et aucun prédécesseur. Le nœud N0 est stocké dans une liste Pot.
Une fois que cela est fait, l'initialisation de la boucle est terminée, et la boucle en tant que telle va s'exécuter.
Dans une première opération 404, la liste Pot est dépilée au moyen d'une fonction Pop(). Comme on le verra dans ce qui suit, il s'agit toujours du nœud ayant le coût le plus faible. Le résultat de ce dépilement est stocké dans un nœud courant Ne, et ce nœud est entré dans une liste de nœuds déjà optimisés.
Ensuite, dans une opération 406, un test vérifie si l'algorithme est terminé, c'est-à-dire si la coupure du nœud Ne est le bord droit de l'image, et si la longueur de l'image est la longueur souhaitée.
Si c'est le cas, la boucle se termine en 408. Sinon, dans une opération 41 0, le pilote appelle la fonction SelectQ avec le nœud courant Ne. Le résultat de cet appel est stocké dans une liste Nxt.
Dans la fonction Select(), le sélectionneur 6 sélectionne la liste des coupures du fichier Cuts qui correspondent à la coupure du nœud courant Ne selon les critères de sélection explicités plus haut. Ensuite, ces coupures sont arrangées sous forme de nœuds dans la liste Nxt, en fonction de la longueur associée à chaque coupure.
Ainsi, si la position de la coupure du nœud courant Ne est p, et que I est la longueur de la transition de la coupure du nœud courant Ne vers une coupure c tirée du fichier Cuts, alors un nœud est créé dans la liste Nxt qui a comme coupure la coupure c, et comme position une position q = p+1 .
Dans le cas où un tel nœud a déjà été rencontré et est dans la liste Pot, alors les attributs de ce nœud sont copiés depuis la liste Pot, c'est-à-dire son nœud prédécesseur et le coût de ce nœud. Sinon, ce nœud est nouveau, et le prédécesseur n'est pas initialisé, tandis que le coût associé à ce nœud est initialisé avec une valeur "infinie". Par valeur infinie, on entend soit des données indiquant que le coût n'a jamais été calculé, doit des données correspondant à un très grand coût.
La fonction Select() est prévue pour arranger la liste Nxt de manière ordonnée par coûts de transition croissants. Par coût de transition, on entend ici le coût associé à la diférence entre la coupure du nœud Ne et la coupure de chaque nœud de la liste Nxt. En variante, la fonction Select() peut effectuer un tri selon un autre attribut.
Ensuite, le pilote 1 1 appelle l'assembleur 8 dans une suite d'opérations 412 à 420 pour la mise à jour des attributs de coût des nœuds selon l'algorithme de Dijkstra.
Cette suite d'opérations est une boucle qui commence en 412 par le dépilage de la liste Nxt dans un nœud Ntmp. Si le nœud Ntmp est dans la liste des nœuds déjà optimisés, alors ce nœud est ignoré et l'opération 410 est répétée, car le coût de ce nœud ne peut pas être amélioré.
Lorsque Ntmp existe, un test 414 vérifie au moyen d'une fonction Cost() si le coût du nœud Ntmp peut être diminué. Pour cela, la fonction Cost() compare le coût du nœud Ntmp et le coût du nœud courant Ne ajouté du coût de transition de la coupure du nœud courant Ne à la coupure du nœud Ntmp. Si le coût du nœud Ntmp est plus important, alors cela indique qu'il est possible d'atteindre ce nœud de manière plus économe en passant par le nœud courant Ne.
Alors, le coût du nœud Ntmp est mis à jour dans une opération 416 en ajoutant au coût associé au nœud courant Ne le coût de transition de la coupure du nœud courant Ne vers la coupure du nœud Ntmp. Comme on l'a vu plus haut, ce coût de passage est nul lorsque la coupure du nœud Ntmp n'est pas une coupure parallèle. Ensuite, dans une opération 418, le nœud courant Ne est indiqué comme prédécesseur du nœud Ntmp.
Ensuite, la liste Nxt est à nouveau dépilée dans l'opération 41 2. Avant cela, le nœud Ntmp est reversé dans la liste Pot dans une opération 420. Cette opération est réalisée de manière ordonnée, c'est-à-dire que le nœud Ntmp est introduit dans la liste Pot en fonction du coût qui lui est associé. Dans le cas où le nœud Ntmp est déjà dans la liste Pot, ses attributs de coût et de prédécesseur sont mis à jour et la liste Pot est triée en conséquence. Lorsque, l'opération 412 détermine que la liste Nxt est vide, la boucle est réitérée en 404 avec un nouveau dépilage de la liste Pot.
Dans ce qui précède, il apparaît que chaque nœud de la liste Pot associé à ses prédécesseurs représente une variante d'image partiellement synthétisée possible. L'algorithme est optimisé pour s'arrêter dès que l'image synthétisée la plus fidèle, c'est- à-dire avec le coût le plus faible, et de bonne longueur est trouvée. Par bonne longueur, on entend que la position du dernier nœud est égale à la longueur voulue pour l'image synthétisée, et que la coupure de ce nœud est le bord droit. L'algorithme exposé avec la figure 4 est donc très performant et permet de produire avec un faible coût de calcul une représentation qui a elle-même un poids faible d'une image synthétisée avec très peu d'artefacts. Cependant, cet algorithme est perfectible. En effet, en fonction de la distribution des coûts associés aux coupures parallèles et de part le fait qu'un plus court chemin est toujours composé lui-même de plus courts chemins, il peut arriver que l'image synthétisée comporte une forte répétition d'un motif particulier de l'image originale.
Pour prévenir ce problème, la fonction Select() peut être modifiée pour mettre en œuvre une pluralité de règles de sélection en plus de la première règle mentionnée plus haut. La première règle décrite plus haut peut être variée en permettant de choisir comme coupures non parallèles les coupures situées à gauche de la coupure courante, c'est- à-dire en permettant de revenir en arrière avec toutes les coupures, et pas seulement les coupures parallèles. Dans ce cas le morceau d'image copié est inversé car copié de la droite vers la gauche.
Une deuxième règle peut être basée sur la limitation du nombre de répétitions d'une colonne de l'image d'entrée 12 dans toute portion de l'image synthétisée d'une certaine longueur. Ainsi, il est possible d'assurer que l'image synthétisée ne contient pas de répétitions désagréables à l'œil.
Il faut pour cela maintenir un tableau d'occurrences pour chaque colonne de l'image d'entrée. Ce tableau est mis à jour dans l'opération 404 à partir des prédécesseurs du nœud Ne. Ce tableau contient le nombre d'occurrences des colonnes de l'image originale dans la portion de l'image partiellement synthétisée précédent Ne et de longueur choisie.
Lors de la sélection des nœuds dans l'opération 406, si la coupure d'un nœud donné candidat pour l'ajout dans la liste Nxt est une coupure frontale, alors un morceau de l'image originale sera ajouté à l'image synthétisée en cours. Le tableau d'occurrences est alors consulté pour vérifier que l'augmentation du nombre d'occurrences dû à cette copie ne dépassera pas un certain seuil. Si le seuil est dépassé, le nœud n'est pas ajouté dans la liste Nxt. Une troisième règle opère de manière similaire mais en tenant compte de l'image synthétisée entière, au lieu d'une longueur choisie. Les colonnes utilisées dans ses règles ont dans l'exemple décrit ici chacune une largeur de 1 pixel. Dans d'autres variantes, cette largeur peut être plus importante, voire varier. Une quatrième règle peut imposer de la variété entre images synthétisées successivement. Pour cela, le sélectionneur 6 reçoit ou a accès à une liste d'images synthétisées décrites par leurs coupures, et ainsi donc à la position de chacune des colonnes de l'image originale dans chaque image déjà synthétisée.
La quatrième règle peut être de ne pas permettre de sélectionner comme nœud suivant les nœuds dont l'inclusion entraînerait la copie dans l'image synthétisée de colonnes de l'image originale à une position qui est proche de ce qui a déjà été réalisé dans les images déjà synthétisées.
Cela peut être réalisé en parcourant la liste Nxt produite par l'application de la première règle en combinaison ou pas avec la deuxième ou la troisième règle, et en retirant les nœuds qui ne satisfont pas cette quatrième règle.
De plus, pour l'application des deuxième, troisième, et quatrième règles, les calculs de tableau d'occurrences réalisés pour une image synthétisée donnée peuvent être réutilisés pour une image synthétisée ultérieure, comme l'algorithme est le même pour toutes les images synthétisées. Cela permet d'éviter de répéter de nombreux calculs.
Une cinquième règle peut imposer la reproduction d'une partie de l'image originale à un endroit précis de l'image synthétisée, par exemple par une interface de copier-coller. La zone à reproduire à l'identique a donc des coordonnées connues dans l'image synthétisée.
Pour appliquer cette règle, l'opération 406 doit gérer deux situations :
a. un nœud ajouté dans la liste Nxt a une coupure qui définit avec la coupure du nœud courant une zone de l'image originale qui est située avant la zone à reproduire à l'identique dans l'image synthétisée, ou lorsque le nœud courant a une position située après la zone à reproduire à l'identique dans l'image synthétisée, b. u n nœud ajouté dans la l iste Nxt a u ne coupu re qu i défi n it avec la coupu re du nœud courant une zone de l'image originale qui traverse la zone à reproduire à l'identique dans l'image synthétisée.
Les cas a. et b. peuvent être détectés en comparant les coordonnées dans l'image synthétisée des points associés à la coupure du nœud ajouté et celles de la zone à reproduire à l'identique.
Dans le cas a, l'opération 406 est inchangée.
Dans le cas b. le sélectionneur doit déterminer si la coupure du nœud ajouté reproduit la zone à reproduire à l'identique aux bonnes coordonnées. Si c'est le cas, alors ce nœud est gardé. Sinon, le nœud ajouté est retiré de la liste Nxt. Dans le cas où le nœud ajouté est gardé, le choix du nœud suivant est très contraint, car sa coupure doit reproduire le reste (totalement ou en partie) de la zone à reproduire à l'identique en partant de cette coupure. Une sixième règle consiste à encourager les colonnes à apparaître avec des décalages qui suivent la fonction d'autocorrélation unidimensionnelle de l'image originale.
La fonction d'auto-corrélation mesure la distance de l'image avec sa copie décalée de x pixels, pour tout x.
Pour ce faire, on modifie le coût de transition entre deux coupures en lui ajoutant un coût supplémentaire variant comme l'inverse de la valeur de corrélation pour un x égal au décalage (modulo W) entre la position de la coupure courante dans l'image originale et sa position dans l'image en cours de synthèse, le tout multiplié par l'écart entre les deux coupures par rapport auxquelles on considère le coût de transition. D'une manière générale, le fait que les plus courts chemins sont eux-mêmes composés de plus courts chemins de taille inférieure permet, dans le cas où les règles appliquées ne dépendent pas des opérations précédentes, de réaliser des gains importants sur les calculs.
En effet, si on calcule la solution pour une taille W, alors les calculs effectués peuvent être réutilisés intégralement, et il est possible d'obtenir la solution pour une taille W+X plus rapidement.
Compte tenu de l'état de l'art, il apparaît à l'homme du métier que l'algorithme décrit précédemment est un algorithme de plus court chemin (Dijkstra) appliqué sur un graphe. Bien que le graphe ne soit pas explicitement construit, il est implicitement défini par les règles de sélection des nœuds suivants.
Tout autre algorithme de plus court chemin, y compris des algorithmes approximatifs type A * ou aléatoires, pourront donc être employés de manière équivalente. De même, le graphe correspondant aux règles décrites ci-avant pourrait être construit en mémoire explicitement, afin d'y effectuer divers traitements. Définir le graphe implicitement tel que décrit ci-avant permet néanmoins une exécution plus efficace de la synthèse d'une nouvelle image. L'exemple qui vient d'être décrit l'a été en rapport avec une synthèse selon la direction horizontale d'une image. Mais une synthèse selon la direction verticale sera identique, à cela près que les coupures seront cette fois horizontales. Une autre possibilité serait d'imposer une rotation de 90 ° à l'image, et de lui appliquer un redimensionnement identique.
Lorsque l'on souhaite réaliser un redimensionnement bidimensionnel d'une image, il est possible de :
- calculer les coupures verticales,
- faire une synthèse horizontale pour obtenir une image intermédiaire,
- calculer les coupures horizontales dans l'image intermédiaire,
- faire une synthèse verticale pour obtenir l'image finale. Cependant, cela impose de recalculer pour chaque image intermédiaire les coupures horizontales. Or cela est pénalisant, car ces coupes vont varier en fonction du redimensionnement horizontal qui a été effectué en premier lieu. Le résultat prend donc plus de temps à générer.
Le Demandeur a donc établi un algorithme représenté sur la figure 6, qui permet de réaliser une pluralité d'images synthétisées avec un agrandissement ou un rétrécissement bidirectionnel distinct, tout en ne conservant qu'un seul jeu de coupures horizontales et verticales qui est celui de l'image originale.
Dans l'exemple décrit ici, l'invention reçoit en entrée une image de taille MxN, une largeur cible W et produit en sortie une image de taille WxN ressemblant à l'entrée.
L'invention procède en deux temps: étant donné une taille cible de WxH pixels et une image originale de taille MxN, l'invention produit tout d'abord une image intermédiaire de taille WxN à partir de l'image MxN, puis dans un second temps une image de taille WxH à partir de l'image intermédiaire de taille WxN. II convient de noter que l'ordre des opérations importe peu et que les opérations effectuées horizontalement et verticalement sont strictement équivalentes. La suite de cet exemple se limite au cas horizontal suivi de vertical.
Pour cela, une opération de synthèse horizontale est réalisée dans une opération 600. Cette opération est identique à l'ensemble de la figure 4. Le résultat est une liste de coupures verticales.
Ensuite, dans une opération 610, le pilote 1 1 appelle l'assembleur 8 pour appliquer à chaque coupure horizontale de l'image originale une transformation qui correspond à la liste de coupures verticales issues de l'opération 600.
Enfin, dans une opération 620, le pilote 1 1 réalise une opération de synthèse verticale, qui est basée sur les coupures horizontales transformées issues de l'opération 610.
Il en résulte une liste de coupures horizontales qui est stockée avec la liste de coupures verticales pour former l'image synthétisée.
Ainsi, pour reconstituer l'image synthétisée, il suffit d'appliquer la synthèse horizontale définie par la liste de coupures verticales à l'image originale et aux coupures horizontales, puis d'appliquer la synthèse verticale définie par les coupures horizontales résultantes à l'image résultante.
La figure 7 représente un système de synthèse d'univers dans lequel un serveur 70 comprend une interface utilisateur GUI et un dispositif 2 tel que décrit précédemment.
Ce serveur peut être réalisé sous la forme d'un circuit intégré spécialisé, ou d'un ordinateur exécutant un code qui exécute toutes les fonctions et présente toutes les caractéristiques du dispositif 2.
Au moyen de l'interface GUI, un utilisateur a la possibilité de générer des images synthétisées variées de manière massive, par lot.
Pour cela, il a accès à une base d'images d'origine 72, et il peut programmer le dispositif 2 pour produire pour chaque image de la base 72 un nombre désiré d'images synthétisées stockées dans une base d'images synthétisées 74. Cette production peut être réalisée en appliquant de manière aléatoire ou systématique un certain nombre des règles de la base 10, et en faisant varier de manière aléatoire ou systématique les paramètres de ces règles.
L'interface GUI permet également à l'utilisateur de créer des images synthétisées présentant des caractéristiques particulières, par exemple en imposant la présence d'une coupure de l'image originale à un endroit précis d'une image synthétisée. Pour cela, le dispositif 2 calcule deux images synthétisées, l'une partant du bord gauche de l'image et s'arrêtant à la coupure concernée, et l'autre image partant de la coupure concernée et s'arrêtant au bord droit de l'image. Bien sûr cela peut être répété en imposant plusieurs coupures à plusieurs endroits cibles.
En variante, l'utilisateur peut également imposer la reproduction d'une partie cible de l'image originale dans une zone cible de l'image synthétisée. Cela permet d'utiliser un "glisser-déposer" d'une partie de l'image originale, ce qui simplifie l'expérience utilisateur. Pour cela, le dispositif 2 peut notamment appliquer la cinquième règle.
Dans ce qui précède, les deuxième, troisième, quatrième et cinquième règles ont été décrites pour améliorer la qualité de la synthèse d'image. Pour cela, ces règles limitent les coupures qui peuvent être utilisées dans l'algorithme de Dijkstra. Elles ont été définies à partir d'un nœud qui a d'abord été ajouté, puis qui est retiré en fonction de ces règles.
Cela signifie que la fonction Select() qui les met en œuvre fonctionne d'abord comme décrit en rapport avec la première règle, puis exécute un deuxième passage sur la liste Nxt pour retirer les nœuds qui ont été ajoutés et ne satisfont pas les deuxième et/ou troisième et/ou quatrième et/ou cinquième règles.
En variante, la fonction Select() pourrait être prévue pour mettre en œuvre toutes les première à cinquième règles en une seule passe, c'est-à-dire qu'un nœud n'est ajouté à la liste Nxt que s'il satisfait à toutes les règles, par des tests a priori.
Pour finir, il apparaît que l'on peut stocker les images synthétisées sous deux formats équivalents.
Selon un premier format, l'image originale et la liste des coupures sont fournies, et les images synthétisées sont constituées par la liste des coupures qui les composent.
Lorsqu'elles doivent être utilisées, les images synthétisées sont construites en collant bout à bout les morceaux de l'image originale situés entre chaque paire de coupures de la liste de coupures.
Cela est particulièrement avantageux car la liste de coupures contient seulement un identifiant de coupures, et un identifiant de l'image originale. Ainsi, lorsqu'il y a beaucoup d'images synthétisées, ce format occupe très peu d'espace de stockage par rapport au stockage d'images brutes.
Il est également possible de déterminer très rapidement la couleur d'un point situé aux coordonnées (x,y) de l'image synthétisée à partir de la liste de coupures. On effectue pour cela une recherche dichotomique sur la liste des coupures qui sont triées par ordre croissant de position (les coupures formant une image synthétisée ne se croisent jamais).
Ceci perm et d'aff ich er les i m ag es à l ' écran o u appl iq u ées su r des obj ets tridimensionnels par placage de texture sans jamais avoir à explicitement former l'image synthétisée en mémoire.
Selon un deuxième format, les images synthétisées sont directement stockées sous forme d'images, c'est-à-dire qu'après que la liste de coupures a été établie, l'image synthétisée correspondante est générée et stockée.
Ce format peut être utile lorsque la puissance de calcul est limitée, et empêche une génération à la volée des images synthétisées à partir de leurs listes de coupures respectives.
L'approche qui a été décrite ci-dessus peut être directement appliquée même sur des données de vidéo et des volumes (en fait des images 3D).
L'approche s'applique également à des signaux 1 D tels que des sons, auquel cas les coupures se réduisent à une seule coordonnée et le coût de correspondance peut être donné, par exemple, par une matrice de similarité. Les chemins deviennent alors des nappes qui séparent le volume en deux selon une direction, mais le reste du fonctionnement est globalement inchangé.
Dans ce cas, il peut être intéressant d'étendre l'algorithme décrit aux figures 4 et 6 pour tenir compte du nombre de dimension des nappes, en répétant les opérations selon chacune de ces dimensions.
D'une manière plus générale, il est possible d'étendre l'algorithme de la figure 6 à un nombre quelconque de directions.
