la correction de la déformation du fisheye par programmation
BOUNTY MISE À JOUR DE STATUT:
J'ai découvert comment mapper un linéaire de la lentille, de destination
coordonnées source
coordonnées.
Comment calculer la distance radiale à partir du centre pour aller de fisheye pour rectiligne?
-
1). J'ai fait de la lutte pour l'inverser, et à la carte coordonnées source à destination des coordonnées. Qu'est-ce que l'inverse, dans le code, dans le style des fonctions de conversion que j'ai posté?
-
2). Je vois aussi que mon undistortion est imparfaite sur certains objectifs - sans doute à ceux qui ne sont pas strictement linéaire. Quel est l'équivalent d'-et-à partir de la source et de la destination des coordonnées pour les lentilles? Encore une fois, que le code juste de formules mathématiques s'il vous plaît...
Question initialement déclaré:
J'ai quelques points qui décrivent les positions dans une photo prise avec un objectif fisheye.
Je veux convertir ces points de coordonnées rectilignes. Je veux undistort l'image.
J'ai trouvé cette description de la façon de générer un effet fisheye, mais pas comment inverser la tendance.
Il y a aussi un post de blog qui explique comment utiliser les outils pour le faire; ce sont des photos de que:
(1) : SOURCE
Photo originale lien
Entrée : image d'Origine avec œil-de-poisson déformation à corriger.
(2) : DESTINATION
Photo originale lien
Sortie : image Corrigée (techniquement aussi avec la correction de la perspective, mais c'est une étape distincte).
Comment calculer la distance radiale à partir du centre pour aller de fisheye pour rectiligne?
Mon stub de fonction ressemble à ceci:
Point correct_fisheye(const Point& p,const Size& img) {
//to polar
const Point centre = {img.width/2,img.height/2};
const Point rel = {p.x-centre.x,p.y-centre.y};
const double theta = atan2(rel.y,rel.x);
double R = sqrt((rel.x*rel.x)+(rel.y*rel.y));
//fisheye undistortion in here please
//... change R ...
//back to rectangular
const Point ret = Point(centre.x+R*cos(theta),centre.y+R*sin(theta));
fprintf(stderr,"(%d,%d) in (%d,%d) = %f,%f = (%d,%d)\n",p.x,p.y,img.width,img.height,theta,R,ret.x,ret.y);
return ret;
}
Sinon, j'arrivais à les convertir à l'image de fisheye pour rectiligne avant de trouver les points, mais je suis complètement déconcerté par la OpenCV documentation. Est-il un moyen simple de le faire dans OpenCV, et le fait d'effectuer assez bien pour le faire à un flux vidéo en direct?
- Je n'arrive pas à obtenir ce que vous cherchez. Le fisheye cartes à partir d'une sphère à l'image de l'avion. La cartographie inverse serait de l'image en arrière à une sphère de droite? Ce rectilignes de coordonnées que vous recherchez?
- Ma source de l'image est fisheye déformée, et je veux undistort il
- Donc, est à l'image de la photo.net/learn/fisheye ce que vous recherchez?
- Oui, l'image rectifiée par exemple par l'intermédiaire d'OpenCV, ou une formule de correction de point dans l'image.
- Avez-vous besoin de faire cela pour une gamme de caméras, ou tout simplement pour une caméra / un type de lentille?
- Va, avez-vous jamais obtenir une réponse définitive à cette question? Je serais très intéressé de voir tout le code dont vous avez fini avec.
- Je sais, ça fait un bon moment depuis que cette question a été posée, mais j'ai un problème similaire -- avez-vous jamais obtenir un morceau de code fonctionnel pour la transformation, y compris la correction de la perspective que vous avez mentionné?
- J'ai fini par utiliser la solution que j'ai posté moi-même ci-dessous; bonne chance!
Vous devez vous connecter pour publier un commentaire.
La description que vous mentionnez états que la projection par un trou d'épingle de la caméra (qui n'introduit pas de distorsion de l'objectif) est modélisé par
et la projection d'un commun objectif fisheye caméras (qui est, déformé) est modélisé par
Vous le savez déjà R_d et thêta et si vous connaissais l'appareil photo de la longueur focale (représenté par f) la correction de l'image serait à l'informatique R_u en termes de R_d et thêta. En d'autres termes,
est la formule que vous cherchez. L'estimation de la distance focale f peut être résolu par l'étalonnage de la caméra ou par d'autres moyens tels que la possibilité pour l'utilisateur de fournir de la rétroaction sur la façon dont l'image est corrigée ou à l'aide de connaissances à partir de la scène d'origine.
Afin de résoudre le même problème en utilisant OpenCV, vous devez obtenir l'appareil photo, les paramètres intrinsèques et de la distorsion de l'objectif coefficients. Voir, par exemple, le Chapitre 11 de L'Apprentissage D'OpenCV (n'oubliez pas de vérifier la correction). Ensuite, vous pouvez utiliser un programme comme celui-ci (écrit avec les liaisons Python pour OpenCV) dans le but d'inverser la distorsion de l'objectif:
Également noter que OpenCV utilise très différente de la distorsion de l'objectif du modèle à la une de la page web lié à.
(Affiche originale, offrant une alternative)
La fonction suivante cartes de destination (rectiligne) en coordonnées source (fisheye-déformée) coordonnées. (Je serais heureux d'aider à inverser)
Je suis arrivé à ce point par essai-et-erreur: je n'ai pas fondamentalement comprendre pourquoi ce code fonctionne, des explications et de l'amélioration de la précision apprécié!
Lorsqu'il est utilisé avec un facteur de 3.0, elle a réussi à undistorts les images utilisées comme exemples (je n'ai fait aucune tentative de la qualité de l'interpolation):
lien Mort(Et c'est à partir de l'article du blog, pour la comparaison:)
Si vous pensez que vos formules sont exactes, vous pouvez comput une formule exacte avec la trigo, comme suit:
Cependant, comme @jmbr dit, la caméra de distorsion dépend de l'objectif et le zoom. Plutôt que de compter sur une formule fixe, vous voudrez peut-être essayer un polynôme d'extension:
En jouant d'abord Un, puis de l'ordre supérieur des coefficients, vous pouvez calculer raisonnable de fonction locale (la forme de l'expansion prend avantage de la symétrie du problème). En particulier, il devrait être possible de calculer initiale coefficients de l'approximation de l'théorique de la fonction ci-dessus.
Aussi, pour obtenir de bons résultats, vous aurez besoin d'utiliser un filtre d'interpolation pour générer votre image corrigée. Aussi longtemps que la distorsion n'est pas trop grande, vous pouvez utiliser le type de filtre que vous voudriez utiliser pour redimensionner l'image de façon linéaire sans trop de problème.
Edit: selon votre demande, l'équivalent facteur d'échelle pour la formule ci-dessus:
Si vous tracez la formule ci-dessus aux côtés de tan(Rin/f), vous pouvez voir qu'ils sont très similaires dans leur forme. Fondamentalement, la distorsion de la tangente devient sévère avant le péché(w) devient très différent de w.
La formule d'inversion doit être quelque chose comme:
Je aveuglément à la mise en œuvre des formules à partir de ici, donc je ne peux pas garantir qu'il ferait ce qu'il vous faut.
Utilisation
auto_zoom
pour obtenir la valeur de lazoom
paramètre.J'ai pris ce que JMBR fait et fondamentalement renversée. Il prit le rayon de la déformation de l'image (Rd, qui est, la distance en pixels depuis le centre de l'image) et a trouvé une formule pour le Ru, le rayon de la distortion de l'image.
Vous voulez aller dans l'autre sens. Pour chaque pixel de la non faussée (image traitée), vous voulez savoir ce que le pixel correspondant est dans la déformation de l'image.
En d'autres termes, compte tenu de (xu, yu) --> (xd, yd). Vous replacez ensuite chaque pixel dans une image avec son pixel correspondant de l'image déformée.
À partir du moment où JMBR fait, je fais l'inverse, de trouver des Rd en fonction de Ru. J'obtiens:
où f est la longueur focale en pixels (j'expliquerai plus tard), et
r = Ru/f
.La longueur focale de mon appareil photo était de 2,5 mm. La taille de chaque pixel sur mon CCD de 6 um carré. f est donc 2500/6 = 417 pixels. Ce qui peut être trouvé par essai et erreur.
Trouver Rd vous permet de trouver le pixel correspondant dans l'image déformée à l'aide des coordonnées polaires.
L'angle de chaque pixel à partir du point central est le même:
theta = arctan( (yu-yc)/(xu-xc) )
où xc, yc sont les points centraux de.Puis,
Assurez-vous que vous savez quel quadrant vous êtes dans.
Voici le code C#, j'ai utilisé
J'ai trouvé ce fichier pdf, et j'ai prouvé que les mathématiques sont corrects (sauf pour la ligne
vd = *xd**fv+v0 which should say vd = **yd**+fv+v0
).http://perception.inrialpes.fr/CAVA_Dataset/Site/files/Calibration_OpenCV.pdf
Il n'utilise pas tous les derniers coefficients OpenCV est disponible, mais je suis sûr qu'il pourrait être adapté assez facilement.