Exemple #1
0
l_int32 main(int    argc,
             char **argv)
{
l_int32    i, n, w, h, val;
l_uint32   val32;
L_AMAP    *m;
NUMA      *na;
PIX       *pix;
PIXCMAP   *cmap;
RB_TYPE    key, value;
RB_TYPE   *pval;

    lept_mkdir("lept/map");

    pix = pixRead("weasel8.240c.png");
    pixGetDimensions(pix, &w, &h, NULL);
    fprintf(stderr, "Image area in pixels: %d\n", w * h);
    cmap = pixGetColormap(pix);

        /* Build the histogram, stored in a map.  Then compute
         * and display the histogram as the number of pixels vs
         * the colormap index */
    m = BuildMapHistogram(pix, 1, FALSE);
    TestMapIterator1(m, FALSE);
    TestMapIterator2(m, FALSE);
    DisplayMapHistogram(m, cmap, "/tmp/lept/map/map1");
    l_amapDestroy(&m);

        /* Ditto, but just with a few pixels */
    m = BuildMapHistogram(pix, 14, TRUE);
    DisplayMapHistogram(m, cmap, "/tmp/lept/map/map2");
    l_amapDestroy(&m);

        /* Do in-order tranversals, using the iterators */
    m = BuildMapHistogram(pix, 7, FALSE);
    TestMapIterator1(m, TRUE);
    TestMapIterator2(m, TRUE);
    l_amapDestroy(&m);

        /* Do in-order tranversals, with iterators and destroying the map */
    m = BuildMapHistogram(pix, 7, FALSE);
    TestMapIterator3(m, TRUE);
    lept_free(m);
    m = BuildMapHistogram(pix, 7, FALSE);
    TestMapIterator4(m, TRUE);
    lept_free(m);

        /* Do in-order tranversals, with iterators and reversing the map */
    m = BuildMapHistogram(pix, 7, FALSE);
    TestMapIterator5(m, TRUE);
    l_amapDestroy(&m);

        /* Build a histogram the old-fashioned way */
    na = pixGetCmapHistogram(pix, 1);
    numaWrite("/tmp/lept/map/map2.na", na);
    gplotSimple1(na, GPLOT_X11, "/tmp/lept/map/map1", NULL);
    numaDestroy(&na);

        /* Build a separate map from (rgb) --> colormap index ... */
    m = l_amapCreate(L_UINT_TYPE);
    n = pixcmapGetCount(cmap);
    for (i = 0; i < n; i++) {
        pixcmapGetColor32(cmap, i, &val32);
        key.utype = val32;
        value.itype = i;
        l_amapInsert(m, key, value);
    }
        /* ... and test the map */
    for (i = 0; i < n; i++) {
        pixcmapGetColor32(cmap, i, &val32);
        key.utype = val32;
        pval = l_amapFind(m, key);
        if (i != pval->itype)
            fprintf(stderr, "i = %d != val = %llx\n", i, pval->itype);
    }
    l_amapDestroy(&m);

    pixDestroy(&pix);
    return 0;
}
Exemple #2
0
/*!
 * \brief   pixColorSegmentRemoveColors()
 *
 * \param[in]    pixd  8 bpp, colormapped
 * \param[in]    pixs  32 bpp rgb, with initial pixel values
 * \param[in]    finalcolors max number of colors to retain
 * \return  0 if OK, 1 on error
 *
 * <pre>
 * Notes:
 *      (1) This operation is in-place.
 *      (2) This is phase 4 of color segmentation, and the second part
 *          of the 2-step noise removal.  Only 'finalcolors' different
 *          colors are retained, with colors with smaller populations
 *          being replaced by the nearest color of the remaining colors.
 *          For highest accuracy, for pixels that are being replaced,
 *          we find the nearest colormap color  to the original rgb color.
 * </pre>
 */
l_ok
pixColorSegmentRemoveColors(PIX     *pixd,
                            PIX     *pixs,
                            l_int32  finalcolors)
{
l_int32    i, ncolors, index, tempindex;
l_int32   *tab;
l_uint32   tempcolor;
NUMA      *na, *nasi;
PIX       *pixm;
PIXCMAP   *cmap;

    PROCNAME("pixColorSegmentRemoveColors");

    if (!pixd)
        return ERROR_INT("pixd not defined", procName, 1);
    if (pixGetDepth(pixd) != 8)
        return ERROR_INT("pixd not 8 bpp", procName, 1);
    if ((cmap = pixGetColormap(pixd)) == NULL)
        return ERROR_INT("cmap not found", procName, 1);
    if (!pixs)
        return ERROR_INT("pixs not defined", procName, 1);
    ncolors = pixcmapGetCount(cmap);
    if (finalcolors >= ncolors)  /* few enough colors already; nothing to do */
        return 0;

        /* Generate a mask over all pixels that are not in the
         * 'finalcolors' most populated colors.  Save the colormap
         * index of any one of the retained colors in 'tempindex'.
         * The LUT has values 0 for the 'finalcolors' most populated colors,
         * which will be retained; and 1 for the rest, which are marked
         * by fg pixels in pixm and will be removed. */
    na = pixGetCmapHistogram(pixd, 1);
    if ((nasi = numaGetSortIndex(na, L_SORT_DECREASING)) == NULL) {
        numaDestroy(&na);
        return ERROR_INT("nasi not made", procName, 1);
    }
    numaGetIValue(nasi, finalcolors - 1, &tempindex);  /* retain down to this */
    pixcmapGetColor32(cmap, tempindex, &tempcolor);  /* use this color */
    tab = (l_int32 *)LEPT_CALLOC(256, sizeof(l_int32));
    for (i = finalcolors; i < ncolors; i++) {
        numaGetIValue(nasi, i, &index);
        tab[index] = 1;
    }

    pixm = pixMakeMaskFromLUT(pixd, tab);
    LEPT_FREE(tab);

        /* Reassign the masked pixels temporarily to the saved index
         * (tempindex).  This guarantees that no pixels are labeled by
         * a colormap index of any colors that will be removed.
         * The actual value doesn't matter, as long as it's one
         * of the retained colors, because these pixels will later
         * be reassigned based on the full set of colors retained
         * in the colormap. */
    pixSetMasked(pixd, pixm, tempcolor);

        /* Now remove unused colors from the colormap.  This reassigns
         * image pixels as required. */
    pixRemoveUnusedColors(pixd);

        /* Finally, reassign the pixels under the mask (those that were
         * given a 'tempindex' value) to the nearest color in the colormap.
         * This is the function used in phase 2 on all image pixels; here
         * it is only used on the masked pixels given by pixm. */
    pixAssignToNearestColor(pixd, pixs, pixm, LEVEL_IN_OCTCUBE, NULL);

    pixDestroy(&pixm);
    numaDestroy(&na);
    numaDestroy(&nasi);
    return 0;
}