La compréhension OpenCV est undistort fonction
Je suis à la recherche de undistort une image en utilisant les coefficients de distorsion que j'ai calculé pour mon appareil photo, sans changer la caméra de la matrice. C'est exactement ce que undistort()
fait, mais j'ai voulu mettre la sortie à une grande toile de l'image.
Quand j'ai essayé ceci:
Mat drawtransform = getOptimalNewCameraMatrix(cameraMatrix, distCoeffs, size, 1.0, size * 2);
undistort(inputimage, undistorted, cameraMatrix, distCoeffs, drawtransform);
- Il encore écrit de la même taille d'image, mais seulement la partie supérieure gauche de l'échelle-par-deux non faussée résultat. Comme le dit la documentation, undistort écrit dans une image de la cible de la même taille.
Il est assez évident que je peux simplement aller copier et reproduire un peu modifié la version de undistort()
mais je vais avoir du mal à comprendre ce qu'il fait. Voici le code source:
void cv::undistort( InputArray _src, OutputArray _dst, InputArray _cameraMatrix,
InputArray _distCoeffs, InputArray _newCameraMatrix )
{
Mat src = _src.getMat(), cameraMatrix = _cameraMatrix.getMat();
Mat distCoeffs = _distCoeffs.getMat(), newCameraMatrix = _newCameraMatrix.getMat();
_dst.create( src.size(), src.type() );
Mat dst = _dst.getMat();
CV_Assert( dst.data != src.data );
int stripe_size0 = std::min(std::max(1, (1 << 12) / std::max(src.cols, 1)), src.rows);
Mat map1(stripe_size0, src.cols, CV_16SC2), map2(stripe_size0, src.cols, CV_16UC1);
Mat_<double> A, Ar, I = Mat_<double>::eye(3,3);
cameraMatrix.convertTo(A, CV_64F);
if( distCoeffs.data )
distCoeffs = Mat_<double>(distCoeffs);
else
{
distCoeffs.create(5, 1, CV_64F);
distCoeffs = 0.;
}
if( newCameraMatrix.data )
newCameraMatrix.convertTo(Ar, CV_64F);
else
A.copyTo(Ar);
double v0 = Ar(1, 2);
for( int y = 0; y < src.rows; y += stripe_size0 )
{
int stripe_size = std::min( stripe_size0, src.rows - y );
Ar(1, 2) = v0 - y;
Mat map1_part = map1.rowRange(0, stripe_size),
map2_part = map2.rowRange(0, stripe_size),
dst_part = dst.rowRange(y, y + stripe_size);
initUndistortRectifyMap( A, distCoeffs, I, Ar, Size(src.cols, stripe_size),
map1_part.type(), map1_part, map2_part );
remap( src, dst_part, map1_part, map2_part, INTER_LINEAR, BORDER_CONSTANT );
}
}
Environ la moitié des lignes sont ici pour la santé mentale de la vérification et de l'initialisation des paramètres d'entrée. Ce que je suis confus au sujet de qui est ce qui se passe avec map1
et map2
. Ces noms sont malheureusement de moins descriptif que la plupart. Je dois être en manque de quelque explication, c'est peut-être niché dans une introduction page, ou en vertu de la doc pour une autre fonction.
map1
est une deux voies signé entier court de la matrice et map2
est un entier court non signé de la matrice, les deux sont de dimension (hauteur, max(4096/largeur, 1)). La question est, pourquoi? Quels seront ces cartes contiennent? Quelle est la signification et le but de cette répartition? Quelle est la signification et le but de l'étrange dimension des bandes?
Vous devez vous connecter pour publier un commentaire.
Utilisation initUndistortRectifyMap pour obtenir la transformation de l'échelle que vous désirez , puis appliquer sa sortie (les deux matrices que vous mentionnez) à remap .
La première carte est utilisée pour calculer la transformation de la coordonnée x à chaque pixel de position, le second est utilisé pour transformer la coordonnée y de la.
Vous voudrez peut-être lire la description pour la fonction remap. La carte représente le pixel en X,Y de l'emplacement dans l'image source pour chaque pixel dans l'image de destination. Map1_part est tous les X emplacement dans la source, et Map2_part est, chaque année emplacement dans la source.
Sans lire dans beaucoup, à la répartition des données pourrait être une méthode pour accélérer le processus de transformation.
EDIT:
Aussi, si vous êtes à la recherche pour juste redimensionner votre image à une plus grande dimension vous pourriez tout simplement ré-taille de l'image de sortie.