﻿ snibgo's ImageMagick pages

# Correlating shapes

blah.

See Polar Distortions for a discussion of unrolling images around a defined central point (and rolling them back up).

See Nearest coastal point for the nearCoast.bat script.

Scripts on this page assume that the version of ImageMagick in %IMDEV% has been built with various process modules. See Process modules.

## The method

We want to correlate one shape with another. We can do this by finding points on the edge of one shape, then for each point finding the closest point on the other.

If the shapes are not similar, this can create a problem that a correlation in one direction is not a correlation in the other direction. That is, if point pA on shape A is the closest point to pB on shape B, it may not be true that pB on shape B is the closest point to pA on shape A.

## Sample images

set SRC_DIR=\pictures\20150805\

set RESIZE=-resize 400x400

set SRC1=%SRC_DIR%AGA_2499_rnd2.tiff
set SRC2=%SRC_DIR%AGA_2505_tri2.tiff

set MSK1=%SRC_DIR%AGA_2499_mc.png
set MSK2=%SRC_DIR%AGA_2505_mc.png

goto skip
 %IM%convert ^ %SRC1% ^ %RESIZE% ^ cs_src1.png %IM%convert ^ %SRC2% ^ %RESIZE% ^ cs_src2.png %IM%convert ^ %MSK1% ^ %RESIZE% ^ cs_msk1.png %IM%convert ^ %MSK2% ^ %RESIZE% ^ cs_msk2.png
 Create an outline of the union of the two masks: %IM%convert ^ cs_msk1.png ^ cs_msk2.png ^ -compose Lighten -composite ^ -edge 1 ^ cs_sup_msk.png Ideally, this edge should be slightly outside the union. Blah. set nlDEBUG=1 call %PICTBAT%nLightest ^ cs_sup_msk.png 999 >cs_sup_msk.lis

cs_sup_msk.lis contains a list of coordinates found in the outline:

159,10
200,13
119,20
239,26
84,43
274,48
59,76
304,76
329,109
43,114
344,148
36,155
356,188
39,196
363,229
49,236
361,270
37,276
379,307
17,312
1,350
398,352
361,372
131,373
295,373
35,374
76,374
172,376
254,387
212,388

Find the nearest points in each mask. This gives us two pairs of coordinates (x, y, x', y') for each point: a position on the round mask, and a position on the triangular mask. We write this data to a number of text files:

• cs_correl_1_2.lis
• cs_correl_2_1.lis
• cs_tri1.lis
• cs_tri2.lis
• cs_lines.txt like cs_correl_1_2.lis, but with text "line" at the start of each line.
set ncSEA_COL=auto

del cs_correl_1_2.lis
del cs_correl_2_1.lis
del cs_lines.txt

set /A NFp1=%nl_nFound%+1

echo %NFp1% 2 >cs_tri1.lis
echo %NFp1% 2 >cs_tri2.lis

for /F "tokens=1-2 delims=, " %%X in (cs_sup_msk.lis) do (
call %PICTBAT%nearCoast cs_msk1.png %%X %%Y

set mx=!ncCST_X!
set my=!ncCST_Y!

call %PICTBAT%nearCoast cs_msk2.png %%X %%Y

echo line !mx!,!my!,!ncCST_X!,!ncCST_Y! >>cs_lines.txt

echo !mx! !my! >>cs_tri1.lis
echo !ncCST_X! !ncCST_Y! >>cs_tri2.lis

echo !mx! !my! !ncCST_X! !ncCST_Y! >>cs_correl_1_2.lis
echo !ncCST_X! !ncCST_Y! !mx! !my! >>cs_correl_2_1.lis
)

set ncSEA_COL=

Add the central point as a null-distortion.

for /F "usebackq" %%L in (`%IM%identify ^
-ping ^
-format "W_2=%%[fx:w/2]\nH_2=%%[fx:h/2]" ^
cs_msk1.png`) do set %%L

echo %W_2% %H_2% >>cs_tri1.lis
echo %W_2% %H_2% >>cs_tri2.lis

echo %W_2% %H_2% %W_2% %H_2% >>cs_correl_1_2.lis
echo %W_2% %H_2% %W_2% %H_2% >>cs_correl_2_1.lis

Make debugging images.

 :skip call %PICTBAT%tritsttst cs_tri1.lis cs_t1 call %PICTBAT%tritsttst cs_tri2.lis cs_t2
 %IM%convert ^ cs_msk1.png ^ cs_msk2.png ^ -evaluate Divide 2 ^ -compose Plus -composite ^ -stroke Red -draw "@cs_lines.txt" ^ cs_tc_lines.png %IM%convert ^ cs_src1.png ^ -distort Shepards "@cs_correl_1_2.lis" ^ cs_ds1.png %IM%convert ^ cs_src2.png ^ -distort Shepards "@cs_correl_2_1.lis" ^ cs_ds2.png %IMDEV%convert ^ cs_src1.png ^ -verbose ^ -distort Triangulate "@cs_correl_1_2.lis" ^ cs_dt1.png >cs_dt1.lis 2^>^&1 %IMDEV%convert ^ cs_src2.png ^ -verbose ^ -distort Triangulate "@cs_correl_2_1.lis" ^ cs_dt2.png >cs_dt2.lis 2^>^&1

Again, but with "last". Make debugging images.

 call %PICTBAT%tritstlasttst cs_tri1.lis cs_t1l call %PICTBAT%tritstlasttst cs_tri2.lis cs_t2l
 %IM%convert ^ cs_msk1.png ^ cs_msk2.png ^ -evaluate Divide 2 ^ -compose Plus -composite ^ -stroke Red -draw "@cs_lines.txt" ^ cs_tc_lines.png %IM%convert ^ cs_src1.png ^ -define triangulate:edgesort=Last ^ -distort Shepards "@cs_correl_1_2.lis" ^ cs_ds1l.png %IM%convert ^ cs_src2.png ^ -define triangulate:edgesort=Last ^ -distort Shepards "@cs_correl_2_1.lis" ^ cs_ds2l.png %IMDEV%convert ^ cs_src1.png ^ -verbose ^ -define triangulate:edgesort=Last ^ -distort Triangulate "@cs_correl_1_2.lis" ^ cs_dt1l.png >cs_dt1l.lis 2^>^&1 %IMDEV%convert ^ cs_src2.png ^ -verbose ^ -define triangulate:edgesort=Last ^ -distort Triangulate "@cs_correl_2_1.lis" ^ cs_dt2l.png >cs_dt2l.lis 2^>^&1

## Scripts

For convenience, .bat scripts are also available in a single zip file. See Zipped BAT files.

### nearCoast.bat

rem Given image %1 is black mainland around white "sea",
rem finds coordinates (ncX,ncY) of nearest point on the mainland to given coordinate.
rem If the given coord is in the white "sea", the nearest point will be on the coast.
@rem
@rem   %2, %3 coords of central point  [default center of %1]
@rem        Each coord may be suffixed with "%", for percentage of width or height.
@rem        Default: centre of image.
@rem   %4 proportion towards coast point (0 to 100) [100]
@rem   %5 output debugging image [default NULL:, no output]
@rem
@rem Also uses:
@rem   ncSUP_SAMP Factor for supersampling [default 1].
@rem   ncPREFIX prefix for temporary files
@rem   ncBLACKSEA if 1, assumes sea is black (and land is white) so doesn't negate.
@rem   ncSEA_COL sea color: black, white or auto. Default white.
@rem     auto will choose automatically, which takes time.
@rem   nc?? automatic choice for negate
@rem   nc?? if 1, assumes %1 is already supersampled and unrolled.
@rem
@rem Returns data about nearest point:
@rem   ncRAD   distance from given coord. 0 means given coord wasn't sea.
@rem   ncTHETA bearing from given coord to found point, anti-clockwise from north.
@rem   ncCST_X } x,y coord of found point.
@rem   ncCST_Y }

@if "%1"=="" findstr /B "rem @rem" %~f0 & exit /B 1

@setlocal enabledelayedexpansion

@call echoOffSave

call %PICTBAT%setInOut %1 nc

if "%ncIM%"=="" set ncIM=%IMDEV%

set CENT_X=%2
set CENT_Y=%3

if "%CENT_X%"=="." set CENT_X=
if "%CENT_Y%"=="." set CENT_Y=

set BLANK_CENT=0
if "%CENT_X%"=="" if "%CENT_Y%"=="" set BLANK_CENT=1

if "%CENT_X%"=="" set CENT_X=50%%
if "%CENT_Y%"=="" set CENT_Y=50%%

set X_SUFFIX=%CENT_X:~-1%
if "%X_SUFFIX%"=="%%" (
set nX=%CENT_X:~0,-1%
set X_MULT=w/100
) else (
set nX=%CENT_X%
set X_MULT=1
)

set Y_SUFFIX=%CENT_Y:~-1%
if "%Y_SUFFIX%"=="%%" (
set nY=%CENT_Y:~0,-1%
set Y_MULT=h/100
) else (
set nY=%CENT_Y%
set Y_MULT=1
)

set PROP=%4
if "%PROP%"=="." set PROP=
if "%PROP%"=="" set PROP=100

set OUTFILE=%5
if "%OUTFILE%"=="." set OUTFILE=
if "%OUTFILE%"=="" set OUTFILE=NULL:

set SUP_SAMP=%ncSUP_SAMP%
if "%SUP_SAMP%"=="." set SUP_SAMP=
if "%SUP_SAMP%"=="" set SUP_SAMP=1

for /F "usebackq" %%L in (`%ncIM%identify ^
-ping ^
-format "WW=%%w\nHH=%%h\nnX=%%[fx:%nX%*%X_MULT%]\nnY=%%[fx:%nY%*%Y_MULT%]"
%INFILE%`) do set %%L

for /F "usebackq" %%L in (`%ncIM%identify ^
-ping ^
-format "W_SS=%%[fx:%WW%*%SUP_SAMP%]\nH_SS=%%[fx:%HH%*%SUP_SAMP%]\nnXS=%%[fx:%nX%*%SUP_SAMP%]\nnYS=%%[fx:%nY%*%SUP_SAMP%]"
xc:`) do set %%L

rem echo WW=%WW%  HH=%HH%  W_SS=%W_SS%  H_SS=%H_SS%  nX=%nX%  nY=%nY%  nXS=%nXS%  nYS=%nYS%

if %BLANK_CENT%==1 (
set sUNROLL=-distort depolar "-1,0"
) else (
set sUNROLL=-distort depolar "-1,0,%nXS%,%nYS%"
)

if %SUP_SAMP%==1 (
set sSUP_UP=
) else (
set sSUP_UP=-resize "%W_SS%x%H_SS%^^^!"
)

if "%ncBLACKSEA%"=="1" (
set sNEG=
) else (
set sNEG=-negate
)

if "%ncSEA_COL%"=="" set ncSEA_COL=white

if "%ncSEA_COL%"=="white" (
set sNEG=-negate
) else if "%ncSEA_COL%"=="black" (
set sNEG=
) else if "%ncSEA_COL%"=="auto" (
for /F "usebackq" %%L in (`%ncIM%identify ^
-format "doNEG=%%[fx:p{0,0}.intensity>0.5?1:0]" ^
%INFILE%`) do set %%L

if "!doNeg!"=="1" (
set sNEG=-negate
) else (
set sNEG=
)
) else (
)

for /F "usebackq tokens=1-3 delims=:, " %%W in (`%ncIM%convert ^
%INFILE% ^
%sNEG% ^
%sSUP_UP% ^
-virtual-pixel Black ^
%sUNROLL% ^
-threshold 50%% ^
-process onewhite ^
NULL: 2^>^&1`) do (
set MAGIC=%%W
set X=%%X
set Y=%%Y
)

if not "%magic%"=="onewhite" exit /B 1

for /F "usebackq" %%L in (`%ncIM%identify ^
-ping ^
-format "dx=%%[fx:%nXS%>%W_SS%/2?%nXS%:%W_SS%-%nXS%]\ndy=%%[fx:%nYS%>%H_SS%/2?%nYS%:%H_SS%-%nYS%]"
%INFILE%`) do set %%L

for /F "usebackq" %%L in (`%ncIM%identify ^
-ping ^
xc:`) do set %%L

for /F "usebackq" %%L in (`%ncIM%identify ^
xc:`) do set %%L

if not "%OUTFILE%"=="NULL:" (

if "%sNEG%"=="" (
set DBG_COL=yellow
) else (
set DBG_COL=red
)

%ncIM%convert ^
%INFILE% ^
-fill None -stroke !DBG_COL! ^
-draw "line   %nX%,%nY% %CST_X%,%CST_Y%" ^
-draw "circle %nX%,%nY% %CST_X%,%CST_Y%" ^
-alpha off ^
%OUTFILE%
)

call echoRestore

@endlocal & set ncOUTFILE=%OUTFILE%& set ncRAD=%RAD%& set ncTHETA=%THETA%& set ncCST_X=%CST_X%& set ncCST_Y=%CST_Y%

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
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

To improve internet download speeds, some images may have been automatically converted (by ImageMagick, of course) from PNG to JPG.

Source file for this web page is correlsh.h1. To re-create this web page, run "procH1 correlsh".

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.