2020-03-11 01:58:06 +00:00
# include "ImageApplyAutoCrop.h"
# include "ImageProcess_Public.h"
CImageApplyAutoCrop : : CImageApplyAutoCrop ( )
: m_isCrop ( false )
, m_isDesaskew ( false )
, m_isFillBlank ( false )
, m_isConvexHull ( true )
, m_threshold ( 40 )
, m_noise ( 2 )
, m_indent ( 5 )
{
}
CImageApplyAutoCrop : : CImageApplyAutoCrop ( bool isCrop , bool isDesaskew , bool isFillBlank , const cv : : Size & fixedSize , bool isConvex , double threshold , int noise , int indent )
: m_isCrop ( isCrop )
, m_isDesaskew ( isDesaskew )
, m_isFillBlank ( isFillBlank )
, m_isConvexHull ( isConvex )
, m_threshold ( threshold )
, m_noise ( noise )
, m_indent ( indent )
, m_fixedSize ( fixedSize )
{
}
CImageApplyAutoCrop : : ~ CImageApplyAutoCrop ( )
{
}
void CImageApplyAutoCrop : : apply ( cv : : Mat & pDib , int side )
{
2020-12-09 08:02:51 +00:00
( void ) side ;
if ( pDib . empty ( ) ) return ;
if ( ! m_isCrop & & ! m_isDesaskew & & ! m_isFillBlank & & m_fixedSize . empty ( ) ) return ;
2020-03-11 01:58:06 +00:00
cv : : Mat src = pDib ;
2020-12-09 08:02:51 +00:00
cv : : Mat thre ;
2020-03-11 01:58:06 +00:00
cv : : Mat dst ;
2020-12-09 08:02:51 +00:00
hg : : threshold_Mat ( src , thre , m_threshold ) ;
if ( m_noise > 0 )
2020-03-11 01:58:06 +00:00
{
2020-12-09 08:02:51 +00:00
cv : : Mat element = getStructuringElement ( cv : : MORPH_RECT , cv : : Size ( m_noise , m_noise ) ) ;
2020-03-11 01:58:06 +00:00
cv : : morphologyEx ( thre , thre , cv : : MORPH_OPEN , element ) ;
}
std : : vector < cv : : Vec4i > hierarchy ;
std : : vector < std : : vector < cv : : Point > > contours ;
hg : : findContours ( thre , contours , hierarchy , cv : : RETR_EXTERNAL ) ;
2020-12-09 08:02:51 +00:00
m_maxContour = hg : : getMaxContour ( contours , hierarchy ) ;
2020-03-11 01:58:06 +00:00
2020-12-09 08:02:51 +00:00
if ( m_maxContour . size ( ) = = 0 )
2020-03-11 01:58:06 +00:00
{
thre . release ( ) ;
# ifdef LOG
FileTools : : write_log ( " imgprc.txt " , " exit CImageApplyAutoCrop apply " ) ;
# endif // LOG
return ;
}
thre . release ( ) ;
dst . release ( ) ;
2020-12-09 08:02:51 +00:00
cv : : RotatedRect rect = hg : : getBoundingRect ( m_maxContour ) ;
cv : : Rect boudingRect = cv : : boundingRect ( m_maxContour ) ;
boudingRect . x - = 1 ;
boudingRect . y - = 1 ;
boudingRect . width + = 2 ;
boudingRect . height + = 2 ;
2020-03-11 01:58:06 +00:00
2020-12-09 08:02:51 +00:00
if ( m_isDesaskew & & rect . angle ! = 0 )
2020-03-11 01:58:06 +00:00
{
cv : : Point2f srcTri [ 4 ] ;
cv : : Point2f dstTri [ 3 ] ;
rect . points ( srcTri ) ;
dstTri [ 0 ] = cv : : Point2f ( 0 , rect . size . height - 1 ) ;
dstTri [ 1 ] = cv : : Point2f ( 0 , 0 ) ;
dstTri [ 2 ] = cv : : Point2f ( rect . size . width - 1 , 0 ) ;
cv : : Mat warp_mat ;
warp_mat = cv : : getAffineTransform ( srcTri , dstTri ) ;
cv : : warpAffine ( src , dst , warp_mat , rect . size ) ;
}
else
2020-12-09 08:02:51 +00:00
dst = src ( boudingRect & cv : : Rect ( 0 , 0 , src . cols , src . rows ) ) ;
m_maxContour . clear ( ) ;
m_maxContour . push_back ( cv : : Point ( - 1 , dst . rows ) ) ;
m_maxContour . push_back ( cv : : Point ( - 1 , - 1 ) ) ;
m_maxContour . push_back ( cv : : Point ( dst . cols , - 1 ) ) ;
m_maxContour . push_back ( cv : : Point ( dst . cols , dst . rows ) ) ;
2020-03-11 01:58:06 +00:00
if ( m_isFillBlank )
{
cv : : Mat thre_dst ;
hg : : threshold_Mat ( dst , thre_dst , m_threshold ) ;
2020-12-09 08:02:51 +00:00
if ( m_indent > 0 )
{
std : : vector < cv : : Point > rectEdge { cv : : Point ( 0 , 0 ) , cv : : Point ( thre_dst . cols - 1 , 0 ) ,
cv : : Point ( thre_dst . cols - 1 , thre_dst . rows - 1 ) , cv : : Point ( 0 , thre_dst . rows - 1 ) } ;
std : : vector < std : : vector < cv : : Point > > rectEdges { rectEdge } ;
cv : : drawContours ( thre_dst , rectEdges , 0 , cv : : Scalar : : all ( 0 ) ) ;
cv : : Mat element = cv : : getStructuringElement ( cv : : MorphShapes : : MORPH_RECT , cv : : Size ( m_indent * 2 , m_indent * 2 ) ) ;
cv : : erode ( thre_dst , thre_dst , element , cv : : Point ( - 1 , - 1 ) , 1 ) ;
}
2020-03-11 01:58:06 +00:00
hierarchy . clear ( ) ;
contours . clear ( ) ;
2020-12-09 08:02:51 +00:00
m_maxContour . clear ( ) ;
2020-05-16 01:59:44 +00:00
2020-12-09 08:02:51 +00:00
hg : : findContours ( thre_dst , contours , hierarchy , cv : : RETR_EXTERNAL ) ;
2020-03-11 01:58:06 +00:00
if ( m_isConvexHull )
2020-12-09 08:02:51 +00:00
{
m_maxContour = hg : : getMaxContour ( contours , hierarchy ) ;
hg : : convexHull ( m_maxContour , m_maxContour ) ;
contours . clear ( ) ;
contours . push_back ( m_maxContour ) ;
}
2020-03-11 01:58:06 +00:00
2020-12-09 08:02:51 +00:00
contours . push_back ( std : : vector < cv : : Point > ( ) ) ;
contours [ contours . size ( ) - 1 ] . push_back ( cv : : Point ( - 1 , dst . rows - 1 ) ) ;
contours [ contours . size ( ) - 1 ] . push_back ( cv : : Point ( - 1 , - 1 ) ) ;
contours [ contours . size ( ) - 1 ] . push_back ( cv : : Point ( dst . cols , - 1 ) ) ;
contours [ contours . size ( ) - 1 ] . push_back ( cv : : Point ( dst . cols , dst . rows ) ) ;
2020-03-11 01:58:06 +00:00
hg : : fillPolys ( dst , contours , cv : : Scalar ( 255 , 255 , 255 ) ) ;
}
pDib . release ( ) ;
2020-12-09 08:02:51 +00:00
if ( /*(m_isCrop && side == 0) || (side == 1 && m_fixedSize.width * m_fixedSize.height == 0)*/ m_isCrop )
2020-03-11 01:58:06 +00:00
pDib = dst . clone ( ) ;
else
{
2020-12-09 08:02:51 +00:00
#if 0
2020-03-11 01:58:06 +00:00
if ( m_isCrop & & side = = 1 & & ! m_fixedSize . empty ( ) )
if ( std : : abs ( m_fixedSize . width - dst . cols ) > 50 | | std : : abs ( m_fixedSize . height - dst . rows ) > 50 )
{
2020-12-09 08:02:51 +00:00
pDib = dst . clone ( ) ;
2020-03-11 01:58:06 +00:00
# ifdef LOG
FileTools : : write_log ( " imgprc.txt " , " exit CImageApplyAutoCrop apply " ) ;
# endif // LOG
return ;
}
2020-12-09 08:02:51 +00:00
# endif
2020-03-11 01:58:06 +00:00
pDib = cv : : Mat ( m_fixedSize , dst . type ( ) , m_isFillBlank ? cv : : Scalar ( 255 , 255 , 255 ) : cv : : Scalar ( 0 , 0 , 0 ) ) ;
cv : : Rect roi ;
roi . x = dst . cols > pDib . cols ? ( dst . cols - pDib . cols ) / 2 : 0 ;
roi . width = cv : : min ( pDib . cols , dst . cols ) ;
roi . y = dst . rows > pDib . rows ? ( dst . rows - pDib . rows ) / 2 : 0 ;
roi . height = cv : : min ( pDib . rows , dst . rows ) ;
cv : : Rect rect ( ( pDib . cols - roi . width ) / 2 , ( pDib . rows - roi . height ) / 2 , roi . width , roi . height ) ;
2020-12-09 08:02:51 +00:00
for ( cv : : Point & p : m_maxContour )
p + = roi . tl ( ) ;
2020-03-11 01:58:06 +00:00
#if 0
2020-12-09 08:02:51 +00:00
std : : string outrectinfo = " copy to rect x: " + std : : to_string ( rect . x ) + " y: " + std : : to_string ( rect . y ) + " width: " + std : : to_string ( rect . width ) + " height: " + std : : to_string ( rect . height ) ;
2020-03-11 01:58:06 +00:00
std : : string outroiinfo = " roi x: " + std : : to_string ( roi . x ) + " y: " + std : : to_string ( roi . y ) + " width: " + std : : to_string ( roi . width ) + " height: " + std : : to_string ( roi . height ) ;
std : : string dstsize = " dst size: width: " + std : : to_string ( dst . cols ) + " height: " + std : : to_string ( dst . rows ) ;
2020-12-09 08:02:51 +00:00
std : : string pDibszie = " pDib size: width: " + std : : to_string ( pDib . cols ) + " height: " + std : : to_string ( pDib . rows ) ;
2020-03-11 01:58:06 +00:00
FileTools : : write_log ( " imgprc.txt " , dstsize ) ;
FileTools : : write_log ( " imgprc.txt " , pDibszie ) ;
FileTools : : write_log ( " imgprc.txt " , outrectinfo ) ;
FileTools : : write_log ( " imgprc.txt " , outroiinfo ) ;
# endif // LOG
dst ( roi ) . copyTo ( pDib ( rect ) ) ;
2020-11-16 10:05:04 +00:00
2020-03-11 01:58:06 +00:00
}
# ifdef LOG
FileTools : : write_log ( " imgprc.txt " , " exit CImageApplyAutoCrop apply8 " ) ;
# endif // LOG
}
void CImageApplyAutoCrop : : apply ( std : : vector < cv : : Mat > & mats , bool isTwoSide )
{
if ( mats . empty ( ) ) return ;
2020-03-17 13:06:21 +00:00
if ( ! mats [ 0 ] . empty ( ) ) {
apply ( mats [ 0 ] , 0 ) ;
}
2020-03-11 01:58:06 +00:00
if ( isTwoSide & & mats . size ( ) > 1 )
{
cv : : Size dSize = m_fixedSize ;
if ( ! mats [ 0 ] . empty ( ) )
m_fixedSize = mats [ 0 ] . size ( ) ;
2020-04-18 03:18:06 +00:00
if ( ! mats [ 1 ] . empty ( ) ) {
2020-03-17 13:06:21 +00:00
apply ( mats [ 1 ] , 1 ) ;
2020-04-18 03:18:06 +00:00
}
2020-03-11 01:58:06 +00:00
if ( ! mats [ 0 ] . empty ( ) )
m_fixedSize = dSize ;
}
2020-12-09 08:02:51 +00:00
}