snibgo's ImageMagick pages

Test coordinate pairs

When points in one image roughly correspond to points in another, we want to weed out pairs where the match is too approximate.

This page is only partially written.

A building block for this page is Searching an image.

Suppose a feature-matching process has built a list of points in image A that correspond to a list of points in image B. The correspondence is measured by a number, perhaps the RMSE of areas centred on the corrdinates.

The list probably contains false positives, where one point seems to correspond to another but actually doesn't. Comparing the points to each other in isolation from the rest of the images, they seem to match. But when seen as part of the overall pattern of matches, we can see they don't.

So the next task is to weed the list.

The method

The script testCoordPairs.bat takes a text data file and makes another, of the same format, with just the good data. Each line contains five numbers: score, xA, yA, xB, yB. (xA,yA) are integer coordinates in image A, and (xB,yB) are integer coordinates in image B. The score is typically zero to one. The order of the points is immaterial. Each point can be considered to move from the A-coordinates to the B-coordinates. So it moves horizontally by dx and vertically by dy, or a radial distance r = dx^2+dy^2.

This script compares the score with a threshold, eliminating any over the treshold. It calculates the mean and standard deviation of score, dx, dy and r, and eliminates lines where dx is outside the range mean plus or minus a constant times the standard deviation, ie where abs(dx - mean(dx)) > k * standard_deviation(dx). Likewise for dy and r.

Where there is lttle rotation, k=1 or 2 are reasonable values.

Currently the script does nothing with the mean and standard deviation of the score.

Using the scripts

[Example images, marked up. Indicate points that don't really match.]

[Data file]

[Process the data file. Now all the matches are genuine.]

Scripts

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

testCoordPairs.bat

rem From %1, a text file with lines of score,x0,y0,x1,y1
rem creates %2 another text file with "good" coordinate pairs.
@rem
@rem  Returns:
@rem    tcpNUM_GOOD

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

@setlocal enabledelayedexpansion

@call echoOffSave

set INFILE=%1
set OUTFILE=%2

set tcpSCORE_LIMIT=0.05
set tcpSD_FACT=2

del %OUTFILE%>nul

rem A coord pair is bad if either:
rem   score > tcpSCORE_LIMIT
rem   any of dx, dy, radius minus mean > tcpSD_FACT * standard_deviation

set sigdx=0
set sigdy=0
set sigr=0
set sigdx2=0
set sigdy2=0
set sigr2=0
set sigsc=0
set sigsc2=0
set numGood=0

for /F "tokens=1-5 delims=, " %%A in (%INFILE%) do (
  set IS_BAD=0

  if "%%A" GTR "%tcpSCORE_LIMIT%" set IS_BAD=1

  if !IS_BAD!==0 (
    set /A dx=%%D-%%B
    set /A dy=%%E-%%C
    set /A dx2=!dx!*!dx!
    set /A dy2=!dy!*!dy!
    set /A r2=!dx2!+!dy2!

    set /A sigdx+=!dx!
    set /A sigdy+=!dy!
    set /A sigdx2+=!dx2!
    set /A sigdy2+=!dy2!
    rem set /A sigr2+=!r2!

    for /F "usebackq" %%L in (`%IM%identify ^
      -precision 9 ^
      -format "sigsc=%%[fx:!sigsc!+%%A]\nsigsc2=%%[fx:!sigsc2!+%%A*%%A]" ^
      xc:`) do set %%L

    for /F "usebackq" %%L in (`%IM%identify ^
      -precision 9 ^
      -format "sigr=%%[fx:!sigr!+sqrt(!r2!)]\nsigr2=%%[fx:!sigr2!+!r2!]" ^
      xc:`) do set %%L

    rem echo  %%A !dx! !dy! !r2! !IS_BAD!

    set /A numGood+=1
  )
)

echo numGood=%numGood%
echo sigdx=%sigdx% sigdy=%sigdy%  sigr=%sigr%  sigdx2=%sigdx2% sigdy2=%sigdy2% sigr2=%sigr2%
echo sigsc=%sigsc% sigsc2=%sigsc2%

for /F "usebackq" %%L in (`%IM%identify ^
  -precision 9 ^
  -format "meandx=%%[fx:%sigdx%/%numGood%]\nmeandy=%%[fx:%sigdy%/%numGood%]" ^
  xc:`) do set %%L

for /F "usebackq" %%L in (`%IM%identify ^
  -precision 9 ^
  -format "meanr=%%[fx:%sigr%/%numGood%]" ^
  xc:`) do set %%L

for /F "usebackq" %%L in (`%IM%identify ^
  -precision 9 ^
  -format "meansc=%%[fx:%sigsc%/%numGood%]" ^
  xc:`) do set %%L

for /F "usebackq" %%L in (`%IM%identify ^
  -precision 9 ^
  -format "sdx=%%[fx:%tcpSD_FACT%*sqrt(%sigdx2%/%numGood%-%meandx%*%meandx%)]" ^
  xc:`) do set %%L

for /F "usebackq" %%L in (`%IM%identify ^
  -precision 9 ^
  -format "sdy=%%[fx:%tcpSD_FACT%*sqrt(%sigdy2%/%numGood%-%meandy%*%meandy%)]" ^
  xc:`) do set %%L

for /F "usebackq" %%L in (`%IM%identify ^
  -precision 9 ^
  -format "sdr=%%[fx:%tcpSD_FACT%*sqrt(%sigr2%/%numGood%-%meanr%*%meanr%)]" ^
  xc:`) do set %%L

for /F "usebackq" %%L in (`%IM%identify ^
  -precision 9 ^
  -format "sdsc=%%[fx:%tcpSD_FACT%*sqrt(%sigsc2%/%numGood%-%meansc%*%meansc%)]" ^
  xc:`) do set %%L


echo meandx=%meandx% sdx=%sdx% meandy=%meandy% sdy=%sdy% 
echo meanr=%meanr% sdr=%sdr% meansc=%meansc% sdsc=%sdsc%


set numGood=0

for /F "tokens=1-5 delims=, " %%A in (x3.lis) do (
  set IS_BAD=0

  if "%%A" GTR "%tcpSCORE_LIMIT%" set IS_BAD=1

  if !IS_BAD!==0 (
    set /A dx=%%D-%%B
    set /A dy=%%E-%%C
    set /A dx2=!dx!*!dx!
    set /A dy2=!dy!*!dy!
    set /A r2=!dx2!+!dy2!

    for /F "usebackq" %%L in (`%IM%identify ^
      -precision 9 ^
      -format "badx=%%[fx:abs(!dx!-%meandx%)>%sdx%?1:0]\nbady=%%[fx:abs(!dy!-%meandy%)>%sdy%?1:0]\nbadr=%%[fx:abs(sqrt(!r2!)-meanr)>%sdr%?1:0]" ^
      xc:`) do set %%L

    set /A IS_BAD^|=!badx!||!bady!||!badr!

    if !IS_BAD!==0 (
      rem echo  %%A !dx! !dy! !r2! !badx! !bady! !badr!
      echo  %%A,%%B,%%C,%%D,%%E >>%OUTFILE%

      set /A numGood+=1
    )
  )
)

echo numGood=%numGood%


@call echoRestore

@endlocal & set tcpNUM_GOOD=%numGood%

markRect.bat

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

rem @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 (
  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!
  if not "%mrPIX_HT%"=="0" set sNUMB=!sNUMB! text %%X,%%Y '!nCrop!'

  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

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 compcomp.h1. To re-create this web page, execute "procH1 compcomp".


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.


Page version v1.0 21-May-2014.

Page created 22-May-2014 16:44:34.

Copyright © 2014 Alan Gibson.