/*! * pixProjectivePtaGray() * * Input: pixs (8 bpp) * ptad (4 pts of final coordinate space) * ptas (4 pts of initial coordinate space) * grayval (0 to bring in BLACK, 255 for WHITE) * Return: pixd, or null on error */ PIX * pixProjectivePtaGray(PIX *pixs, PTA *ptad, PTA *ptas, l_uint8 grayval) { l_float32 *vc; PIX *pixd; PROCNAME("pixProjectivePtaGray"); if (!pixs) return (PIX *)ERROR_PTR("pixs not defined", procName, NULL); if (!ptas) return (PIX *)ERROR_PTR("ptas not defined", procName, NULL); if (!ptad) return (PIX *)ERROR_PTR("ptad not defined", procName, NULL); if (pixGetDepth(pixs) != 8) return (PIX *)ERROR_PTR("pixs must be 8 bpp", procName, NULL); if (ptaGetCount(ptas) != 4) return (PIX *)ERROR_PTR("ptas count not 4", procName, NULL); if (ptaGetCount(ptad) != 4) return (PIX *)ERROR_PTR("ptad count not 4", procName, NULL); /* Get backwards transform from dest to src, and apply it */ getProjectiveXformCoeffs(ptad, ptas, &vc); pixd = pixProjectiveGray(pixs, vc, grayval); FREE(vc); return pixd; }
/*! * pixProjectiveSampledPta() * * Input: pixs (all depths) * ptad (4 pts of final coordinate space) * ptas (4 pts of initial coordinate space) * incolor (L_BRING_IN_WHITE, L_BRING_IN_BLACK) * Return: pixd, or null on error * * Notes: * (1) Brings in either black or white pixels from the boundary. * (2) Retains colormap, which you can do for a sampled transform.. * (3) No 3 of the 4 points may be collinear. * (4) For 8 and 32 bpp pix, better quality is obtained by the * somewhat slower pixProjectivePta(). See that * function for relative timings between sampled and interpolated. */ PIX * pixProjectiveSampledPta(PIX *pixs, PTA *ptad, PTA *ptas, l_int32 incolor) { l_float32 *vc; PIX *pixd; PROCNAME("pixProjectiveSampledPta"); if (!pixs) return (PIX *)ERROR_PTR("pixs not defined", procName, NULL); if (!ptas) return (PIX *)ERROR_PTR("ptas not defined", procName, NULL); if (!ptad) return (PIX *)ERROR_PTR("ptad not defined", procName, NULL); if (incolor != L_BRING_IN_WHITE && incolor != L_BRING_IN_BLACK) return (PIX *)ERROR_PTR("invalid incolor", procName, NULL); if (ptaGetCount(ptas) != 4) return (PIX *)ERROR_PTR("ptas count not 4", procName, NULL); if (ptaGetCount(ptad) != 4) return (PIX *)ERROR_PTR("ptad count not 4", procName, NULL); /* Get backwards transform from dest to src, and apply it */ getProjectiveXformCoeffs(ptad, ptas, &vc); pixd = pixProjectiveSampled(pixs, vc, incolor); FREE(vc); return pixd; }
// Computes the coefficients of a randomized projective transformation. // The image transform requires backward transformation coefficient, and the // box transform the forward coefficients. // Returns the incolor arg to pixProjective. int ProjectiveCoeffs(int width, int height, TRand* randomizer, float** im_coeffs, float** box_coeffs) { // Setup "from" points. Pta* src_pts = ptaCreate(4); ptaAddPt(src_pts, 0.0f, 0.0f); ptaAddPt(src_pts, width, 0.0f); ptaAddPt(src_pts, width, height); ptaAddPt(src_pts, 0.0f, height); // Extract factors from pseudo-random sequence. float factors[FN_NUM_FACTORS]; float shear = 0.0f; // Shear is signed. for (int i = 0; i < FN_NUM_FACTORS; ++i) { // Everything is squared to make wild values rarer. if (i == FN_SHEAR) { // Shear is signed. shear = randomizer->SignedRand(0.5 / 3.0); shear = shear >= 0.0 ? shear * shear : -shear * shear; // Keep the sheared points within the original rectangle. if (shear < -factors[FN_X0]) shear = -factors[FN_X0]; if (shear > factors[FN_X1]) shear = factors[FN_X1]; factors[i] = shear; } else if (i != FN_INCOLOR) { factors[i] = fabs(randomizer->SignedRand(1.0)); if (i <= FN_Y3) factors[i] *= 5.0 / 8.0; else factors[i] *= 0.5; factors[i] *= factors[i]; } } // Setup "to" points. Pta* dest_pts = ptaCreate(4); ptaAddPt(dest_pts, factors[FN_X0] * width, factors[FN_Y0] * height); ptaAddPt(dest_pts, (1.0f - factors[FN_X1]) * width, factors[FN_Y1] * height); ptaAddPt(dest_pts, (1.0f - factors[FN_X1] + shear) * width, (1 - factors[FN_Y2]) * height); ptaAddPt(dest_pts, (factors[FN_X0] + shear) * width, (1 - factors[FN_Y3]) * height); getProjectiveXformCoeffs(dest_pts, src_pts, im_coeffs); getProjectiveXformCoeffs(src_pts, dest_pts, box_coeffs); ptaDestroy(&src_pts); ptaDestroy(&dest_pts); return factors[FN_INCOLOR] > 0.5f ? L_BRING_IN_WHITE : L_BRING_IN_BLACK; }
static l_float32 * Generate4PtTransformVector(l_int32 type) { l_int32 i; l_float32 *vc; PTA *ptas, *ptad; ptas = ptaCreate(4); ptad = ptaCreate(4); for (i = 0; i < 4; i++) { ptaAddPt(ptas, xs[i], ys[i]); ptaAddPt(ptad, xd[i], yd[i]); } if (type == PROJECTIVE) getProjectiveXformCoeffs(ptad, ptas, &vc); else /* BILINEAR */ getBilinearXformCoeffs(ptad, ptas, &vc); ptaDestroy(&ptas); ptaDestroy(&ptad); return vc; }