97l_int32 w, h, d, i, j, wplt, wpld, gx, gy, vald;
98l_int32 val1, val2, val3, val4, val5, val6, val7, val8, val9;
99l_uint32 *datat, *linet, *datad, *lined;
103 return (
PIX *)ERROR_PTR(
"pixs not defined", __func__, NULL);
104 pixGetDimensions(pixs, &w, &h, &d);
106 return (
PIX *)ERROR_PTR(
"pixs not 8 bpp", __func__, NULL);
109 return (
PIX *)ERROR_PTR(
"invalid orientflag", __func__, NULL);
112 if ((pixt = pixAddMirroredBorder(pixs, 1, 1, 1, 1)) == NULL)
113 return (
PIX *)ERROR_PTR(
"pixt not made", __func__, NULL);
116 pixd = pixCreateTemplate(pixs);
117 datat = pixGetData(pixt);
118 wplt = pixGetWpl(pixt);
119 datad = pixGetData(pixd);
120 wpld = pixGetWpl(pixd);
121 for (i = 0; i < h; i++) {
122 linet = datat + i * wplt;
123 lined = datad + i * wpld;
124 for (j = 0; j < w; j++) {
147 vald = L_ABS(val1 + 2 * val4 + val7
148 - val3 - 2 * val6 - val9) >> 3;
150 vald = L_ABS(val1 + 2 * val2 + val3 - val7
151 - 2 * val8 - val9) >> 3;
153 gx = L_ABS(val1 + 2 * val2 + val3 - val7
154 - 2 * val8 - val9) >> 3;
155 gy = L_ABS(val1 + 2 * val4 + val7
156 - val3 - 2 * val6 - val9) >> 3;
157 vald = L_MIN(255, gx + gy);
203l_int32 w, h, d, i, j, wpls, wpld;
204l_int32 cval, rval, bval, val, lgrad, rgrad, tgrad, bgrad;
205l_uint32 *datas, *lines, *datad, *lined;
209 return (
PIX *)ERROR_PTR(
"pixs not defined", __func__, NULL);
210 pixGetDimensions(pixs, &w, &h, &d);
212 return (
PIX *)ERROR_PTR(
"pixs not 8 bpp", __func__, NULL);
214 return (
PIX *)ERROR_PTR(
"invalid orientflag", __func__, NULL);
216 pixd = pixCreateTemplate(pixs);
217 datas = pixGetData(pixs);
218 wpls = pixGetWpl(pixs);
219 datad = pixGetData(pixd);
220 wpld = pixGetWpl(pixd);
222 for (i = 0; i < h; i++) {
223 lines = datas + i * wpls;
224 lined = datad + i * wpld;
227 for (j = 1; j < w - 1; j++) {
230 if (lgrad * rgrad > 0) {
232 val = -L_MAX(lgrad, rgrad);
234 val = L_MIN(lgrad, rgrad);
243 for (j = 0; j < w; j++) {
244 lines = datas + wpls;
247 for (i = 1; i < h - 1; i++) {
249 lined = datad + i * wpld;
252 if (tgrad * bgrad > 0) {
254 val = -L_MAX(tgrad, bgrad);
256 val = L_MIN(tgrad, bgrad);
315 const char *debugfile)
317l_int32 i, n, val, nval, diff, njumps, jumpsum, nreversal;
320 if (pjpl) *pjpl = 0.0;
321 if (pjspl) *pjspl = 0.0;
322 if (prpl) *prpl = 0.0;
323 if (!pjpl && !pjspl && !prpl && !debugfile)
324 return ERROR_INT(
"no output requested", __func__, 1);
325 if (!pixs || pixGetDepth(pixs) != 1)
326 return ERROR_INT(
"pixs not defined or not 1 bpp", __func__, 1);
329 return ERROR_INT(
"invalid side", __func__, 1);
331 return ERROR_INT(
"invalid minjump; must be >= 1", __func__, 1);
333 return ERROR_INT(
"invalid minreversal; must be >= 1", __func__, 1);
336 return ERROR_INT(
"edge profile not made", __func__, 1);
337 if ((n = numaGetCount(na)) < 2) {
345 numaGetIValue(na, 0, &val);
346 for (i = 1; i < n; i++) {
347 numaGetIValue(na, i, &nval);
348 diff = L_ABS(nval - val);
349 if (diff >= minjump) {
356 *pjpl = (l_float32)njumps / (l_float32)(n - 1);
358 *pjspl = (l_float32)jumpsum / (l_float32)(n - 1);
362 nae = numaFindExtrema(na, minreversal, NULL);
363 nreversal = numaGetCount(nae) - 1;
364 *prpl = (l_float32)nreversal / (l_float32)(n - 1);
385 const char *debugfile)
387l_int32 x, y, w, h, loc, index, ival;
393 if (!pixs || pixGetDepth(pixs) != 1)
394 return (
NUMA *)ERROR_PTR(
"pixs undefined or not 1 bpp", __func__, NULL);
397 return (
NUMA *)ERROR_PTR(
"invalid side", __func__, NULL);
399 pixGetDimensions(pixs, &w, &h, NULL);
405 pixGetLastOffPixelInRun(pixs, 0, 0,
L_FROM_LEFT, &loc);
406 loc = (loc == w - 1) ? 0 : loc + 1;
407 numaAddNumber(na, loc);
408 for (y = 1; y < h; y++) {
409 pixGetPixel(pixs, loc, y, &val);
411 pixGetLastOnPixelInRun(pixs, loc, y,
L_FROM_RIGHT, &loc);
413 pixGetLastOffPixelInRun(pixs, loc, y,
L_FROM_LEFT, &loc);
414 loc = (loc == w - 1) ? 0 : loc + 1;
416 numaAddNumber(na, loc);
420 pixGetLastOffPixelInRun(pixs, w - 1, 0,
L_FROM_RIGHT, &loc);
421 loc = (loc == 0) ? w - 1 : loc - 1;
422 numaAddNumber(na, loc);
423 for (y = 1; y < h; y++) {
424 pixGetPixel(pixs, loc, y, &val);
426 pixGetLastOnPixelInRun(pixs, loc, y,
L_FROM_LEFT, &loc);
428 pixGetLastOffPixelInRun(pixs, loc, y,
L_FROM_RIGHT, &loc);
429 loc = (loc == 0) ? w - 1 : loc - 1;
431 numaAddNumber(na, loc);
435 pixGetLastOffPixelInRun(pixs, 0, 0,
L_FROM_TOP, &loc);
436 loc = (loc == h - 1) ? 0 : loc + 1;
437 numaAddNumber(na, loc);
438 for (x = 1; x < w; x++) {
439 pixGetPixel(pixs, x, loc, &val);
441 pixGetLastOnPixelInRun(pixs, x, loc,
L_FROM_BOT, &loc);
443 pixGetLastOffPixelInRun(pixs, x, loc,
L_FROM_TOP, &loc);
444 loc = (loc == h - 1) ? 0 : loc + 1;
446 numaAddNumber(na, loc);
450 pixGetLastOffPixelInRun(pixs, 0, h - 1,
L_FROM_BOT, &loc);
451 loc = (loc == 0) ? h - 1 : loc - 1;
452 numaAddNumber(na, loc);
453 for (x = 1; x < w; x++) {
454 pixGetPixel(pixs, x, loc, &val);
456 pixGetLastOnPixelInRun(pixs, x, loc,
L_FROM_TOP, &loc);
458 pixGetLastOffPixelInRun(pixs, x, loc,
L_FROM_BOT, &loc);
459 loc = (loc == 0) ? h - 1 : loc - 1;
461 numaAddNumber(na, loc);
466 pixt = pixConvertTo8(pixs, TRUE);
467 cmap = pixGetColormap(pixt);
468 pixcmapAddColor(cmap, 255, 0, 0);
469 index = pixcmapGetCount(cmap) - 1;
471 for (y = 0; y < h; y++) {
472 numaGetIValue(na, y, &ival);
473 pixSetPixel(pixt, ival, y, index);
476 for (x = 0; x < w; x++) {
477 numaGetIValue(na, x, &ival);
478 pixSetPixel(pixt, x, ival, index);
481 pixWrite(debugfile, pixt, IFF_PNG);
l_ok pixMeasureEdgeSmoothness(PIX *pixs, l_int32 side, l_int32 minjump, l_int32 minreversal, l_float32 *pjpl, l_float32 *pjspl, l_float32 *prpl, const char *debugfile)
pixMeasureEdgeSmoothness()