If we are searching for small crops from one image within another image, we want to ensure the crop has detail.
There is no point in searching for a patch of blue in an image of blue sky. The more detail a patch has, the more likely it is to be unique within the other image. (This may not be true for artificial images, but I reckon it's true of ordinary photographs.)
There are two approaches to this problem. One is to rank all of the pixels by some measure, such as the standard deviation of surrounding pixels, and then to find the highest-ranking pixel, the second highest, and so on. The algorithm ensures that chosen pixels are not too close together. That method is explored in Details, details. It is quite slow.
Another approach works in the opposite direction. It starts with a number of regularly-spaces pixels, and calculates are measure for each of these. For those patches with a poor measure (low entropy), we won't bother searching in the other image. This is much faster, as we calculate the measure for a much smaller number of pixels. However, many of the pixels will turn out to be unsuitable. That approach is described in this page.
Set up initial conditions:
set MD_SRC=\pictures\20140523\AGA_1837_g.tiff set WEB_SIZE=-resize 500x500
The source photograph for this page has had fairly heavy processing from the raw camera image. This is a challenging image, as there are large areas of no detail (in the sky) and repeated areas of similar detail (the roof tiles, painted brickwork and blinds in the windows).
Put it another way: in this image, the chances of a small crop have high entropy is very low.
On this page, all operations are performed on the full-size image, roughly 7500x5000 pixels. Results are resized for display on the web.
The source image. rem goto skip %IM%convert ^ %MD_SRC% ^ %WEB_SIZE% ^ md_src_sm.jpg |
for /F "usebackq" %%L in (`%IM%identify -format "WW=%%w\nHH=%%h" %MD_SRC%`) do set %%L echo %WW% %HH%
7378 4924
Generate a list of coordinates.
call %PICTBAT%nGenCoord %WW% %HH% 6 4 >md_coords.lis
md_coords.lis contains:
1054,985 2108,985 3162,985 4216,985 5270,985 6324,985 1054,1970 2108,1970 3162,1970 4216,1970 5270,1970 6324,1970 1054,2954 2108,2954 3162,2954 4216,2954 5270,2954 6324,2954 1054,3939 2108,3939 3162,3939 4216,3939 5270,3939 6324,3939
Create 24 crops, each 100x100 pixels, centred on these coordinates:
set ncDEBUG=1 set ncDEBUG_STROKE=-stroke #f00 -fill None -strokewidth 15 set ncCROPDIR=. set ncEXT=.png call %PICTBAT%nCrop %MD_SRC% md_coords.lis 100 100 %IM%convert ^ %ncDEBUG_FILE% ^ %WEB_SIZE% ^ mc_crops.jpg
Here are the 24 crops, shown full size. For convenience, we number these web images.
for /L %%i in (0,1,23) do ( %IM%convert ^ AGA_1837_g_100_100_crop_%%i.png ^ -stroke None -fill Red -gravity SouthWest -pointsize 20 -annotate 0 "%%i" ^ md_crop_%%i.png )
Crops 4, 5, 12, 13 and 20 are featureless, so would have many false matches in another image.
Crops 15, 17 and 22 look useful.
As a better test of which crops are useful, we will search for them within another image that has undergone similar, but not identical, processing.
Seach for the crops within this image. set SRCH_IMG=\pictures\20140523\AGA_1839_g.tiff %IM%convert ^ %SRCH_IMG% ^ %WEB_SIZE% ^ md_srch_sm.jpg |
We search for the crops using the method given in Simple alignment.
set MATCH_LIS=md_match.lis del %MATCH_LIS% set MATCH_LIS2=md_match2.lis echo CropNum,Score,X,Y >%MATCH_LIS% set CROP_NUM=0 for /F %%F in (%ncLIST_FILE%) do ( echo %%F call %PICTBAT%srchImg %SRCH_IMG% %%F if ERRORLEVEL 1 exit /B 1 echo !CROP_NUM!, !siCOMP_FLT!, !siCENT_X!, !siCENT_Y! >>%MATCH_LIS% set /A CROP_NUM+=1 ) cSort /i%MATCH_LIS% /o%MATCH_LIS2% /h /kScore
CropNum,Score,X,Y 0, 0.0668794, 4419, 2398 1, 0.0127875, 3210, 1926 2, 0.0380188, 4726, 2204 3, 0.0593571, 3105, 420 4, 0.0022269, 6710, 237 5, 0.00497868, 6094, 999 6, 0.0814029, 4376, 2736 7, 0.047739, 2480, 2350 8, 0.11398, 4367, 2374 9, 0.056907, 6039, 4477 10, 0.0517877, 4748, 3212 11, 0.0842783, 6698, 2155 12, 0.0084113, 1187, 4393 13, 0.0217025, 1405, 3110 14, 0.0646012, 4047, 2401 15, 0.0726231, 4599, 3303 16, 0.0772284, 3453, 2313 17, 0.0843147, 4678, 2858 18, 0.0485805, 2517, 4379 19, 0.0422138, 2500, 4571 20, 0.0148356, 3553, 4390 21, 0.040483, 4447, 2597 22, 0.0855242, 5040, 2405 23, 0.0630489, 3449, 2334
These are the matches found, in order of the score, so the closest matches are at the top.
CropNum,Score,X,Y 4, 0.0022269, 6710, 237 5, 0.00497868, 6094, 999 12, 0.0084113, 1187, 4393 1, 0.0127875, 3210, 1926 20, 0.0148356, 3553, 4390 13, 0.0217025, 1405, 3110 2, 0.0380188, 4726, 2204 21, 0.040483, 4447, 2597 19, 0.0422138, 2500, 4571 7, 0.047739, 2480, 2350 18, 0.0485805, 2517, 4379 10, 0.0517877, 4748, 3212 9, 0.056907, 6039, 4477 3, 0.0593571, 3105, 420 23, 0.0630489, 3449, 2334 14, 0.0646012, 4047, 2401 0, 0.0668794, 4419, 2398 15, 0.0726231, 4599, 3303 16, 0.0772284, 3453, 2313 6, 0.0814029, 4376, 2736 11, 0.0842783, 6698, 2155 17, 0.0843147, 4678, 2858 22, 0.0855242, 5040, 2405 8, 0.11398, 4367, 2374
We can markup a copy of the searched image with the locations found.
:skip set mrCOL_X=3 set mrCOL_Y=4 call %PICTBAT%markRect %SRCH_IMG% md_match.lis 100 100 %IM%convert ^ %mrOUTFILE% ^ %WEB_SIZE% ^ md_srch_marked.jpg |
The closest matches are for crops 4 and 5, but these are at the wrong position in the sky.
Correct matches have been found for only crop numbers 7, 15, and 20. Crop 15 is a correct match but the score is not good because the curtain has moved between photos. Crop 11 is close, but one glass pane too high. 19 is also very close. 20 is also very close, less than 100 pixels out. False matches have been found for rest.
Aside: checking for correct matches isn't possible with these reduced images. I checked the full-size versions by making the two images into layers for Gimp.
%PICTBAT%toGimp %ncDEBUG_FILE% %mrOUTFILE%
del md_sd.lis for /L %%i in (0,1,23) do ( %IM%convert AGA_1837_g_100_100_crop_%%i.png -format "%%i, %%[fx:standard_deviation]\n" info: >>md_sd.lis ) cSort /imd_sd.lis /omd_sd.lis /k1 /r
15, 0.217446 22, 0.166763 11, 0.123797 17, 0.100795 7, 0.092101 16, 0.068679 14, 0.0641415 19, 0.0611273 18, 0.0604791 10, 0.0585896 9, 0.0583192 3, 0.0540542 20, 0.0520365 23, 0.0512842 6, 0.0495721 8, 0.047464 0, 0.0416223 2, 0.0368887 13, 0.036255 21, 0.0320853 1, 0.00956863 12, 0.00800066 5, 0.0070369 4, 0.00379715
The threshold could be somewhere between 0.06 and 0.10.
del md_lbd.lis for /L %%i in (0,1,23) do ( %IM%convert ^ AGA_1837_g_100_100_crop_%%i.png ^ ^( +clone -blur 0x4 ^) ^ -compose Difference -composite ^ -grayscale RMS ^ -format "%%i, %%[fx:mean]\n" info: >>md_lbd.lis ) cSort /imd_lbd.lis /omd_lbd.lis /k1 /r
11, 0.0402368 18, 0.0341297 22, 0.0284433 17, 0.0270779 3, 0.0249619 14, 0.0242513 23, 0.0241707 0, 0.0232178 15, 0.0221118 8, 0.021639 6, 0.0214891 16, 0.0207127 19, 0.0186017 9, 0.0165609 21, 0.0164521 7, 0.0157946 2, 0.0156873 10, 0.0141526 13, 0.00665879 20, 0.0057895 1, 0.00486209 12, 0.00432354 4, 0.000983201 5, 0.000929366
The threshold could be somewhere between 0.010 and 0.022.
del md_2bd.lis for /L %%i in (0,1,23) do ( %IM%convert ^ AGA_1837_g_100_100_crop_%%i.png ^ ^( -clone 0 -blur 0x4 ^) ^ ^( -clone 0 -blur 0x6 ^) ^ -delete 0 ^ -compose Difference -composite ^ -grayscale RMS ^ -format "%%i, %%[fx:mean]\n" info: >>md_2bd.lis ) cSort /imd_2bd.lis /omd_2bd.lis /k1 /r
11, 0.0131496 22, 0.0120719 17, 0.0108971 15, 0.0107203 18, 0.00831235 19, 0.00767631 14, 0.0073792 7, 0.00694394 16, 0.00651588 8, 0.00609133 9, 0.00608128 6, 0.00577632 23, 0.00565061 0, 0.00536901 3, 0.00445679 2, 0.00428925 10, 0.00427402 21, 0.00248127 13, 0.00186595 20, 0.0016006 12, 0.00107566 1, 0.000959411 5, 0.000167381 4, 0.000101817
The threshold could be somewhere between 0.010 and 0.022.
del md_dog.lis for /L %%i in (0,1,23) do ( %IM%convert ^ AGA_1837_g_100_100_crop_%%i.png ^ -morphology Convolve DoG:0,4.0,6.0 ^ -grayscale RMS ^ -format "%%i, %%[fx:mean]\n" info: >>md_dog.lis ) cSort /imd_dog.lis /omd_dog.lis /k1 /r
22, 0.0210045 11, 0.019456 17, 0.0178273 15, 0.0174037 18, 0.0153237 14, 0.0133908 19, 0.0129771 7, 0.0124542 16, 0.0116234 9, 0.01044 8, 0.0104363 23, 0.0104016 6, 0.0102716 0, 0.00911032 10, 0.00751994 2, 0.00738392 3, 0.00699886 21, 0.00446465 13, 0.00308597 20, 0.00272584 12, 0.00180523 1, 0.00167776 5, 0.000307883 4, 0.000188003
The threshold could be somewhere between 0.004 and 0.016.
For convenience, scripts are available in a single zip file. See Zipped BAT files.
@set STOP_WATCH_SUB= @if not "%STOP_WATCH_TIME%"=="" set STOP_WATCH_SUB=/S "%STOP_WATCH_TIME%" @cDate %STOP_WATCH_SUB% /f"\q \H:\M:\S" @for /F "usebackq tokens=*" %%L IN (`cDate /f"\d-\b-\Y \H:\M:\S"`) do @set STOP_WATCH_TIME=%%L @rem echo %STOP_WATCH_TIME% @if not "%1"=="" @echo %STOP_WATCH_TIME% %1 %2 %3 %4 %5 %6 %7 %8 %9>>stopwatch.lis
@rem Given: @rem %1 image width @rem %2 image height @rem %3 number of points horizontally >=1 @rem %4 number of points vertically >=1 @rem %5 optional deltaX @rem %6 optional deltaY @rem echoes list of coordinates to stdout. @if "%4"=="" findstr /B "rem @rem" %~f0 & exit /B 1 @setlocal enabledelayedexpansion @call echoOffSave set deltaX=%5 if "%deltaX%"=="" set deltaX=0 set deltaY=%6 if "%deltaY%"=="" set deltaY=0 for /L %%Y in (1,1,%4) do ( for /L %%X in (1,1,%3) do ( for /F "usebackq" %%L in (`%IM%identify ^ -format "px=%%[fx:int(%%X*%1/(%3+1)+%deltaX%+0.5)]\npy=%%[fx:int(%%Y*%2/(%4+1)+%deltaY%+0.5)]" ^ xc:`) do set %%L echo !px!,!py! ) ) @call echoRestore
rem From image %1, rem list of x,y coordinates in text file %2, rem creates crops width %3 height %4 in files *_crop_n.* rem Also creates text file _crops.lis. Name is returned as ncLIST_FILE. @rem @rem Also uses: @rem ncDEBUG if 1, creates a marked-up copy of image. @rem ncDEBUG_STROKE eg to get thick strokes @rem ncCROPDIR directory to place the crops, default %TEMP% @rem ncBASE default name is based on %1, %3 and %4, in directory ncCROPDIR @rem ncEXT @rem @rem Returns: @rem ncLIST_FILE name of created file with list of names of crop files @rem FIXME: we could also use (optional?) standard deviation of each crop. @rem Or some other measure, such as difference from a blur. @if "%4"=="" findstr /B "rem @rem" %~f0 & exit /B 1 @setlocal enabledelayedexpansion @call echoOffSave call %PICTBAT%setInOut %1 nl if "%ncEXT%"=="" set ncEXT=%EXT% if "%ncDEBUG%"=="1" set DEBUG_FILE=%BASENAME%_nc_dbg%ncEXT% if "%ncDEBUG_STROKE%"=="" set ncDEBUG_STROKE=-stroke #f00 -fill None if "%ncCROPDIR%"=="" set ncCROPDIR=%TEMP% if "%ncBASE%"=="" set ncBASE=%ncCROPDIR%\%~n1_%3_%4_crop if "%ncAtBASE%"=="" set ncAtBASE=%~n1_%3_%4_crop set CROP_FILE=%ncAtBASE%_crops.txt del %CROP_FILE% 2>nul set RECT_FILE=%ncBASE%_rects.txt del %RECT_FILE% 2>nul set LIST_FILE=%ncBASE%s.lis del %LIST_FILE% 2>nul set nCrop=0 rem set sCROP= set sRECT= set /A W_2=%3/2 set /A H_2=%4/2 for /F "tokens=1,2 delims=, " %%X in (%2) do ( set /A dx=%%X-%W_2% set /A dy=%%Y-%H_2% set IMG_FILE=%ncBASE%_!nCrop!%ncEXT% rem set sCrop=!sCrop! ^( +clone -crop %3x%4+!dx!+!dy! +repage -write !IMG_FILE! +delete ^) echo ^( +clone -crop %3x%4+!dx!+!dy! +repage -write !IMG_FILE! +delete ^) >> %CROP_FILE% echo !IMG_FILE!>>%LIST_FILE% set /A nCrop+=1 if "%ncDEBUG%"=="1" ( set /A endX=!dx!+%3-1 set /A endY=!dy!+%4-1 set sRECT=!sRECT! rectangle !dx!,!dy!,!endX!,!endY! echo rectangle !dx!,!dy!,!endX!,!endY! >>%RECT_FILE% rem FIXME: also annotate the rectangles ) ) %IM%convert ^ %INFILE% ^ @%CROP_FILE% ^ NULL: if ERRORLEVEL 1 exit /B 1 if "%ncDEBUG%"=="1" ( %IM%convert ^ %INFILE% ^ %ncDEBUG_STROKE% ^ -draw @%RECT_FILE% ^ %DEBUG_FILE% if ERRORLEVEL 1 exit /B 1 ) @call echoRestore @endlocal & set ncLIST_FILE=%LIST_FILE%& set ncDEBUG_FILE=%DEBUG_FILE%
rem Given image %1, creates marked-up version with numbered rectangles. rem Takes coordinates of rectangle centres from file %2. rem %3 width of rectangle, default 1 rem %4 height of rectangle, default 1 @rem @rem %2 is CSV file with columns X,Y{,N} @rem If third column is present, uses this for annotation. @rem Otherwise numbers seqentially. @rem @rem Also uses: @rem mrSTROKE eg to get thick strokes @rem mrPIX_HT height of font in pixels. If 0, no numbering. @rem mrCOL_X column number in %2 for x-coordinate, counting from 1 @rem mrCOL_Y column number in %2 for y-coordinate, counting from 1 @rem FIXME: Also option for circles? Ellipes? @if "%4"=="" findstr /B "rem @rem" %~f0 & exit /B 1 @setlocal enabledelayedexpansion @call echoOffSave call %PICTBAT%setInOut %1 mr if "%mrSTROKE%"=="" set mrSTROKE=-stroke #f00 -fill None if "%mrPIX_HT%"=="" set mrPIX_HT=20 if "%mrCOL_X%"=="" set mrCOL_X=1 if "%mrCOL_Y%"=="" set mrCOL_Y=2 set RW=%3 if "%RW%"=="" set RW=1 set RH=%4 if "%RW%"=="" set RH=1 set /A W_2=%RW%/2 set /A H_2=%RH%/2 set nCrop=0 set sRECT= set sNUMB= call %PICTBAT%getPointSize %INFILE% %H_2% set mrTEXT=-pointsize %gpPointsize% -fill #f00 -stroke None for /F "tokens=%mrCOL_X%,%mrCOL_Y% delims=, " %%X in (%2) do ( if not "%%X" GTR "a" ( set /A dx=%%X-%W_2% set /A dy=%%Y-%H_2% set /A endX=!dx!+%RW%-1 set /A endY=!dy!+%RH%-1 set sRECT=!sRECT! rectangle !dx!,!dy!,!endX!,!endY! set ANNOT=%%Z if "%ANNOT%"=="" set ANNOT=!nCrop! if not "%mrPIX_HT%"=="0" set sNUMB=!sNUMB! text %%X,%%Y '!ANNOT!' set /A nCrop+=1 ) ) if "%mrPIX_HT%"=="0" ( set sTEXT= ) else ( set sTEXT=%mrTEXT% -draw "%sNUMB%" ) %IM%convert ^ %INFILE% ^ %mrSTROKE% ^ -draw "%sRECT%" ^ %sTEXT% ^ %OUTFILE% @call echoRestore @endlocal & set mrOUTFILE=%OUTFILE%
setlocal set TEMP_TIFF=%TEMP%\tg.tiff set TEMP_XCF=%TEMP%\tg.xcf %IM%convert ^ %* ^ -set label %%f ^ -type TrueColorAlpha ^ -compress zip ^ %TEMP_TIFF% call %PICTBAT%GimpLoadSave %TEMP_TIFF% xcf start %GIMP% %TEMP_XCF%
rem Searches image %1 for image %2. @rem Writes results to optional batch file %3. Don't use this; it is for legacy purposes only. @rem If dimensions are large, resizes to find approx location, @rem and searches again within cropped limits. @rem Assumes width and height of %2 is smaller than of %1. @rem @rem Also uses: @rem siMETRIC defaults to RMSE @rem siDEBUG if 1, creates a marked-up copy of image. @rem siDEBUG_STROKE eg to get thick strokes @rem @rem Returns: @rem siCOMP_XW, siCOMP_YW coord of top-left of found area @rem siCOMP_FLT RMSE difference beween %2 and found area @rem siCOMP_CROP=%subW%x%subH%+%COMP_XW%+%COMP_YW% crop spec of found area @rem Written: 31 Jan 2014 @rem Revised: 6 May 2014 @rem Revised: 31 May 2014 Don't resize src if already exists. @rem FIXME: +repage, then add offsets (-format "%X %Y") at end. @if "%2"=="" findstr /B "rem @rem" %~f0 & exit /B 1 @setlocal @call echoOffSave call %PICTBAT%setInOut %1 si if "%siDEBUG%"=="1" ( set DEBUG_OUT=%BASENAME%_si_dbg%EXT% if "%siDEBUG_STROKE%"=="" set siDEBUG_STROKE=-fill None -stroke #f00 ) set SRCNAME=%~n1 set SRC=%INFILE% set SUB=%2 set fBAT=%3 if "%fBAT%"=="" set fBAT=NUL if "%siMETRIC%"=="" set siMETRIC=RMSE set TMPEXT=.miff set TMPDIR=%TEMP% set TMPSRC=%TMPDIR%\siSrc%TMPEXT% set TMPSUB=%TMPDIR%\siSub%TMPEXT% if not "%fBat%"=="NUL" del %fBat% 2>nul FOR /F "usebackq" %%L ^ IN (`%IM%convert -ping %SUB% -format "subW=%%w\nsubH=%%h\nMinDim=%%[fx:w<h?w:h]" info:`) ^ DO set /A %%L FOR /F "usebackq" %%L ^ IN (`%IM%identify -format "OFFSET_X=%%X\nOFFSET_Y=%%Y" %SRC%`) ^ DO set /A %%L echo MinDim=%MinDim% Offset=(%OFFSET_X%,%OFFSET_Y%) if %MinDim% GEQ 10000 ( call :ResizeSrch 0.1 1000 call :CropSrch !COMP_XW! !COMP_YW! 2000 ) else if %MinDim% GEQ 5000 ( call :ResizeSrch 0.2 500 call :CropSrch !COMP_XW! !COMP_YW! 1000 ) else if %MinDim% GEQ 2000 ( call :ResizeSrch 0.5 200 call :CropSrch !COMP_XW! !COMP_YW! 400 ) else if %MinDim% GEQ 1000 ( call :ResizeSrch 1 100 call :CropSrch !COMP_XW! !COMP_YW! 200 ) else if %MinDim% GEQ 500 ( call :ResizeSrch 2 50 call :CropResizeSrch !COMP_XW! !COMP_YW! 100 5 20 call :CropResizeSrch !COMP_XW! !COMP_YW! 40 10 10 call :CropResizeSrch !COMP_XW! !COMP_YW! 20 20 5 call :CropResizeSrch !COMP_XW! !COMP_YW! 10 50 2 call :CropSrch !COMP_XW! !COMP_YW! 4 ) else if %MinDim% GEQ 200 ( call :ResizeSrch 5 20 call :CropResizeSrch !COMP_XW! !COMP_YW! 40 10 10 call :CropResizeSrch !COMP_XW! !COMP_YW! 20 20 5 call :CropResizeSrch !COMP_XW! !COMP_YW! 10 50 2 call :CropSrch !COMP_XW! !COMP_YW! 4 ) else if %MinDim% GEQ 100 ( call :ResizeSrch 10 10 call :CropSrch !COMP_XW! !COMP_YW! 20 ) else if %MinDim% GEQ 50 ( call :ResizeSrch 20 5 call :CropSrch !COMP_XW! !COMP_YW! 10 ) else if %MinDim% GEQ 20 ( call :ResizeSrch 50 2 call :CropSrch !COMP_XW! !COMP_YW! 2 ) else if %MinDim% GEQ 10 ( call :ResizeSrch 50 2 call :CropSrch !COMP_XW! !COMP_YW! 2 ) else ( FOR /F "usebackq tokens=1-4 delims=()@, " %%R ^ IN (`%IM%compare ^ -similarity-threshold 0 -dissimilarity-threshold 1 -subimage-search ^ -metric %siMETRIC% %SRC% %SUB% NULL: 2^>^&1`) ^ DO ( set COMP_INT=%%R set COMP_FLT=%%S set COMP_XW=%%T set COMP_YW=%%U ) ) rem set /A COMP_XW+=%OFFSET_X% rem set /A COMP_YW+=%OFFSET_Y% if "%siDEBUG%"=="1" ( set /A endX=%COMP_XW%+%subW%-1 set /A endY=%COMP_YW%+%subH%-1 rem FIXME: does draw respect offsets? Add +repage to make this irrelevant. %IM%convert ^ %SRC% ^ +repage ^ %siDEBUG_STROKE% ^ -draw "rectangle %COMP_XW%,%COMP_YW% !endX!,!endY!" ^ %DEBUG_OUT% ) if not "%fBat%"=="NUL" echo set COMP_XW=%COMP_XW%^&set COMP_YW=%COMP_YW%^&set COMP_FLT=%COMP_FLT%^&set COMP_CROP=%subW%x%subH%+%COMP_XW%+%COMP_YW% >%fBat% FOR /F "usebackq" %%L ^ IN (`%IM%convert -ping %SUB% -format "centX=%%[fx:%COMP_XW%+w/2]\ncentY=%%[fx:%COMP_YW%+h/2]" info:`) ^ DO set /A %%L call echoRestore endlocal & set siCOMP_XW=%COMP_XW%& set siCOMP_YW=%COMP_YW%& set siCOMP_FLT=%COMP_FLT%& set siCENT_X=%centX%& set siCENT_Y=%centY%& set siCOMP_CROP=%subW%x%subH%+%COMP_XW%+%COMP_YW% exit /B 0 :error echo Error in %0 exit /B 1 rem ------ Subroutines ---------------------------------------------------------- :ResizeSrch rem %1 is percentage reduction, eg 50 for 50%. May be <1. rem %2 is multiplier (=100/%1) echo ResizeSrch %1 %2 rem The convert and compare could be combined into one convert. set COMP_XW=0 set COMP_YW=0 set TMPSRC_RES=%TMPDIR%\%SRCNAME%_si_%1%TMPEXT% @rem FIXME: +repage, then add offsets (-format "%X %Y") at end. if not exist %TMPSRC_RES% %IM%convert %SRC% +repage -resize %1%% %TMPSRC_RES% %IM%convert %SUB% -resize %1%% %TMPSUB% set COMP_XW= FOR /F "tokens=1-4 usebackq delims=()@, " %%R ^ IN (`%IM%compare ^ -similarity-threshold 0 -dissimilarity-threshold 1 -subimage-search ^ -metric %siMETRIC% %TMPSRC_RES% %TMPSUB% NULL: 2^>^&1`) ^ DO ( rem echo %%R %%S %%T %%U set COMP_INT=%%R set COMP_FLT=%%S if not "%%T"=="" set /A COMP_XW=%%T*%2 if not "%%U"=="" set /A COMP_YW=%%U*%2 ) if "%COMP_XW%"=="" exit /B 1 echo COMP_XW, YW = %COMP_XW% %COMP_YW% exit /B 0 :CropSrch rem %1,%2 are coords for top-left of estimated result. rem %3 is plus or minus for tolerance in both directions. echo CropSrch %1 %2 %3 set /A cropL=%1-%3 set /A cropT=%2-%3 if %cropL% LSS 0 set cropL=0 if %cropT% LSS 0 set cropT=0 set /A cropW=%subW%+%3+%3 set /A cropH=%subH%+%3+%3 set COMP_XW=%cropL% set COMP_YW=%cropT% %IM%convert ^ %SRC% ^ +repage ^ -crop %cropW%x%cropH%+%cropL%+%cropT% ^ +repage ^ %TMPSRC% FOR /F "tokens=1-4 usebackq delims=()@, " %%R ^ IN (`%IM%compare ^ -similarity-threshold 0 -dissimilarity-threshold 1 -subimage-search ^ -metric %siMETRIC% %TMPSRC% %SUB% NULL: 2^>^&1`) ^ DO ( rem echo %%R %%S %%T %%U set COMP_INT=%%R set COMP_FLT=%%S if not "%%T"=="" set /A COMP_XW+=%%T if not "%%U"=="" set /A COMP_YW+=%%U ) echo COMP_XW, YW = %COMP_XW% %COMP_YW% exit /B 0 :CropResizeSrch rem %1,%2 are coords for top-left of estimated result. rem %3 is plus or minus for tolerance in both directions. rem %4 is percentage reduction, eg 50 for 50%. May be <1. rem %5 is multiplier (=100/%1) rem %1 to %3 are in terms of original full size. echo CropResizeSrch %1 %2 %3 %4 %5 set /A cropL=%1-%3 set /A cropT=%2-%3 if %cropL% LSS 0 set cropL=0 if %cropT% LSS 0 set cropT=0 set /A cropW=%subW%+%3+%3 set /A cropH=%subH%+%3+%3 set COMP_XW=%cropL% set COMP_YW=%cropT% %IM%convert ^ %SRC% ^ -crop %cropW%x%cropH%+%cropL%+%cropT% ^ +repage ^ -resize %4%% -write %TMPSRC% +delete ^ %SUB% -resize %4%% %TMPSUB% FOR /F "tokens=1-4 usebackq delims=()@, " %%R ^ IN (`%IM%compare ^ -similarity-threshold 0 -dissimilarity-threshold 1 -subimage-search ^ -metric %siMETRIC% %TMPSRC% %TMPSUB% NULL: 2^>^&1`) ^ DO ( echo %%R %%S %%T %%U set COMP_INT=%%R set COMP_FLT=%%S if not "%%T"=="" set /A COMP_XW+=%%T*%5 if not "%%U"=="" set /A COMP_YW+=%%U*%5 ) echo COMP_XW, YW = %COMP_XW% %COMP_YW% exit /B 0
All images on this page were created by the commands shown, using:
%IM%identify -version
Version: ImageMagick 6.8.9-0 Q16 x64 2014-04-06 http://www.imagemagick.org Copyright: Copyright (C) 1999-2014 ImageMagick Studio LLC Features: DPC OpenMP Delegates: bzlib cairo freetype jbig jng jp2 jpeg lcms lqr pangocairo png ps rsvg tiff webp xml zlib
Source file for this web page is mtokens=1-4 usebackq delims=()@, " %%R ^ IN (`%IM%compare ^ -similarity-threshold 0 -dissimilarity-threshold 1 -subimage-search ^ -metric %siMETRIC% %TMPSRC% %TMPSUB% NULL: 2^>^&1`) ^ DO ( echo %%R %%S %%T %%U set COMP_INT=%%R set COMP_FLT=%%S if not "%%T"=="" set /A COMP_XW+=%%T*%5 if not "%%U"=="" set /A COMP_YW+=%%U*%5 ) rem echo COMP_XW, YW = %COMP_XW% %COMP_YW% exit /B 0
All images on this page were created by the commands shown, using:
%IM%identify -version
Version: ImageMagick 6.9.1--6 Q16 x64 2015-06-20 http://www.imagemagick.org Copyright: Copyright (C) 1999-2015 ImageMagick Studio LLC License: http://www.imagemagick.org/script/license.php Features: Cipher DPC Modules OpenMP Delegates (built-in): bzlib cairo freetype jng jp2 jpeg lcms lqr openexr pangocairo png ps rsvg tiff webp xml zlib
Source file for this web page is measdet.h1. To re-create this web page, run "procH1 measdet".
This page, including the images, is my copyright. Anyone is permitted to use or adapt any of the code, scripts or images for any purpose, including commercial use.
Anyone is permitted to re-publish this page, but only for non-commercial use.
Anyone is permitted to link to this page, including for commercial use.
Page version v1.0 24-May-2014.
Page created 14-Oct-2015 05:11:19.
Copyright © 2015 Alan Gibson.