Beispiel #1
0
Shape ConvertShape(          // return shape with nlandmarks, return no rows if can't
    const Shape& shape,      // in
    int          nlandmarks) // in: shape.rows=no change, 17=shape17, anything else return no rows
                             //     if shape.rows=77, treat specially:
                             //     77=nochange, 76=muct76, 68=xm2vts, 22=ar, 20=bioid, 17=shape17
{
    Shape newshape;
    if (nlandmarks == shape.rows)
        newshape = shape.clone();
    else if (nlandmarks == 17)
        newshape = Shape17OrEmpty(shape);
    else if (shape.rows == 76) // MUCT 76
    {
        switch (nlandmarks)
        {
        case 68:
            newshape = DimKeep(shape.clone(), 68, 2);  // MUCT 68 and XM2VTS
            break;
        default:
            break;
        }
    }
    else if (shape.rows == 77) // MUCT 77 (Stasm version 4)
    {
        switch (nlandmarks)
        {
        case 20:
            newshape = Shape77As20(shape);  // BioID
            break;
        case 22:
            newshape = Shape77As22(shape);  // AR
            break;
        case 68:
            newshape = Shape77As68(shape);  // MUCT 68 and XM2VTS
            break;
        case 76:
            newshape = Shape77As76(shape); // MUCT 76 (Stasm version 3)
            break;
        default:
            break;
        }
    }
    CV_Assert(newshape.rows == nlandmarks || newshape.rows == 0);
    return newshape;
}
Beispiel #2
0
void GenAndWriteShapeMod(             // generate the shape model and write it to a .mh file
    ShapeFile&  sh,                   // io: shapes_ field modified if there are missing points
                                      //     entire sh changed if TASM_SUBSET_DESC_MODS
    const char* outdir,               // in: output directory (-d flag)
    const char* modname,              // in: e.g. "yaw00"
    const char* cmdline,              // in: command line used to invoke tasm
    bool        force_facedet,        // in: facedet the images themselves (ignore shapefile facedets)
    bool        write_detpars,        // in: write the image detpars to facedet.shape
    bool        write_imputed_shapes, // in: write imputed.shapes file if shapes are imputed
    bool        write_imgs)           // in: write images showing landmark tab values
{
    clock_t start_time = clock();
    lprintf("--- Generating the shape model ---\n");

    // the reference shape is the first shape with no missing
    // points and irefshape is its index
    int irefshape = FirstShapeWithAllPoints(sh);

    vec_int nused_vec; // vec [nshapes] of int, nbr of used points in each shape
    NbrUsedPointsVec(nused_vec, sh.shapes_);

    const int nshapes_with_missing_points =
        NbrShapesWithMissingPoints(sh.shapes_, nused_vec);

    if (nshapes_with_missing_points)
        ShowPercentagePointsMissing(
            nshapes_with_missing_points, sh.shapes_);

    Shape     meanshape;
    VEC       eigvals;
    MAT       eigvecs;
    vec_Shape aligned_shapes; // sh.shapes_ aligned to ref shape

    GenShapeMod(
        meanshape, eigvals, eigvecs, aligned_shapes,
        sh, irefshape, nused_vec, outdir, modname, cmdline,
        force_facedet, write_detpars);

    // shapemodel_sh is the shapes we used to build the shape model
    // (this will be sh unless TASM_REBUILD_SUBSET is not NULL)
    ShapeFile shapemodel_sh(sh); // copy sh to shapemodel_sh

    if (nshapes_with_missing_points)
    {
        // Points are missing in some shapes (typically because the points
        // were manually landmarked as missing because they are obscured).
        // Update sh.shape by imputing those points.
        // After this, all shapes in sh.shapes_ have all points.

        ImputeMissingPoints(sh.shapes_,
                            aligned_shapes, meanshape, eigvals, eigvecs);

        if (write_imputed_shapes)
            WriteImputedShapes(sh, outdir, cmdline); // write imputed.shape

        if (TASM_REBUILD_SUBSET)
        {
            lprintf("--- Regenerating the shape model "
                    "using the imputed shapes matching %s---\n",
                    TASM_REBUILD_SUBSET);
            lprintf("Reference shape is now the first shape "
                    "(since all shapes now all have all landmarks)\n");
            irefshape = 0;
            // copy sh from ImputeMissingPoints above to shapemodel_sh
            shapemodel_sh = sh;
            shapemodel_sh.Subset_(TASM_REBUILD_SUBSET);
            if (TASM_SUBSET_DESC_MODS)
                sh = shapemodel_sh;
            NbrUsedPointsVec(nused_vec, shapemodel_sh.shapes_);
            GenShapeMod(
                meanshape, eigvals, eigvecs, aligned_shapes,
                shapemodel_sh, irefshape, nused_vec, outdir,
                modname, cmdline,
                force_facedet, false /*write_detpars*/);
        }
    }
    WriteShapeMod(TASM_MODNAME, meanshape, eigvals, eigvecs, outdir, cmdline);

    const double totaltime = double(clock() - start_time) / CLOCKS_PER_SEC;
    lprintf("[%.1f secs%s to generate the shape model]\n",
            totaltime,
            totaltime > 180? ssprintf(" (%.1f minutes)", totaltime / 60): "");

    if (write_imgs)
        TasmDraw(shapemodel_sh, irefshape, meanshape, outdir);

    // sanity check that we convert to Shape17 correctly or not at all
    const Shape shape17(Shape17OrEmpty(sh.shapes_[irefshape]));
    if (shape17.rows) // converted to Shape17?
        SanityCheckShape17(shape17);
}
Beispiel #3
0
static void TraceShape(  // write an image file showing current shape on the image
    const Shape& shape,  // in: current search shape
    const Image& pyrimg, // in: image scaled to this pyramid level
    int          ilev,   // in: pyramid level (0 is full size)
    int          iter,   // in: model iteration (-1 if start shape)
    const char*  suffix) // in
{
#if TRACE_IMAGES // will be 0 unless debugging (defined in stasm.h)

    static int index; // number images so they appear in order in the directory
    // start at index 30 because lower indices have already used for facedet etc.
    if (strcmp(suffix, "start") == 0)
        index = 30;
    Image img; // pyrimg rescaled back to full size image (after rescaling by eyemouth)
    const double RESOLUTION = 2; // 1 for no extra resolution, 2 for double resolution
    const double rescale = RESOLUTION / GetPyrScale(ilev);
    cv::resize(pyrimg, img, cv::Size(), rescale, rescale, cv::INTER_NEAREST);
    CImage cimg; cvtColor(img, cimg, CV_GRAY2BGR); // color image
    DesaturateImg(cimg);
    Shape shape1(RoundMat(shape));
    shape1 += .4; // put shape points in center of rescaled pixels
    shape1 *= rescale;
    DrawShape(cimg, shape1, C_YELLOW, false, 1);
    char path[SLEN];
    if (iter < 0) // start shape?
        sprintf(path, "%s_%2.2d_%s.bmp", Base(imgpath_g), index, suffix);
    else
        sprintf(path, "%s_%2.2d_lev%d_iter%d_%s.bmp",
                Base(imgpath_g), index, ilev, iter, suffix);
    ImgPrintf(cimg, 10 * RESOLUTION, 20 * RESOLUTION, C_YELLOW, 2, path);
    if (iter >= 0)
    {
        // draw 1D patch boundary at one point (patch is drawn
        // horizontal, not rotated to shape boundary as it should be)
        // [Thanks to Satish Lokkoju for RoundMat fix]

        Shape shape2(RoundMat(shape));
        int ipoint = 0;
        int proflen = 9; // TASM_1D_PROFLEN
        int x1 = cvRound(shape2(ipoint, IX)) - proflen / 2;
        int x2 = x1 + proflen;
        int y1 = cvRound(shape2(ipoint, IY));
        int y2 = y1 + 1;
        rectangle(cimg,
                  cv::Point(cvRound(rescale * x1), cvRound(rescale * y1)),
                  cv::Point(cvRound(rescale * x2), cvRound(rescale * y2)),
                  CV_RGB(255,0,0), 1);

        // draw 2D patch boundary at one point

        if (ilev <= HAT_START_LEV) // we use HATs only at upper pyr levs
        {
            // get position of left eye pupil by first converting to a shape17
            ipoint = 0; // assume we can't get position of left eye pupil
            Shape newshape(Shape17OrEmpty(shape2));
            if (newshape.rows) // successfully converted to a shape17?
                ipoint = L17_LPupil;
            else
                newshape = shape2;
            #define round2(x) 2 * cvRound((x) / 2)
            int patchwidth = HAT_PATCH_WIDTH + round2(ilev * HAT_PATCH_WIDTH_ADJ);
            x1 = cvRound(newshape(ipoint, IX)) - patchwidth / 2;
            x2 = x1 + patchwidth;
            y1 = cvRound(newshape(ipoint, IY)) - patchwidth / 2;
            y2 = y1 + patchwidth;
            rectangle(cimg,
                      cv::Point(cvRound(rescale * x1), cvRound(rescale * y1)),
                      cv::Point(cvRound(rescale * x2), cvRound(rescale * y2)),
                      CV_RGB(255,0,0), 1);
        }
    }
    lprintf("%s\n", path);
    if (!cv::imwrite(path, cimg))
        Err("Cannot write %s", path);
    index++;

#endif // TRACE_IMAGES
}