void ShapeModel::viewShapeModelUpdate(ModelViewInfo *pInfo)
{
    Mat_< double > paramV;
    paramV.create(this->nShapeParams, 1);
    for (int i=0;i<nShapeParams;i++){
        paramV(i, 0) = (pInfo->vList[i]/30.0 - 0.5)*6*
                        sqrt(pcaShape->eigenvalues.at<double>(i, 0));
    }
    Mat_<cv::Vec3b> img;
    
    ModelImage s;
    s.setShapeInfo(&shapeInfo);
    s.loadTrainImage(Mat_<unsigned char>::ones(190*2, 160*2)*255);
    projectParamToShape(paramV, s.shapeVec);
    SimilarityTrans st = s.shapeVec.getShapeTransformFitingSize(
                            Size(320, 380));
    s.buildFromShapeVec(st, 1000);
    img = s.show(0, -1, false);
    imshow("Viewing Shape Model", img);
}
示例#2
0
void ASMModel::doSearch(const cv::Mat& img, FitResult& fitResult, int verbose)
{
    // Step 2: Ensure it is a grayscale image
    Mat grayImg;
    if (img.channels() == 3){
        cv::cvtColor(img, grayImg, CV_BGR2GRAY);
    }
    else
        grayImg = img;
    
    // Step 3: Resize each face image
    Mat resizedImg;
    // Resize the image to proper size
    double ratio;
    ratio = sqrt( double(40000) / (grayImg.rows * grayImg.cols));
    cv::resize(grayImg, resizedImg, cv::Size(grayImg.cols*ratio, grayImg.rows*ratio));
    
    puts("Start fitting...");
    ModelImage curSearch;
    curSearch.setShapeInfo( &shapeInfo );
    curSearch.loadTrainImage(resizedImg);

    fitResult.params = Mat_<double>::zeros(nShapeParams, 1);

    ShapeVec &sv = curSearch.shapeVec;
    ShapeVec shape_old;
    
    projectParamToShape(fitResult.params, sv);
    SimilarityTrans st = sv.getShapeTransformFitingSize(resizedImg.size(), 
                                                      searchScaleRatio,
                                                      searchInitXOffset,
                                                      searchInitYOffset);
    fitResult.transformation = st;
    curSearch.buildFromShapeVec(st);

    pyramidLevel = 2;
    int k=localFeatureRad;
    
    ns=4;
    
    // sum of offsets of current iteration.
    int totalOffset;
    if (verbose >= ASM_FIT_VERBOSE_AT_LEVEL)
        curSearch.show();
    // Update each point
    vector< Point_< int > > V;
    for (int l=this->pyramidLevel; l>=0; l--){
        if (verbose >= ASM_FIT_VERBOSE_AT_LEVEL)
            printf("Level %d\n", l);
        Mat_<double> img=curSearch.getDerivImage(l);
//         printf("Image size: %dx%d\n", img.cols, img.rows);
        // at most 5 iterations for each level
        int runT;
        double avgMov;
		
		// [zl] this number has funky effects and also asjust speed a bit. 
		
        for (runT=0; runT<3; runT++){
            // Backup current shape
            shape_old.fromPointList(curSearch.points);
            
            totalOffset = 0;
            vector< Point_< int > > bestEP(nMarkPoints);
            for (int i=0; i<this->nMarkPoints; i++){
                if (verbose >= ASM_FIT_VERBOSE_AT_POINT)
                    printf("Dealing point %d...\n", i);

                Mat_< double > nrmV(2*k+1, 1);
                double curBest=-1, ct;
                int bestI = 0;
                double absSum;
                for (int e=ns; e>=-ns; e--){
                    curSearch.getPointsOnNorm(i, k, l, V, 2*searchStepAreaRatio, e);
                
                    absSum = 0;
                    for (int j=-k;j<=k;j++){
                        nrmV(j+k, 0) = img(V[j+k]);
                        absSum += fabs(nrmV(j+k, 0));
                    }
                    nrmV *= 1/absSum;
                    ct = cv::Mahalanobis(nrmV, this->meanG[l][i], this->iCovarG[l][i]);
//                     printf("absSum: %lf, ct: %lf\n", absSum, ct);
                    if (verbose >= ASM_FIT_VERBOSE_AT_POINT)
                        curSearch.show(l, i, true, e);
                    
                    if (ct<curBest || curBest<0){
                        curBest = ct;
                        bestI = e;
                        bestEP[i] = V[k];
                    }
                }
//                 printf("best e: %d\n", bestI);
//                 bestEP[i] = V[bestI+(ns+k)];
                totalOffset += abs(bestI);
                
                if (verbose >= ASM_FIT_VERBOSE_AT_POINT)
                    curSearch.show(l, i, true, bestI);
            }
            for (int i=0;i<nMarkPoints;i++){
                curSearch.points[i] = bestEP[i];
                curSearch.points[i].x <<= l;
                if (l>0) curSearch.points[i].x += (1<<(l-1));
                curSearch.points[i].y <<= l;
                if (l>0) curSearch.points[i].y += (1<<(l-1));
            }
            curSearch.shapeVec.fromPointList(curSearch.points);
            
            if (verbose >= ASM_FIT_VERBOSE_AT_ITERATION)
                curSearch.show(l);
            
            // Project to PCA model and then back
            //findParamForShape(curSearch.shapeVec,  fitResult);
            findParamForShapeBTSM(curSearch.shapeVec, shape_old, fitResult, fitResult, l);
            
            pcaPyr[l].backProject(fitResult.params, sv);
            
            // Reconstruct new shape
            curSearch.buildFromShapeVec(fitResult.transformation);
            
            avgMov = (double)totalOffset/nMarkPoints;
            if (verbose >= ASM_FIT_VERBOSE_AT_ITERATION){
                printf("Iter %d:  Average offset: %.3f\n", runT+1, avgMov);
                curSearch.show(l);
            }
            
            if (avgMov < 1.3){
                runT++;
                break;
            }
        }
        if (verbose == ASM_FIT_VERBOSE_AT_LEVEL){
            printf("%d iterations. average offset for last iter: %.3f\n", runT, avgMov);
            curSearch.show(l);
        }
    }
    
    SimilarityTrans s2;
    s2.a = 1/ratio;
    fitResult.transformation = s2 * fitResult.transformation;
}