Page 1 of 1
Cropping multiple receipts on one scanned image
Posted: 2019-09-04T08:14:24-07:00
by dmcgrathtbi
Hi, I am trying to find a way to crop out multiple receipts on one scanned image automatically. The receipts can be in any orientation and are generally on a white background. See image.
https://drive.google.com/file/d/11G-Fk_ ... sp=sharing
I can achieve this on a dark background by increasing the contrast and the using Freds multicrop script to crop all the receipts out.
I am using ImageMagick 6.9.9-40 on a mac
Any help would be appreciated!!
Re: Cropping multiple receipts on one scanned image
Posted: 2019-09-04T09:28:46-07:00
by fmw42
Why is your image blurry?
This works fine for me.
Code: Select all
convert Receipts_blurred.png -crop 50x100% -fuzz 15% -trim +repage results.png
Re: Cropping multiple receipts on one scanned image
Posted: 2019-09-05T06:59:27-07:00
by dmcgrathtbi
Hi, thanks for the response.
There could be upwards of 10 receipts on the one page scanned in all different orientations so unfortunately setting the crop size won't work. Need to find a way to pick up where the receipts are on the page and crop around them accordingly.
As mentioned can do this with a dark background but having trouble with low contrast.
Re: Cropping multiple receipts on one scanned image
Posted: 2019-09-05T09:06:42-07:00
by fmw42
I tried to blur your receipt and increase contrast and threshold, but could not get a good separation into two parts. Low contrast is very hard for separating text. I have no good solution at this time.
Re: Cropping multiple receipts on one scanned image
Posted: 2019-09-05T09:13:53-07:00
by dmcgrathtbi
Thanks for trying. Yeah it is a tough one
Re: Cropping multiple receipts on one scanned image
Posted: 2019-09-05T10:06:22-07:00
by snibgo
We can stretch the contrast to make black and white. Then spread the blackness a bit. Windows syntax:
Code: Select all
magick Receipts_blurred.png -contrast-stretch 5%x90% ( +clone ) -geometry +20+20 -compose Darken -composite receipts_out.png
This may be sufficient for Fred's script to work. If not, spread the blackness more.
Re: Cropping multiple receipts on one scanned image
Posted: 2019-09-06T03:21:03-07:00
by dmcgrathtbi
Nice suggestion. I am getting loads of interference and cropping multiple parts of the images. How do you undo the effect you put on the image?
Re: Cropping multiple receipts on one scanned image
Posted: 2019-09-06T04:38:43-07:00
by snibgo
I have shown how the image can be processed to find the location of each receipt. You would then crop the original image at those locations.
Re: Cropping multiple receipts on one scanned image
Posted: 2019-09-06T04:53:45-07:00
by dmcgrathtbi
Ah thanks ok, I get the idea now. I am new to Imagemagick so not sure on how to do that exactly. Is there a specific command for that?
Re: Cropping multiple receipts on one scanned image
Posted: 2019-09-06T06:15:34-07:00
by snibgo
dmcgrathtbi wrote:Is there a specific command for that?
No. It can be built into a script. This is a fairly common requirement: get information from one image to decide how to process another image.
For example, Windows BAT syntax:
Code: Select all
%IMG7%magick ^
Receipts_blurred.png ^
-contrast-stretch 5%%x50%% ^
-threshold 90%% ^
( -clone 0 ) -geometry +20+20 -compose Darken -composite ^
( -clone 0 ) -geometry -20-20 -compose Darken -composite ^
( +clone ) -geometry +20-10 -compose Darken -composite ^
receipts_smear.png
The smearing is big enough to join the characters on each receipt, but small enough that the receipts are not joined together.
Other methods can be used to smear, eg morphology.
Then a script uses connected-components to find the receipts. I use a threshold of 1% of the image size in pixels. Components smaller than this are not considered to be separate receipts.
Code: Select all
call %PICTBAT%rectSubimages ^
receipts_smear.png receipt_out.png . . 1c Receipts_blurred.png
The output images are:
The script rectSubimages.bat is:
Code: Select all
rem Given image %1 is a number of rectangular subimages on solid-colour background,
rem crops to each one.
@rem %2 is output files
@rem %3 is background colour [default White].
@rem %4 is fuzz factor.
@rem %5 is threshold for minumum size of subimages (area, in pixels).
@rem %5 may have suffix 'c' or '%' for percentage or 'p' for proportion of image w*h.
@rem Default 0.
@rem %6 Image to be cropped. Default: %1.
@rem
@rem Any pair of subimages may overlap in x or y directions.
@rem
@rem First written: 11-June-2016
@rem Updated:
@rem 29-October-2016 added optional suffix for %5.
@rem 6-September-2019 added optional %6
@if "%1"=="" findstr /B "rem @rem" %~f0 & exit /B 1
@setlocal enabledelayedexpansion
@call echoOffSave
call %PICTBAT%setInOut %1 rsi
if not "%2"=="" if not "%2"=="." set OUTFILE=%2
set BACK_COL=%3
if "%BACK_COL%"=="." set BACK_COL=
if "%BACK_COL%"=="" set BACK_COL=White
set FUZZ=%4
if "%FUZZ%"=="." set FUZZ=
if "%FUZZ%"=="" set FUZZ=0
set THRESH=%5
if "%THRESH%"=="." set THRESH=
if "%THRESH%"=="" set THRESH=0
set TOCROP=%6
if "%TOCROP%"=="." set TOCROP=
if "%TOCROP%"=="" set TOCROP=%INFILE%
if %FUZZ%==0 (
set sFUZZ=
) else (
set sFUZZ=-fuzz %FUZZ%%%
)
set TH_LAST=%THRESH:~-1%
if "%TH_LAST%"=="^%" set TH_LAST=c
if /I "%TH_LAST%"=="c" (
for /F "usebackq" %%L in (`%IM%identify ^
-precision 16 ^
-format "nTHRESH=%%[fx:int(w*h*%THRESH:~0,-1%/100)]" ^
%INFILE%`) do set %%L
) else if /I "%TH_LAST%"=="p" (
for /F "usebackq" %%L in (`%IM%identify ^
-format "nTHRESH=%%[fx:int(w*h*%THRESH:~0,-1%)]" ^
%INFILE%`) do set %%L
) else (
set nTHRESH=%THRESH%
)
echo %0: nTHRESH=%nTHRESH%
if %nTHRESH%==0 (
set sTHRESH=
) else (
set "sTHRESH=-define connected-components:area-threshold^=%nTHRESH%"
)
echo %0: sTHRESH=%sTHRESH%
set IMG_NUM=0
for /F "usebackq skip=1 tokens=2,5" %%A in (`%IM%convert ^
%INFILE% ^
-strip ^
%sFUZZ% ^
-transparent %BACK_COL% ^
-channel RGB -evaluate set 100%% +channel ^
-background Black -layers Flatten ^
+depth ^
-fuzz 0 ^
-define connected-components:verbose^=true ^
%sTHRESH% ^
-connected-components 4 ^
NULL:`) do (
for /F "usebackq" %%L in (`%IM%convert ^
xc:%%B -format "IS_BLACK=%%[fx:mean>0.5?1:0]\n" ^
info:`) do set %%L
rem echo !IMG_NUM!, %%A, %%B, IS_BLACK=!IS_BLACK!
if !IS_BLACK!==1 (
set sCROP_!IMG_NUM!=%%A
set sCOL_!IMG_NUM!=%%B
set /A IMG_NUM+=1
)
)
echo %0: IMG_NUM=%IMG_NUM%
set /A LAST_IMG=%IMG_NUM%-1
set sCROPS=
for /L %%I in (0,1,%LAST_IMG%) do (
set N=%%I
echo %%I, !sCROP_%%I!, !sCOL_%%I!
set sCROPS=!sCROPS! ^( -clone 0 -crop !sCROP_%%I! ^)
)
echo %0: sCROPS=%sCROPS%
%IM%convert ^
%TOCROP% ^
%sCROPS% ^
-delete 0 ^
%sFUZZ% -trim +repage ^
%OUTFILE%
call echoRestore
@endlocal & set rsiOUTFILE=%OUTFILE%& set rsiNUM=%IMG_NUM%& set rsiCROPS=%sCROPS%
Re: Cropping multiple receipts on one scanned image
Posted: 2019-09-06T09:32:43-07:00
by snibgo
Above, I smeared the black by compositing clones, each with an offset.
Morphology may be more intuitive and faster. For example, we spread horizontally by 31 pixels (15 pixels left, and 15 right), and 51 pixels vertically (25 in each direction). "Erode" means the white pixels are eroded, reduced.
Code: Select all
%IMG7%magick ^
Receipts_blurred.png ^
-contrast-stretch 5%%x50%% ^
-threshold 90%% ^
-morphology Erode Rectangle:31x1;Rectangle:1x51 ^
receipts_smear2.png
Re: Cropping multiple receipts on one scanned image
Posted: 2019-09-06T11:27:05-07:00
by fmw42
One can also use connected components processing to remove small regions that may not be part of the text on the receipt. See
https://imagemagick.org/script/connected-components.php