Esempio n. 1
0
main(int    argc,
     char **argv)
{
l_int32      i;
PIX         *pixs, *pixt0, *pixt1, *pixt2, *pixt3, *pixt4, *pixt5, *pixt6;
static char  mainName[] = "binmorph4_reg";

    pixs = pixRead("feyn.tif");

#if TEST_SYMMETRIC
        /* This works properly if there is an added border */
    resetMorphBoundaryCondition(SYMMETRIC_MORPH_BC);
#if 1
    pixt1 = pixAddBorder(pixs, 64, 0);
    pixTransferAllData(pixs, &pixt1, 0, 0);
#endif
#endif  /* TEST_SYMMETRIC */

    pixt1 = pixCreateTemplateNoInit(pixs);
    pixt2 = pixCreateTemplateNoInit(pixs);
    pixt3 = pixCreateTemplateNoInit(pixs);
    pixt4 = pixCreateTemplateNoInit(pixs);
    pixt5 = pixCreateTemplateNoInit(pixs);
    pixt6 = pixCreateTemplateNoInit(pixs);
    
    for (i = 2; i < 64; i++) {

#if 1
            /* Compare morph composite with morph non-composite */
        DoComparisonDwa1(pixs, pixt1, pixt2, pixt3, pixt4,
                         pixt5, pixt6, i);
#endif

#if 1
            /* Compare DWA non-composite with morph composite */
        if (i < 16)
            DoComparisonDwa2(pixs, pixt1, pixt2, pixt3, pixt4,
                             pixt5, pixt6, i);
            /* Compare DWA composite with DWA non-composite */
        if (i < 16)
            DoComparisonDwa3(pixs, pixt1, pixt2, pixt3, pixt4,
                             pixt5, pixt6, i);
            /* Compare DWA composite with morph composite */
        DoComparisonDwa4(pixs, pixt1, pixt2, pixt3, pixt4,
                         pixt5, pixt6, i);
            /* Compare DWA composite with morph non-composite */
        DoComparisonDwa5(pixs, pixt1, pixt2, pixt3, pixt4,
                         pixt5, pixt6, i);
#endif
    }

    pixDestroy(&pixs);
    pixDestroy(&pixt1);
    pixDestroy(&pixt2);
    pixDestroy(&pixt3);
    pixDestroy(&pixt4);
    pixDestroy(&pixt5);
    pixDestroy(&pixt6);
    return 0;
}
Esempio n. 2
0
/*!
 *  pixDilateGray3h()
 *
 *      Input:  pixs (8 bpp, not cmapped)
 *      Return: pixd, or null on error
 *
 *  Notes:
 *      (1) Special case for horizontal 3x1 brick Sel;
 *          also used as the first step for the 3x3 brick Sel.
 */
static PIX *
pixDilateGray3h(PIX  *pixs)
{
l_uint32  *datas, *datad, *lines, *lined;
l_int32    w, h, wpl, i, j;
l_int32    val0, val1, val2, val3, val4, val5, val6, val7, val8, val9, maxval;
PIX       *pixd;

    PROCNAME("pixDilateGray3h");

    if (!pixs)
        return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
    if (pixGetDepth(pixs) != 8)
        return (PIX *)ERROR_PTR("pixs not 8 bpp", procName, NULL);

    pixd = pixCreateTemplateNoInit(pixs);
    pixSetBorderVal(pixd, 4, 8, 2, 8, 0);  /* only to silence valgrind */
    pixGetDimensions(pixs, &w, &h, NULL);
    datas = pixGetData(pixs);
    datad = pixGetData(pixd);
    wpl = pixGetWpl(pixs);
    for (i = 0; i < h; i++) {
        lines = datas + i * wpl;
        lined = datad + i * wpl;
        for (j = 1; j < w - 8; j += 8) {
            val0 = GET_DATA_BYTE(lines, j - 1);
            val1 = GET_DATA_BYTE(lines, j);
            val2 = GET_DATA_BYTE(lines, j + 1);
            val3 = GET_DATA_BYTE(lines, j + 2);
            val4 = GET_DATA_BYTE(lines, j + 3);
            val5 = GET_DATA_BYTE(lines, j + 4);
            val6 = GET_DATA_BYTE(lines, j + 5);
            val7 = GET_DATA_BYTE(lines, j + 6);
            val8 = GET_DATA_BYTE(lines, j + 7);
            val9 = GET_DATA_BYTE(lines, j + 8);
            maxval = L_MAX(val1, val2);
            SET_DATA_BYTE(lined, j, L_MAX(val0, maxval));
            SET_DATA_BYTE(lined, j + 1, L_MAX(maxval, val3));
            maxval = L_MAX(val3, val4);
            SET_DATA_BYTE(lined, j + 2, L_MAX(val2, maxval));
            SET_DATA_BYTE(lined, j + 3, L_MAX(maxval, val5));
            maxval = L_MAX(val5, val6);
            SET_DATA_BYTE(lined, j + 4, L_MAX(val4, maxval));
            SET_DATA_BYTE(lined, j + 5, L_MAX(maxval, val7));
            maxval = L_MAX(val7, val8);
            SET_DATA_BYTE(lined, j + 6, L_MAX(val6, maxval));
            SET_DATA_BYTE(lined, j + 7, L_MAX(maxval, val9));
        }
    }
    return pixd;
}
Esempio n. 3
0
/*!
 *  pixDilateGray3v()
 *
 *      Input:  pixs (8 bpp, not cmapped)
 *      Return: pixd, or null on error
 *
 *  Notes:
 *      (1) Special case for vertical 1x3 brick Sel;
 *          also used as the second step for the 3x3 brick Sel.
 */
static PIX *
pixDilateGray3v(PIX  *pixs)
{
l_uint32  *datas, *datad, *linesi, *linedi;
l_int32    w, h, wpl, i, j;
l_int32    val0, val1, val2, val3, val4, val5, val6, val7, val8, val9, maxval;
PIX       *pixd;

    PROCNAME("pixDilateGray3v");

    if (!pixs)
        return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
    if (pixGetDepth(pixs) != 8)
        return (PIX *)ERROR_PTR("pixs not 8 bpp", procName, NULL);

    pixd = pixCreateTemplateNoInit(pixs);
    pixGetDimensions(pixs, &w, &h, NULL);
    datas = pixGetData(pixs);
    datad = pixGetData(pixd);
    wpl = pixGetWpl(pixs);
    for (j = 0; j < w; j++) {
        for (i = 1; i < h - 8; i += 8) {
            linesi = datas + i * wpl;
            linedi = datad + i * wpl;
            val0 = GET_DATA_BYTE(linesi - wpl, j);
            val1 = GET_DATA_BYTE(linesi, j);
            val2 = GET_DATA_BYTE(linesi + wpl, j);
            val3 = GET_DATA_BYTE(linesi + 2 * wpl, j);
            val4 = GET_DATA_BYTE(linesi + 3 * wpl, j);
            val5 = GET_DATA_BYTE(linesi + 4 * wpl, j);
            val6 = GET_DATA_BYTE(linesi + 5 * wpl, j);
            val7 = GET_DATA_BYTE(linesi + 6 * wpl, j);
            val8 = GET_DATA_BYTE(linesi + 7 * wpl, j);
            val9 = GET_DATA_BYTE(linesi + 8 * wpl, j);
            maxval = L_MAX(val1, val2);
            SET_DATA_BYTE(linedi, j, L_MAX(val0, maxval));
            SET_DATA_BYTE(linedi + wpl, j, L_MAX(maxval, val3));
            maxval = L_MAX(val3, val4);
            SET_DATA_BYTE(linedi + 2 * wpl, j, L_MAX(val2, maxval));
            SET_DATA_BYTE(linedi + 3 * wpl, j, L_MAX(maxval, val5));
            maxval = L_MAX(val5, val6);
            SET_DATA_BYTE(linedi + 4 * wpl, j, L_MAX(val4, maxval));
            SET_DATA_BYTE(linedi + 5 * wpl, j, L_MAX(maxval, val7));
            maxval = L_MAX(val7, val8);
            SET_DATA_BYTE(linedi + 6 * wpl, j, L_MAX(val6, maxval));
            SET_DATA_BYTE(linedi + 7 * wpl, j, L_MAX(maxval, val9));
        }
    }
    return pixd;
}
/*!
 *  pixCreateTemplate()
 *
 *      Input:  pixs
 *      Return: pixd, or null on error
 *
 *  Notes:
 *      (1) Makes a Pix of the same size as the input Pix, with the
 *          data array allocated and initialized to 0.
 *      (2) Copies the other fields, including colormap if it exists.
 */
PIX *
pixCreateTemplate(PIX  *pixs)
{
PIX     *pixd;

    PROCNAME("pixCreateTemplate");

    if (!pixs)
        return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);

    if ((pixd = pixCreateTemplateNoInit(pixs)) == NULL)
        return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
    memset(pixd->data, 0, 4 * pixd->wpl * pixd->h);
    return pixd;
}
Esempio n. 5
0
main(int    argc,
     char **argv)
{
l_int32      error;
l_uint32    *data;
PIX         *pix1, *pix2, *pix3, *pix1c, *pix2c, *pix1t, *pix2t, *pixd;
PIXA        *pixa;
static char  mainName[] = "pixmem_reg";

    error = 0;
    pixa = pixaCreate(0);

        /* Copy with internal resizing: onto a cmapped image */
    pix1 = pixRead("weasel4.16c.png");
    pix2 = pixRead("feyn-fract.tif");
    pix3 = pixRead("lucasta.150.jpg");
    fprintf(stderr, "before copy 2 --> 3\n");
    pixCopy(pix3, pix2);
    Compare(pix2, pix3, &error);
    pixSaveTiled(pix3, pixa, 4, 1, 30, 32);
    fprintf(stderr, "before copy 3 --> 1\n");
    pixCopy(pix1, pix3);
    Compare(pix2, pix1, &error);
    pixSaveTiled(pix1, pixa, 4, 0, 30, 32);
    pixDestroy(&pix1);
    pixDestroy(&pix2);
    pixDestroy(&pix3);

        /* Copy with internal resizing: from a cmapped image */
    pix1 = pixRead("weasel4.16c.png");
    pix2 = pixRead("feyn-fract.tif");
    pix3 = pixRead("lucasta.150.jpg");
    fprintf(stderr, "before copy 1 --> 2\n");
    pixCopy(pix2, pix1);
    Compare(pix2, pix1, &error);
    pixSaveTiled(pix2, pixa, 1, 1, 30, 32);
    fprintf(stderr, "before copy 2 --> 3\n");
    pixCopy(pix3, pix2);
    Compare(pix3, pix2, &error);
    pixSaveTiled(pix3, pixa, 1, 0, 30, 32);
    pixDestroy(&pix1);
    pixDestroy(&pix2);
    pixDestroy(&pix3);

        /* Transfer of data pixs --> pixd, when pixs is not cloned.
         * pixs is destroyed.  */
    pix1 = pixRead("weasel4.16c.png");
    pix2 = pixRead("feyn-fract.tif");
    pix3 = pixRead("lucasta.150.jpg");
    pix1c = pixCopy(NULL, pix1);
    fprintf(stderr, "before transfer 1 --> 2\n");
    pixTransferAllData(pix2, &pix1, 0, 0);
    Compare(pix2, pix1c, &error);
    pixSaveTiled(pix2, pixa, 1, 1, 30, 32);
    fprintf(stderr, "before transfer 2 --> 3\n");
    pixTransferAllData(pix3, &pix2, 0, 0);
    Compare(pix3, pix1c, &error);
    pixSaveTiled(pix3, pixa, 1, 0, 30, 32);
    pixDestroy(&pix1c);
    pixDestroy(&pix3);

        /* Another transfer of data pixs --> pixd, when pixs is not cloned.
         * pixs is destroyed. */
    pix1 = pixRead("weasel4.16c.png");
    pix2 = pixRead("feyn-fract.tif");
    pix3 = pixRead("lucasta.150.jpg");
    pix1c = pixCopy(NULL, pix1);
    pix2c = pixCopy(NULL, pix2);
    fprintf(stderr, "before copy transfer 1 --> 2\n");
    pixTransferAllData(pix2, &pix1c, 0, 0);
    Compare(pix2, pix1, &error);
    pixSaveTiled(pix2, pixa, 1, 0, 30, 32);
    fprintf(stderr, "before copy transfer 2 --> 3\n");
    pixTransferAllData(pix3, &pix2, 0, 0);
    Compare(pix3, pix1, &error);
    pixSaveTiled(pix3, pixa, 1, 0, 30, 32);
    pixDestroy(&pix1);
    pixDestroy(&pix2c);
    pixDestroy(&pix3);

        /* Transfer of data pixs --> pixd, when pixs is cloned.
         * pixs has its refcount reduced by 1. */
    pix1 = pixRead("weasel4.16c.png");
    pix2 = pixRead("feyn-fract.tif");
    pix3 = pixRead("lucasta.150.jpg");
    pix1c = pixClone(pix1);
    pix2c = pixClone(pix2);
    fprintf(stderr, "before clone transfer 1 --> 2\n");
    pixTransferAllData(pix2, &pix1c, 0, 0);
    Compare(pix2, pix1, &error);
    pixSaveTiled(pix2, pixa, 1, 0, 30, 32);
    fprintf(stderr, "before clone transfer 2 --> 3\n");
    pixTransferAllData(pix3, &pix2c, 0, 0);
    Compare(pix3, pix1, &error);
    pixSaveTiled(pix3, pixa, 1, 0, 30, 32);
    pixDestroy(&pix1);
    pixDestroy(&pix2);
    pixDestroy(&pix3);

        /* Extraction of data when pixs is not cloned, putting
         * the data into a new template of pixs. */
    pix2 = pixRead("feyn-fract.tif");
    fprintf(stderr, "no clone: before extraction and reinsertion of 2\n");
    pix2c = pixCopy(NULL, pix2);  /* for later reference */
    data = pixExtractData(pix2);
    pix2t = pixCreateTemplateNoInit(pix2);
    pixFreeData(pix2t);
    pixSetData(pix2t, data);
    Compare(pix2c, pix2t, &error);
    pixSaveTiled(pix2t, pixa, 4, 1, 30, 32);
    pixDestroy(&pix2);
    pixDestroy(&pix2c);
    pixDestroy(&pix2t);

        /* Extraction of data when pixs is cloned, putting
         * a copy of the data into a new template of pixs. */
    pix1 = pixRead("weasel4.16c.png");
    fprintf(stderr, "clone: before extraction and reinsertion of 1\n");
    pix1c = pixClone(pix1);  /* bump refcount of pix1 to 2 */
    data = pixExtractData(pix1);  /* should make a copy of data */
    pix1t = pixCreateTemplateNoInit(pix1);
    pixFreeData(pix1t);
    pixSetData(pix1t, data);
    Compare(pix1c, pix1t, &error);
    pixSaveTiled(pix1t, pixa, 1, 0, 30, 32);
    pixDestroy(&pix1);
    pixDestroy(&pix1c);
    pixDestroy(&pix1t);

    pixd = pixaDisplay(pixa, 0, 0);
    pixDisplay(pixd, 100, 100);
    pixWrite("/tmp/junkpixmem.png", pixd, IFF_PNG);
    pixaDestroy(&pixa);
    pixDestroy(&pixd);

    if (error)
        fprintf(stderr, "Fail: an error occurred\n");
    else
        fprintf(stderr, "Success: no errors\n");
    return 0;
}
Esempio n. 6
0
void
TestAll(L_REGPARAMS  *rp,
        PIX          *pixs,
        l_int32       symmetric)
{
l_int32  i, n, rsize, fact1, fact2, extra;
l_int32  size, lastsize;
l_int32  dwasize[256];
l_int32  ropsize[256];
PIX     *pix1, *pix2, *pix3, *pix4, *pix5, *pix6;

    if (symmetric) {
            /* This works properly with an added border of 128 */
        resetMorphBoundaryCondition(SYMMETRIC_MORPH_BC);
        pix1 = pixAddBorder(pixs, 128, 0);
        pixTransferAllData(pixs, &pix1, 0, 0);
        fprintf(stderr, "Testing with symmetric boundary conditions\n");
    } else {
        resetMorphBoundaryCondition(ASYMMETRIC_MORPH_BC);
        fprintf(stderr, "Testing with asymmetric boundary conditions\n");
    }

    pix1 = pixCreateTemplateNoInit(pixs);
    pix2 = pixCreateTemplateNoInit(pixs);
    pix3 = pixCreateTemplateNoInit(pixs);
    pix4 = pixCreateTemplateNoInit(pixs);
    pix5 = pixCreateTemplateNoInit(pixs);
    pix6 = pixCreateTemplateNoInit(pixs);

    /* ---------------------------------------------------------------- *
     *                  Faster test; testing fewer sizes                *
     * ---------------------------------------------------------------- */
#if  FASTER_TEST
        /* Compute the actual sizes used for each input size 'i' */
    for (i = 0; i < 256; i++) {
        dwasize[i] = 0;
        ropsize[i] = 0;
    }
    for (i = 65; i < 256; i++) {
        selectComposableSizes(i, &fact1, &fact2);
        rsize = fact1 * fact2;
        ropsize[i] = rsize;
        getExtendedCompositeParameters(i, &n, &extra, &dwasize[i]);
    }

        /* Use only values where the resulting sizes are equal */
    for (i = 65; i < 240; i++) {
        n = 1 + (l_int32)((i - 63) / 62);
        extra = i - 63 - (n - 1) * 62 + 1;
        if (extra == 2) continue;  /* don't use this one (e.g., i == 126) */
        if (ropsize[i] == dwasize[i])
            DoComparisonDwa1(rp, pixs, pix1, pix2, pix3, pix4, pix5, pix6, i);
    }
#endif  /* FASTER_TEST */

    /* ---------------------------------------------------------------- *
     *          Slower test; testing maximum number of sizes            *
     * ---------------------------------------------------------------- */
#if  SLOWER_TEST
    lastsize = 0;
    for (i = 65; i < 199; i++) {
        getExtendedCompositeParameters(i, &n, &extra, &size);
        if (size == lastsize) continue;
        if (size == 126 || size == 188) continue;  /* deliberately off by one */
        lastsize = size;
        DoComparisonDwa2(rp, pixs, pix1, pix2, pix3, pix4, pix5, pix6, size);
    }
#endif  /* SLOWER_TEST */

    fprintf(stderr, "\n");
    pixDestroy(&pix1);
    pixDestroy(&pix2);
    pixDestroy(&pix3);
    pixDestroy(&pix4);
    pixDestroy(&pix5);
    pixDestroy(&pix6);
}
Esempio n. 7
0
main(int    argc,
     char **argv)
{
l_int32      i, n, rsize, fact1, fact2, extra;
l_int32      size, lastsize;
l_int32      dwasize[256];
l_int32      ropsize[256];
PIX         *pixs, *pixt0, *pixt1, *pixt2, *pixt3, *pixt4, *pixt5, *pixt6;
static char  mainName[] = "binmorph5_reg";

    pixs = pixRead("feyn.tif");

#if TEST_SYMMETRIC
        /* This works properly if there's an added border */
    resetMorphBoundaryCondition(SYMMETRIC_MORPH_BC);
#if 1
    pixt1 = pixAddBorder(pixs, 64, 0);
    pixTransferAllData(pixs, &pixt1, 0, 0);
#endif
#endif  /* TEST_SYMMETRIC */

    pixt1 = pixCreateTemplateNoInit(pixs);
    pixt2 = pixCreateTemplateNoInit(pixs);
    pixt3 = pixCreateTemplateNoInit(pixs);
    pixt4 = pixCreateTemplateNoInit(pixs);
    pixt5 = pixCreateTemplateNoInit(pixs);
    pixt6 = pixCreateTemplateNoInit(pixs);
    

    /* ---------------------------------------------------------------- *
     *                  Faster test; testing fewer sizes                *
     * ---------------------------------------------------------------- */
#if  FASTER_TEST 
        /* Compute the actual sizes used for each input size 'i' */
    for (i = 0; i < 256; i++) {
        dwasize[i] = 0;
        ropsize[i] = 0;
    }
    for (i = 65; i < 256; i++) {
        selectComposableSizes(i, &fact1, &fact2);
        rsize = fact1 * fact2;
        ropsize[i] = rsize;
        getExtendedCompositeParameters(i, &n, &extra, &dwasize[i]);
    }

        /* Use only values where the resulting sizes are equal */
    for (i = 65; i < 240; i++) {
        n = 1 + (l_int32)((i - 63) / 62);
        extra = i - 63 - (n - 1) * 62 + 1;
        if (extra == 2) continue;  /* don't use this one (e.g., i == 126) */
        if (ropsize[i] == dwasize[i])
            DoComparisonDwa1(pixs, pixt1, pixt2, pixt3, pixt4,
                             pixt5, pixt6, i);
    }
#endif  /* FASTER_TEST */

    /* ---------------------------------------------------------------- *
     *          Slower test; testing maximum number of sizes            *
     * ---------------------------------------------------------------- */
#if  SLOWER_TEST 
    lastsize = 0;
    for (i = 65; i < 199; i++) {
        getExtendedCompositeParameters(i, &n, &extra, &size);
        if (size == lastsize) continue;
        if (size == 126 || size == 188) continue;  /* deliberately off by one */
        lastsize = size;
        DoComparisonDwa2(pixs, pixt1, pixt2, pixt3, pixt4,
                         pixt5, pixt6, size);
    }
#endif  /* SLOWER_TEST */

    pixDestroy(&pixs);
    pixDestroy(&pixt1);
    pixDestroy(&pixt2);
    pixDestroy(&pixt3);
    pixDestroy(&pixt4);
    pixDestroy(&pixt5);
    pixDestroy(&pixt6);
    return 0;
}
Esempio n. 8
0
//---------------------------------------------------------------------------
//Уменьшение в 2 раза
//Поиск угла
//Предварительное выпрямление
//Эрозия для удаления тонких линий
//Поиск box для обрезки белых полей изображения
//Обрезка предварительно выпрямленного изображения
//Получение трёх изображений:
//------------------------------------------------------------------------------
PIX* LeptPrepareFile::getClearImage(PIX *pix, l_float32 *angle, l_float32 *conf)
{
	PIX        *pixReduce2, *pixDeskew, *pixCrop, *pixErode;
	PIXA       *pixa1, *pixa2;
	l_int32	   result;
	l_float32  _angle, _conf;
	l_int32    XC_crop, YC_crop, XC_old, YC_old, XC_new, YC_new;


		LEP_LOG("enter");
	SetNULL(7, (void **)&pixReduce2, &pixDeskew, &pixCrop, &pixErode, &pixa1, &pixa2, &boxFirstCrop);
	SetNULL(2, (void **)angle, conf);
	try
	{
		LEP_STR_THROW(!pix, "Изображение не найдено");
		//Уменьшение в 2 раза для ускорения (при DPI = 600)
	if ((pix->xres == 600) && (pix->yres == 600))                 //В дальнейшем переработать потому как в текущем варианте обрабатывает корректно только DPI300 и DPI600
		pixReduce2 = pixReduceBinary2(pix, NULL);
	else
	{
		pixReduce2 = pixCreateTemplateNoInit(pix);
		LEP_STR_THROW(!pixReduce2, "Ошибка в pixReduceBinary2");

		pixCopy(pixReduce2, pix);
	}

		LEP_STR_THROW(!pixReduce2, "Ошибка в pixReduceBinary2");
		//Поиск угла наклона
	result = pixFindSkewSweepAndSearch(pixReduce2, &_angle, &_conf,
						4,    //линеное уменьшение,  DEFAULT_SWEEP_REDUCTION = 4
						2,    //бинарное уменьшение, DEFAULT_BS_REDUCTION = 2
						10,   //максимальный угол поиска
				    		0.1,  //дельта угла поиска
						0.01);//конечная дельта угла поиска, DEFAULT_MINBS_DELTA = 0.01
		LEP_STR_THROW(result != 0, "Ошибка поиска угла");
	if (angle) *angle = _angle;
	if (conf) *conf = _conf;
		//Предварительное выпрямление
	pixDeskew = pixRotate(pixReduce2, 3.1415926535 / 180. * _angle, L_ROTATE_AREA_MAP, L_BRING_IN_WHITE, 0, 0);
		LEP_STR_THROW(!pixDeskew, "Ошибка при предварительном повороте изображения");
		//Эрозия для удаления тонких линий
	pixErode = pixCreateTemplateNoInit(pixDeskew);
		LEP_STR_THROW(!pixErode, "Ошибка в pixCreateTemplateNoInit");
	pixCopy(pixErode, pixDeskew);
	pixErodeBrick(pixErode, pixErode, 3, 3);
		//pixWrite("c:\\temp0_0.tif", pixErode, IFF_TIFF_ZIP);
		//Поиск box для обрезки белых полей изображения
	result = pixClipBoxToForeground(pixErode, NULL, NULL, &boxFirstCrop);
		LEP_STR_THROW(result != 0, "Ошибка при поиске обрезки изображения");
		//Получение точки вокруг которой происходило вращение, с учётом обрезки
		XC_old = pixErode->w / 2;      //точка вращения старого изображения на старом изображении
		YC_old = pixErode->h / 2;
		XC_new = boxFirstCrop->w / 2;       //точка вращения нового изображения на новом изображении
		YC_new = boxFirstCrop->h / 2;
		XC_crop = boxFirstCrop->x + XC_new; //точка вращения нового изображения на старом изображении
		YC_crop = boxFirstCrop->y + YC_new;
		centerXRotate = XC_new - (XC_crop - XC_old);   //точка вращения старого изображения на новом изображении
		centerYRotate = YC_new - (YC_crop - YC_old);
		//Обрезка предварительно выпрямленного изображения
	pixCrop = pixClipRectangle(pixDeskew, boxFirstCrop, NULL);
		LEP_STR_THROW(!pixCrop, "Ошибка при обрезке изображения");
		//pixWrite("c:\\pixCrop.tif", pixCrop, IFF_TIFF_ZIP);
	}catch (string error)
	{
		LEP_ERROR(error);
	};

	pixDestroy(&pixReduce2);
	pixDestroy(&pixDeskew);
	pixDestroy(&pixErode);
		LEP_LOG("exit");
	return pixCrop;

}
Esempio n. 9
0
/*!
 *  pixRotateBySampling()
 *
 *      Input:  pixs (1, 2, 4, 8, 16, 32 bpp rgb; can be cmapped)
 *              xcen (x value of center of rotation)
 *              ycen (y value of center of rotation)
 *              angle (radians; clockwise is positive)
 *              incolor (L_BRING_IN_WHITE, L_BRING_IN_BLACK)
 *      Return: pixd, or null on error
 *
 *  Notes:
 *      (1) For very small rotations, just return a clone.
 *      (2) Rotation brings either white or black pixels in
 *          from outside the image.
 *      (3) Colormaps are retained.
 */
PIX *
pixRotateBySampling(PIX *pixs,
                    l_int32 xcen,
                    l_int32 ycen,
                    l_float32 angle,
                    l_int32 incolor) {
    l_int32 w, h, d, i, j, x, y, xdif, ydif, wm1, hm1, wpld;
    l_uint32 val;
    l_float32 sina, cosa;
    l_uint32 *datad, *lined;
    void **lines;
    PIX *pixd;

    PROCNAME("pixRotateBySampling");

    if (!pixs)
        return (PIX *) ERROR_PTR("pixs not defined", procName, NULL);
    if (incolor != L_BRING_IN_WHITE && incolor != L_BRING_IN_BLACK)
        return (PIX *) ERROR_PTR("invalid incolor", procName, NULL);
    pixGetDimensions(pixs, &w, &h, &d);
    if (d != 1 && d != 2 && d != 4 && d != 8 && d != 16 && d != 32)
        return (PIX *) ERROR_PTR("invalid depth", procName, NULL);

    if (L_ABS(angle) < MIN_ANGLE_TO_ROTATE)
        return pixClone(pixs);

    if ((pixd = pixCreateTemplateNoInit(pixs)) == NULL)
        return (PIX *) ERROR_PTR("pixd not made", procName, NULL);
    pixSetBlackOrWhite(pixd, incolor);

    sina = sin(angle);
    cosa = cos(angle);
    datad = pixGetData(pixd);
    wpld = pixGetWpl(pixd);
    wm1 = w - 1;
    hm1 = h - 1;
    lines = pixGetLinePtrs(pixs, NULL);

    /* Treat 1 bpp case specially */
    if (d == 1) {
        for (i = 0; i < h; i++) {  /* scan over pixd */
            lined = datad + i * wpld;
            ydif = ycen - i;
            for (j = 0; j < w; j++) {
                xdif = xcen - j;
                x = xcen + (l_int32)(-xdif * cosa - ydif * sina);
                if (x < 0 || x > wm1) continue;
                y = ycen + (l_int32)(-ydif * cosa + xdif * sina);
                if (y < 0 || y > hm1) continue;
                if (incolor == L_BRING_IN_WHITE) {
                    if (GET_DATA_BIT(lines[y], x))
                        SET_DATA_BIT(lined, j);
                } else {
                    if (!GET_DATA_BIT(lines[y], x))
                        CLEAR_DATA_BIT(lined, j);
                }
            }
        }
        FREE(lines);
        return pixd;
    }

    for (i = 0; i < h; i++) {  /* scan over pixd */
        lined = datad + i * wpld;
        ydif = ycen - i;
        for (j = 0; j < w; j++) {
            xdif = xcen - j;
            x = xcen + (l_int32)(-xdif * cosa - ydif * sina);
            if (x < 0 || x > wm1) continue;
            y = ycen + (l_int32)(-ydif * cosa + xdif * sina);
            if (y < 0 || y > hm1) continue;
            switch (d) {
                case 8:
                    val = GET_DATA_BYTE(lines[y], x);
                    SET_DATA_BYTE(lined, j, val);
                    break;
                case 32:
                    val = GET_DATA_FOUR_BYTES(lines[y], x);
                    SET_DATA_FOUR_BYTES(lined, j, val);
                    break;
                case 2:
                    val = GET_DATA_DIBIT(lines[y], x);
                    SET_DATA_DIBIT(lined, j, val);
                    break;
                case 4:
                    val = GET_DATA_QBIT(lines[y], x);
                    SET_DATA_QBIT(lined, j, val);
                    break;
                case 16:
                    val = GET_DATA_TWO_BYTES(lines[y], x);
                    SET_DATA_TWO_BYTES(lined, j, val);
                    break;
                default:
                    return (PIX *) ERROR_PTR("invalid depth", procName, NULL);
            }
        }
    }

    FREE(lines);
    return pixd;
}