Où puis-je trouver une bonne lecture sur Bicubic interpolation et Lanczos resampling?
je veux implémenter les deux algorithmes de rééchantillonnage d'image mentionnés ci-dessus (bicubic et Lanczos) en C++. Je sais qu'il y a des dizaines d'implémentations existantes, mais j'ai encore envie de faire mon propre. Je veux le faire en partie parce que je veux comprendre comment ils fonctionnent, et en partie parce que je veux leur donner certaines capacités qui ne se trouvent pas dans les implémentations grand public (comme le support multi-CPU configurable et les rapports d'avancement).
J'ai essayé de lire Wikipedia, mais le truc c'est un peu trop sec pour moi. Peut-être il y a le beau explications de ces algorithmes? Je n'ai rien trouvé ni sur SO, ni sur Google.
Ajouté: Semble comme personne ne peut me donner un bon lien sur ces sujets. Quelqu'un peut au moins essayer de les expliquer ici?
3 réponses
le principe de base de fonctionnement des deux algorithmes est assez simple. Ce sont des filtres à convolution. Un filtre de convolution qui pour chaque valeur de sortie déplace le point d'origine des fonctions de convolution pour être centré sur la sortie et multiplie ensuite toutes les valeurs dans l'entrée avec la valeur de la fonction de convolution à cet endroit et les ajoute ensemble.
une propriété de la convolution est que l'intégrale de la sortie est le produit des intégrales des deux entrées fonction. Si vous considérez les images d'entrée et de sortie, alors l'intégrale signifie luminosité moyenne et si vous voulez que la luminosité reste la même l'intégrale de la fonction de convolution doit s'ajouter à un.
une façon de les comprendre est de penser à la fonction de convolution comme quelque chose qui montre combien les pixels d'entrée influencent le pixel de sortie en fonction de leur distance.
les fonctions de Convolution sont habituellement définies de telle sorte qu'elles soient nulles lorsque le la distance est supérieure à une certaine valeur, de sorte que vous n'avez pas à considérer chaque valeur d'entrée pour chaque valeur de sortie.
pour l'interpolation de lanczos la fonction de convolution est basée sur sinc (x) = sin(x*pi)/x fonction, mais seulement les premiers lobes sont pris. Habituellement 3:
lanczos(x) = {
0 if abs(x) > 3,
1 if x == 0,
else sin(x*pi)/x
}
cette fonction s'appelle le noyau filter.
pour rééchantillonner avec lanczos imaginez que vous superposez la sortie et l'entrée l'une sur l'autre, avec des points indiquant où la emplacements de pixels. Pour chaque emplacement de pixel de sortie vous prenez une boîte + - 3 pixels de sortie de ce point. Pour chaque pixel d'entrée qui se trouve dans cette boîte, calculez la valeur de la fonction lanczos à cet endroit avec la distance de l'emplacement de sortie en coordonnées de pixel de sortie comme paramètre. Vous devez ensuite normaliser les valeurs calculées en les mettant à l'échelle de sorte qu'elles s'additionnent à 1. Après cela, multipliez chaque pixel d'entrée avec la valeur d'échelle correspondante et ajoutez les résultats ensemble. pour obtenir la valeur du pixel de sortie.
parce que la fonction lanzos a la propriété de séparabilité et, si vous redimensionnez, la grille est régulière, vous pouvez optimiser ceci en faisant la convolution horizontalement et verticalement séparément et précalculer les filtres verticaux pour chaque ligne et les filtres horizontaux pour chaque colonne.
la convolution Bicubique est essentiellement la même, avec une fonction de filtre du noyau différente.
pour obtenir plus de détails, Il ya un assez bon et explication approfondie dans le livre Traitement D'Image Numérique, section 16.3.
aussi,image_operations.cc et convolver.cc dans skia ont une mise en œuvre assez bien commentée de l'interpolation de lanczos.
alors que ce que dit La Fourmi Aasma décrit grossièrement la différence, Je ne pense pas que ce soit particulièrement instructif quant à la raison pour laquelle vous pourriez faire une telle chose.
en ce qui concerne les liens, vous posez une question très basique dans le traitement d'image, et n'importe quel manuel d'introduction décent sur le sujet le décrira. Si je me souviens bien, Gonzales et Bois est décent sur elle, mais je suis loin de mes livres et ne peut pas vérifier.
Maintenant, sur les détails, il devrait aider à penser à ce que vous faites fondamentalement. Vous avez un réseau carré de mesures pour lesquelles vous voulez interpoler de nouvelles valeurs. Dans le cas simple de l'upsampling, imaginons que vous voulez une nouvelle mesure entre toutes celles que vous avez déjà (par exemple, doubler la résolution).
Maintenant vous n'obtiendrez pas la valeur "correcte", parce qu'en général vous n'avez pas cette information. Donc, vous avez une estimation. Comment faire cela? Une façon très simple serait d'interpoler linéairement. Tout le monde sait le faire avec deux points, il suffit de tracer une ligne entre eux, et de lire la nouvelle valeur hors de la ligne (dans ce cas, à la mi-chemin).
maintenant, une image est bidimensionnelle, donc vous voulez vraiment faire cela à la fois dans les directions gauche-droite et haut-vers le bas. Utilisez le résultat pour votre estimation et voilà vous avez "bilinear" interpolation.
le problème principal avec cela est qu'il n'est pas très précis, bien qu'il soit meilleur (et plus lent) que le " plus proche voisin" approche qui est aussi très locale et rapide.
pour résoudre le premier problème, vous voulez quelque chose de mieux qu'un ajustement linéaire de deux points, vous voulez ajuster quelque chose à plus de points de données (pixels), et quelque chose qui peut être non linéaire. Un bon compromis sur la précision et le coût de calcul est quelque chose appelé une spline cubique. Ainsi, vous obtiendrez une ligne d'ajustement lisse, et vous vous rapprocherez de nouveau de votre nouvelle "mesure" par la valeur qu'elle prend au milieu. Faites ceci dans les deux sens et vous avez "bicubique" interpolation.
Donc, c'est plus précis, mais encore lourd. Une façon d'aborder la question de la vitesse est d'utiliser une convolution, qui a la propriété nice que dans le domaine de Fourier, c'est juste une multiplication, donc nous pouvons l'implémenter assez rapidement. Mais vous n'avez pas besoin de vous soucier de l'implémentation pour comprendre que le résultat de la convolution à tout moment est une fonction (votre image) étant intégrée dans un autre produit, généralement un support beaucoup plus petit (la partie c'est la fonction non-zero) appelée le noyau), après que le noyau a été centré sur ce point particulier. Dans le monde discret, ce ne sont que des sommes des produits.
il s'avère que vous pouvez concevoir un noyau de convolution qui a des propriétés tout à fait comme la spline cubique, et l'utiliser pour obtenir un "bicubic" rapide
le rééchantillonnage Lancsoz est une chose similaire, avec des propriétés légèrement différentes dans le noyau, ce qui signifie principalement qu'ils auront des caractéristiques différentes artefact. Vous pouvez consulter les détails de ces fonctions du noyau assez facilement (je suis sûr que wikipedia les a, ou n'importe quel texte d'intro). Les implémentations utilisées dans les programmes graphiques ont tendance à être hautement optimisées et ont parfois des hypothèses spécialisées qui les rendent plus efficaces mais moins générales.
je voudrais suggérer l'article suivant pour une compréhension de base de différentes méthodes d'interpolation d'image interpolation d'image via convolution. Si vous voulez essayer plusieurs méthodes d'interpolation, le imageresampler est un beau projet open source pour commencer.
à mon avis, l'interpolation d'image peut être comprise à partir de deux aspects, l'un est du point de vue de l'ajustement de la fonction, et l'autre est du point de vue de la convolution. Par exemple, le spline interpolation expliquée dans interpolation d'image via convolution est bien expliqué du point de vue de l'ajustement de la fonction dans interpolation cubique.
en outre, l'interpolation d'image est toujours liée à une application spécifique, par exemple le zoom d'image, la rotation d'image et ainsi de suite. En fait pour une application spécifique, l'interpolation d'image peut être implémentée I. d'une manière intelligente. Par exemple, la rotation d'image peut être implémentée via un tonte en trois méthode et, lors de chaque opération de cisaillement, différents algorithmes d'interpolation unidimensionnelle peuvent être mis en oeuvre.