|
|
|
@ -317,7 +317,8 @@ double cv::findTransformECC(InputArray templateImage, |
|
|
|
|
InputArray inputImage, |
|
|
|
|
InputOutputArray warpMatrix, |
|
|
|
|
int motionType, |
|
|
|
|
TermCriteria criteria) |
|
|
|
|
TermCriteria criteria, |
|
|
|
|
InputArray inputMask) |
|
|
|
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -397,13 +398,26 @@ double cv::findTransformECC(InputArray templateImage, |
|
|
|
|
Mat templateFloat = Mat(hs, ws, CV_32F);// to store the (smoothed) template
|
|
|
|
|
Mat imageFloat = Mat(hd, wd, CV_32F);// to store the (smoothed) input image
|
|
|
|
|
Mat imageWarped = Mat(hs, ws, CV_32F);// to store the warped zero-mean input image
|
|
|
|
|
Mat allOnes = Mat::ones(hd, wd, CV_8U); //to use it for mask warping
|
|
|
|
|
Mat imageMask = Mat(hs, ws, CV_8U); //to store the final mask
|
|
|
|
|
|
|
|
|
|
Mat inputMaskMat = inputMask.getMat(); |
|
|
|
|
//to use it for mask warping
|
|
|
|
|
Mat preMask = |
|
|
|
|
inputMaskMat.empty() ? Mat::ones(hd, wd, CV_8U) : inputMaskMat; |
|
|
|
|
|
|
|
|
|
//gaussian filtering is optional
|
|
|
|
|
src.convertTo(templateFloat, templateFloat.type()); |
|
|
|
|
GaussianBlur(templateFloat, templateFloat, Size(5, 5), 0, 0);//is in-place filtering slower?
|
|
|
|
|
|
|
|
|
|
Mat preMaskFloat = Mat(hd, wd, CV_32F); |
|
|
|
|
preMask.convertTo(preMaskFloat, preMaskFloat.type()); |
|
|
|
|
GaussianBlur(preMaskFloat, preMaskFloat, Size(5, 5), 0, 0);//is in-place filtering slower?
|
|
|
|
|
// Change threshold.
|
|
|
|
|
preMaskFloat *= (0.5/0.95); |
|
|
|
|
// Rounding conversion.
|
|
|
|
|
preMaskFloat.convertTo(preMask, preMask.type()); |
|
|
|
|
preMask.convertTo(preMaskFloat, preMaskFloat.type()); |
|
|
|
|
|
|
|
|
|
dst.convertTo(imageFloat, imageFloat.type()); |
|
|
|
|
GaussianBlur(imageFloat, imageFloat, Size(5, 5), 0, 0); |
|
|
|
|
|
|
|
|
@ -420,6 +434,8 @@ double cv::findTransformECC(InputArray templateImage, |
|
|
|
|
filter2D(imageFloat, gradientX, -1, dx); |
|
|
|
|
filter2D(imageFloat, gradientY, -1, dx.t()); |
|
|
|
|
|
|
|
|
|
gradientX = gradientX.mul(preMaskFloat); |
|
|
|
|
gradientY = gradientY.mul(preMaskFloat); |
|
|
|
|
|
|
|
|
|
// matrices needed for solving linear equation system for maximizing ECC
|
|
|
|
|
Mat jacobian = Mat(hs, ws*numberOfParameters, CV_32F); |
|
|
|
@ -449,17 +465,16 @@ double cv::findTransformECC(InputArray templateImage, |
|
|
|
|
warpAffine(imageFloat, imageWarped, map, imageWarped.size(), imageFlags); |
|
|
|
|
warpAffine(gradientX, gradientXWarped, map, gradientXWarped.size(), imageFlags); |
|
|
|
|
warpAffine(gradientY, gradientYWarped, map, gradientYWarped.size(), imageFlags); |
|
|
|
|
warpAffine(allOnes, imageMask, map, imageMask.size(), maskFlags); |
|
|
|
|
warpAffine(preMask, imageMask, map, imageMask.size(), maskFlags); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
warpPerspective(imageFloat, imageWarped, map, imageWarped.size(), imageFlags); |
|
|
|
|
warpPerspective(gradientX, gradientXWarped, map, gradientXWarped.size(), imageFlags); |
|
|
|
|
warpPerspective(gradientY, gradientYWarped, map, gradientYWarped.size(), imageFlags); |
|
|
|
|
warpPerspective(allOnes, imageMask, map, imageMask.size(), maskFlags); |
|
|
|
|
warpPerspective(preMask, imageMask, map, imageMask.size(), maskFlags); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Scalar imgMean, imgStd, tmpMean, tmpStd; |
|
|
|
|
meanStdDev(imageWarped, imgMean, imgStd, imageMask); |
|
|
|
|
meanStdDev(templateFloat, tmpMean, tmpStd, imageMask); |
|
|
|
@ -497,6 +512,9 @@ double cv::findTransformECC(InputArray templateImage, |
|
|
|
|
// calculate enhanced correlation coefficiont (ECC)->rho
|
|
|
|
|
last_rho = rho; |
|
|
|
|
rho = correlation/(imgNorm*tmpNorm); |
|
|
|
|
if (isnan(rho)) { |
|
|
|
|
CV_Error(Error::StsNoConv, "NaN encountered."); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// project images into jacobian
|
|
|
|
|
project_onto_jacobian_ECC( jacobian, imageWarped, imageProjection); |
|
|
|
|