src/flipdetect.c
l_int32
pixOrientDetect(PIX        *pixs,
                l_float32  *pupconf,
                l_float32  *pleftconf,
                l_int32     mincount,
                l_int32     debug)
{
PIX  *pixt;

    PROCNAME("pixOrientDetect");

    if (!pixs)
        return ERROR_INT("pixs not defined", procName, 1);
    if (pixGetDepth(pixs) != 1)
        return ERROR_INT("pixs not 1 bpp", procName, 1);
    if (!pupconf && !pleftconf)
        return ERROR_INT("nothing to do", procName, 1);
    if (mincount == 0)
        mincount = DEFAULT_MIN_UP_DOWN_COUNT;

    if (pupconf)
        pixUpDownDetect(pixs, pupconf, mincount, debug);
    if (pleftconf) {
        pixt = pixRotate90(pixs, 1);
        pixUpDownDetect(pixt, pleftconf, mincount, debug);
        pixDestroy(&pixt);
    }

    return 0;
}
/*!
 *  pixOrientDetect()
 *
 *      Input:  pixs (1 bpp, deskewed, English text, 150 - 300 ppi)
 *              &upconf (<optional return> ; may be null)
 *              &leftconf (<optional return> ; may be null)
 *              mincount (min number of up + down; use 0 for default)
 *              debug (1 for debug output; 0 otherwise)
 *      Return: 0 if OK, 1 on error
 *
 *  Notes:
 *      (1) See "Measuring document image skew and orientation"
 *          Dan S. Bloomberg, Gary E. Kopec and Lakshmi Dasari
 *          IS&T/SPIE EI'95, Conference 2422: Document Recognition II
 *          pp 302-316, Feb 6-7, 1995, San Jose, CA
 *      (2) upconf is the normalized difference between up ascenders
 *          and down ascenders.  The image is analyzed without rotation
 *          for being rightside-up or upside-down.  Set &upconf to null
 *          to skip this operation.
 *      (3) leftconf is the normalized difference between up ascenders
 *          and down ascenders in the image after it has been
 *          rotated 90 degrees clockwise.  With that rotation, ascenders
 *          projecting to the left in the source image will project up
 *          in the rotated image.  We compute this by rotating 90 degrees
 *          clockwise and testing for up and down ascenders.  Set
 *          &leftconf to null to skip this operation.
 *      (4) Note that upconf and leftconf are not linear measures of
 *          confidence, e.g., in a range between 0 and 100.  They
 *          measure how far you are out on the tail of a (presumably)
 *          normal distribution.  For example, a confidence of 10 means
 *          that it is nearly certain that the difference did not
 *          happen at random.  However, these values must be interpreted
 *          cautiously, taking into consideration the estimated prior
 *          for a particular orientation or mirror flip.   The up-down
 *          signal is very strong if applied to text with ascenders
 *          up and down, and relatively weak for text at 90 degrees,
 *          but even at 90 degrees, the difference can look significant.
 *          For example, suppose the ascenders are oriented horizontally,
 *          but the test is done vertically.  Then upconf can
 *          be < -MIN_CONF_FOR_UP_DOWN, suggesting the text may be
 *          upside-down.  However, if instead the test were done
 *          horizontally, leftconf will be very much larger
 *          (in absolute value), giving the correct orientation.
 *      (5) If you compute both upconf and leftconf, and there is
 *          sufficient signal, the following table determines the
 *          cw angle necessary to rotate pixs so that the text is 
 *          rightside-up:
 *             0 deg :           upconf >> 1,    abs(upconf) >> abs(leftconf)
 *             90 deg :          leftconf >> 1,  abs(leftconf) >> abs(upconf)
 *             180 deg :         upconf << -1,   abs(upconf) >> abs(leftconf)
 *             270 deg :         leftconf << -1, abs(leftconf) >> abs(upconf)
 *      (6) One should probably not interpret the direction unless
 *          there are a sufficient number of counts for both orientations,
 *          in which case neither upconf nor leftconf will be 0.0.
 *      (7) Uses rasterop implementation of HMT.
 */
pixOrientDetect()
Input:  pixs (1 bpp, deskewed, English text, 150 - 300 ppi)
&upconf ( ; may be null)
&leftconf ( ; may be null)
mincount (min number of up + down; use 0 for default)
debug (1 for debug output; 0 otherwise)
Return: 0 if OK, 1 on error

(1) See "Measuring document image skew and orientation"
Dan S. Bloomberg, Gary E. Kopec and Lakshmi Dasari
IS&T/SPIE EI'95, Conference 2422: Document Recognition II
pp 302-316, Feb 6-7, 1995, San Jose, CA
(2) upconf is the normalized difference between up ascenders
and down ascenders.  The image is analyzed without rotation
for being rightside-up or upside-down.  Set &upconf to null
to skip this operation.
(3) leftconf is the normalized difference between up ascenders
and down ascenders in the image after it has been
rotated 90 degrees clockwise.  With that rotation, ascenders
projecting to the left in the source image will project up
in the rotated image.  We compute this by rotating 90 degrees
clockwise and testing for up and down ascenders.  Set
&leftconf to null to skip this operation.
(4) Note that upconf and leftconf are not linear measures of
confidence, e.g., in a range between 0 and 100.  They
measure how far you are out on the tail of a (presumably)
normal distribution.  For example, a confidence of 10 means
that it is nearly certain that the difference did not
happen at random.  However, these values must be interpreted
cautiously, taking into consideration the estimated prior
for a particular orientation or mirror flip.   The up-down
signal is very strong if applied to text with ascenders
up and down, and relatively weak for text at 90 degrees,
but even at 90 degrees, the difference can look significant.
For example, suppose the ascenders are oriented horizontally,
but the test is done vertically.  Then upconf can
be < -MIN_CONF_FOR_UP_DOWN, suggesting the text may be
upside-down.  However, if instead the test were done
horizontally, leftconf will be very much larger
(in absolute value), giving the correct orientation.
pixOrientDetect () Input : pixs ( 1 bpp deskewed English text 150 - 300 ppi ) &upconf ( ; may be null ) &leftconf ( ; may be null ) mincount ( min number of up + down ; use 0 for default ) debug ( 1 for debug output ; 0 otherwise ) Return : 0 if OK 1 on error ( 1 ) See " Measuring document image skew and orientation " Dan S . Bloomberg Gary E . Kopec and Lakshmi Dasari IS&T / SPIE EI ' 95 Conference 2422 : Document Recognition II pp 302 - 316 Feb 6 - 7 1995 San Jose CA ( 2 ) upconf is the normalized difference between up ascenders and down ascenders . The image is analyzed without rotation for being rightside - up or upside - down . Set &upconf to null to skip this operation . ( 3 ) leftconf is the normalized difference between up ascenders and down ascenders in the image after it has been rotated 90 degrees clockwise . With that rotation ascenders projecting to the left in the source image will project up in the rotated image . We compute this by rotating 90 degrees clockwise and testing for up and down ascenders . Set &leftconf to null to skip this operation . ( 4 ) Note that upconf and leftconf are not linear measures of confidence e . g . in a range between 0 and 100 . They measure how far you are out on the tail of a ( presumably ) normal distribution . For example a confidence of 10 means that it is nearly certain that the difference did not happen at random . However these values must be interpreted cautiously taking into consideration the estimated prior for a particular orientation or mirror flip . The up - down signal is very strong if applied to text with ascenders up and down and relatively weak for text at 90 degrees but even at 90 degrees the difference can look significant . For example suppose the ascenders are oriented horizontally but the test is done vertically . Then upconf can be < - MIN_CONF_FOR_UP_DOWN suggesting the text may be upside - down . However if instead the test were done horizontally leftconf will be very much larger ( in absolute value ) giving the correct orientation .
l_int32
pixOrientDetect(PIX        *pixs,
                l_float32  *pupconf,
                l_float32  *pleftconf,
                l_int32     mincount,
                l_int32     debug)
{
PIX  *pixt;
    PROCNAME("pixOrientDetect");
    if (!pixs)
        return ERROR_INT("pixs not defined", procName, 1);
    if (pixGetDepth(pixs) != 1)
        return ERROR_INT("pixs not 1 bpp", procName, 1);
    if (!pupconf && !pleftconf)
        return ERROR_INT("nothing to do", procName, 1);
    if (mincount == 0)
        mincount = DEFAULT_MIN_UP_DOWN_COUNT;
    if (pupconf)
        pixUpDownDetect(pixs, pupconf, mincount, debug);
    if (pleftconf) {
        pixt = pixRotate90(pixs, 1);
        pixUpDownDetect(pixt, pleftconf, mincount, debug);
        pixDestroy(&pixt);
    }
    return 0;
}
l_int32 pixOrientDetect ( PIX * pixs , l_float32 * pupconf , l_float32 * pleftconf , l_int32 mincount , l_int32 debug ) { PIX * pixt ; PROCNAME ( " " ) ; if ( ! pixs ) return ERROR_INT ( " " , procName , 1 ) ; if ( pixGetDepth ( pixs ) != 1 ) return ERROR_INT ( " " , procName , 1 ) ; if ( ! pupconf && ! pleftconf ) return ERROR_INT ( " " , procName , 1 ) ; if ( mincount == 0 ) mincount = DEFAULT_MIN_UP_DOWN_COUNT ; if ( pupconf ) pixUpDownDetect ( pixs , pupconf , mincount , debug ) ; if ( pleftconf ) { pixt = pixRotate90 ( pixs , 1 ) ; pixUpDownDetect ( pixt , pleftconf , mincount , debug ) ; pixDestroy ( & pixt ) ; } return 0 ; }
pixOrientDetect()
      Input:  pixs (1 bpp, deskewed, English text, 150 - 300 ppi)
              &upconf (<optional return> ; may be null)
              &leftconf (<optional return> ; may be null)
              mincount (min number of up + down; use 0 for default)
              debug (1 for debug output; 0 otherwise)
      Return: 0 if OK, 1 on error
pixOrientDetect () Input : pixs ( 1 bpp deskewed English text 150 - 300 ppi ) &upconf ( <optional return > ; may be null ) &leftconf ( <optional return > ; may be null ) mincount ( min number of up + down ; use 0 for default ) debug ( 1 for debug output ; 0 otherwise ) Return : 0 if OK 1 on error