/** * @author YAO Wei, JIA Pei * @version 2010-05-20 * @brief Find the best offset for one point * @param ioShape Input and output - the input and output shape * @param iImg Input - image to be fitted * @param oImages Output - the output images * @param iLev Input - current pyramid level * @param PClose Input - percentage of converged points. Say, 0.9 means if 90% of the points * are judged as converged, the iteration of this pyramid can stop * @param epoch Input - the maximum iteration times * @param profdim Input - dimension used during fitting. For example, the trained data could be 4D, but the user may only use 1D * @note Refer to "AAM Revisited, page 34, figure 13", particularly, those steps. */ void VO_FittingASMNDProfiles::PyramidFit( VO_Shape& ioShape, const cv::Mat& iImg, std::vector<cv::Mat>& oImages, unsigned int iLev, float PClose, unsigned int epoch, unsigned int profdim, bool record) { VO_Shape tempShape = ioShape; int nGoodLandmarks = 0; float PyrScale = pow(2.0f, (float) (iLev) ); const int nQualifyingDisplacements = (int)(this->m_VOASMNDProfile->m_iNbOfPoints * PClose); for(unsigned int iter = 0; iter < epoch; iter++) { this->m_iIteration++; // estimate the best ioShape by profile matching the landmarks in this->m_VOFittingShape nGoodLandmarks = VO_FittingASMNDProfiles::UpdateShape( this->m_VOASMNDProfile, iImg, tempShape, this->m_vShape2DInfo, this->m_VOASMNDProfile->m_vvMeanNormalizedProfile[iLev], this->m_VOASMNDProfile->m_vvvCVMInverseOfSg[iLev], 3, profdim); // conform ioShape to the shape model this->m_VOASMNDProfile->VO_CalcAllParams4AnyShapeWithConstrain( tempShape, this->m_MatModelAlignedShapeParam, this->m_fScale, this->m_vRotateAngles, this->m_MatCenterOfGravity ); tempShape.ConstrainShapeInImage(iImg); if(record) { // If we get better fitting result, record this fitting result cv::Mat temp3 = cv::Mat(this->m_ImageInput.size(), this->m_ImageInput.type(), this->m_ImageInput.channels()); cv::Mat temp3ROI = temp3(cv::Range (0, (int)(this->m_ImageInput.rows/PyrScale) ), cv::Range (0, (int)(this->m_ImageInput.cols/PyrScale) ) ); cv::resize(this->m_ImageInput, temp3ROI, temp3ROI.size()); VO_Fitting2DSM::VO_DrawMesh(tempShape / this->m_fScale2, this->m_VOASMNDProfile, temp3); oImages.push_back(temp3); } // the fitting result is good enough to stop the iteration if(nGoodLandmarks > nQualifyingDisplacements) break; } ioShape = tempShape; }
/** * @author YAO Wei, JIA Pei * @version 2010-05-20 * @brief Find the best offset for one point * @param iImg Input - image to be fitted * @param ioShape Input and output - the input and output shape * @param iShapeInfo Input - the shape information * @param iLev Input - current pyramid level * @param PClose Input - percentage of converged points. Say, 0.9 means if 90% of the points * are judged as converged, the iteration of this pyramid can stop * @param epoch Input - the maximum iteration times * @param profdim Input - dimension used during fitting. For example, the trained data could be 4D, but the user may only use 1D * @note Refer to "AAM Revisited, page 34, figure 13", particularly, those steps. */ void VO_FittingASMNDProfiles::PyramidFit( VO_Shape& ioShape, const cv::Mat& iImg, unsigned int iLev, float PClose, unsigned int epoch, unsigned int profdim) { VO_Shape tempShape = ioShape; int nGoodLandmarks = 0; float PyrScale = pow(2.0f, (float) (iLev-1.0f) ); const int nQualifyingDisplacements = (int)(this->m_VOASMNDProfile->m_iNbOfPoints * PClose); for(unsigned int iter = 0; iter < epoch; iter++) { this->m_iIteration++; // estimate the best ioShape by profile matching the landmarks in this->m_VOFittingShape nGoodLandmarks = VO_FittingASMNDProfiles::UpdateShape( this->m_VOASMNDProfile, iImg, tempShape, this->m_vShape2DInfo, this->m_VOASMNDProfile->m_vvMeanNormalizedProfile[iLev], this->m_VOASMNDProfile->m_vvvCVMInverseOfSg[iLev], 3, profdim); // conform ioShape to the shape model this->m_VOASMNDProfile->VO_CalcAllParams4AnyShapeWithConstrain( tempShape, this->m_MatModelAlignedShapeParam, this->m_fScale, this->m_vRotateAngles, this->m_MatCenterOfGravity ); tempShape.ConstrainShapeInImage(iImg); // the fitting result is good enough to stop the iteration if(nGoodLandmarks > nQualifyingDisplacements) break; } ioShape = tempShape; }