snibgo's ImageMagick pages

Slopes

A simple scheme for creating, storing and processing slopes.

Some image processing works on slopes, also known as vector gradients or vector gradient fields.

In essence, a slope is the value of one pixel minus the value of another pixel, divided by the distance between them. This would give us the slope at the point mid-way between the pixels.

Instead, we may prefer to say the slope at a pixel is the value of the pixel at one side minus the value of the pixel at the other side. This can be done in the x-direction and the y-direction, so we get two values. Scripts here store slopes in a pair of colour images, typically two images in a single MIFF file. The first image is the gradient in the x-direction, the second is the gradient in the y-direction.

Slopes of ordinary photographs are usually close to zero, and can be positive or negative.

If the range of pixel values is 0 to 100%, then the range of slopes would -100% to +100%. Scripts shown here divide by two and add 50%, so the resulting values are in the range 0 to 100%, with 50% representing a zero slope. (Note that when we use the difference beween pixels on either side of a central pixel, the distance between them is two, so dividing by two is reasonable.)

From the two slopes, we can calculate magnitude = hypot (slope-x, slope-y).

In this context, literature often uses scalar to mean ordinary images with one value per channel per pixel, and vector to mean two values per channel per pixel.

These slope methods are useful for Seamless photomontage.

Sample inputs

%IM%convert ^
  -size 20x260 ^
  xc:Black xc:White xc:Black xc:Red xc:Black ^
  xc:Lime xc:Black xc:Blue xc:Black ^
  xc:gray(50%%) xc:Black xc:srgb(50%%,0,0) xc:Black ^
  +append ^
  slp_src.png
slp_src.png
%IM%convert ^
  slp_src.png ^
  -rotate 90 ^
  slp_src_h.png
slp_src_h.png
%IM%convert ^
  slp_src.png ^
  ( slp_src_h.png -transparent Black ) ^
  -compose Over -composite ^
  slp_src_vh.png
slp_src_vh.png

toes.png

toes.pngjpg

Operations

The script slopeXY.bat takes an input colour image and makes a vector. Here, we store these as single MIFF files, but convert them to a pair of PNG files for viewing on the web.

call %PICTBAT%slopeXY ^
  slp_src.png slp_sxy.miff

%IM%convert slp_sxy.miff[0] slp_sxy_0.png

%IM%convert slp_sxy.miff[1] slp_sxy_1.png
slp_sxy_0.png slp_sxy_1.png
call %PICTBAT%slopeXY ^
  slp_src_h.png slp_h_sxy.miff

%IM%convert slp_h_sxy.miff[0] slp_h_sxy_0.png

%IM%convert slp_h_sxy.miff[1] slp_h_sxy_1.png
slp_h_sxy_0.png slp_h_sxy_1.png
call %PICTBAT%slopeXY ^
  slp_src_vh.png slp_vh_sxy.miff

%IM%convert slp_vh_sxy.miff[0] slp_vh_sxy_0.png

%IM%convert slp_vh_sxy.miff[1] slp_vh_sxy_1.png
slp_vh_sxy_0.png slp_vh_sxy_1.png

The script slopeXYmag.bat takes a vector as input, and creates a scalar output, the magnitude of the vector.

call %PICTBAT%slopeXYmag ^
  slp_vh_sxy.miff slp_vh_mag.png
slp_vh_mag.png

The script slopeXYdiv.bat takes a vector as input, and creates a scalar output, the divergence (aka div) of the vector.

See Wikipedia: divergence.

call %PICTBAT%slopeXYdiv ^
  slp_vh_sxy.miff slp_vh_div.png
slp_vh_div.png

The script shpDiv.bat takes an image as input, and directly makes a divergence of the slope. This is also sharper.

call %PICTBAT%shpDiv ^
  slp_src_vh.png slp_vh_shpdiv.png
slp_vh_shpdiv.png

The same operations on toes.png:

call %PICTBAT%slopeXY ^
  toes.png slp_toes_sxy.miff

%IM%convert slp_toes_sxy.miff[0] slp_toes_sxy_0.png

%IM%convert slp_toes_sxy.miff[1] slp_toes_sxy_1.png
slp_toes_sxy_0.png slp_toes_sxy_1.png
call %PICTBAT%slopeXYmag ^
  slp_toes_sxy.miff slp_toes_mag.png
slp_toes_mag.pngjpg
call %PICTBAT%slopeXYdiv ^
  slp_toes_sxy.miff slp_toes_div.miff
slp_toes_div.miffjpg

To aid visibility, the script autoLevMid.bat expands the range of values so the lightest is 100% or the darkest is 0%, or both. So it works like "-auto-level" but keeps 50% at 50%.

call %PICTBAT%autoLevMid ^
  slp_toes_div.png slp_td_alm.png
slp_td_alm.pngjpg

Round-trip

[To do: blah.]

Scripts

slopeXY.bat

rem From colour image %1,
rem find slope of RGB channels.
rem Write output to _two_ images: first is x-slope, second is y-slope.
rem In output, 50% means no slope, > 50% value increases rightwards or downwards.

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

@setlocal

@call echoOffSave

call %PICTBAT%setInOut %1 sxy

if not "%2"=="" set OUTFILE=%2


%IM32f%convert ^
  %INFILE% ^
  -alpha off ^
  -virtual-pixel Edge ^
  -define convolve:scale="50%%^!" -bias 50%% ^
  ( -clone 0 -morphology Convolve 3x1:1,0,-1 ) ^
  ( -clone 0 -morphology Convolve 1x3:1,0,-1 ) ^
  -delete 0 ^
  +depth ^
  -depth 32 ^
  -define "quantum:format=floating-point" ^
  %OUTFILE%


call echoRestore

endlocal & set sxyOUTFILE=%OUTFILE%

slopeXYminus.bat

rem Given %1 and %2 are slopeXY structures (thus contain 2 images each)
rem returns %3 a slopeXY structure, each channel is half (%2 minus %1.)

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

@setlocal

@call echoOffSave

call %PICTBAT%setInOut %1 sxyd

if not "%3"=="" if not "%3"=="." set OUTFILE=%3

set IN_A=%INFILE%
set IN_B=%2


%IM%convert ^
  ( %IN_A%[0] ^
    %IN_B%[0] ^
    -compose Mathematics -define compose:args=0,0.5,-0.5,0.5 -composite ^
  ) ^
  ( %IN_A%[1] ^
    %IN_B%[1] ^
    -compose Mathematics -define compose:args=0,0.5,-0.5,0.5 -composite ^
  ) ^
  +depth ^
  %OUTFILE%


call echoRestore

endlocal & set sxydOUTFILE=%OUTFILE%

slopeXYweighted.bat

rem Given %1 and %2 are slopeXY structures (thus contain 2 images each)
rem write weighted output %3 a slopeXY structure.
rem %4 is w1, floating-point weight (typically 0 to 1).
rem %5 is w2, floating-point weight (typically 0 to 1).
rem
rem Output each channel is w1 * %1 + w2 * %2

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

@setlocal

@call echoOffSave

call %PICTBAT%setInOut %1 sxyw

if not "%3"=="" if not "%3"=="." set OUTFILE=%3

set WT1=%4
if "%WT1%"=="." set WT1=
if "%WT1%"=="" set WT1=0.5

set WT2=%5
if "%WT2%"=="." set WT2=

if "%WT2%"=="" for /F "usebackq" %%L in (`%IM%identify ^
  -format "WT2=%%[fx:1-%WT1%]" ^
  xc:`) do set %%L

set IN_A=%INFILE%
set IN_B=%2


%IM%convert ^
  ( %IN_A%[0] ^
    %IN_B%[0] ^
    -compose Mathematics -define compose:args=0,%WT2%,%WT1%,-0.5 -composite ^
  ) ^
  ( %IN_A%[1] ^
    %IN_B%[1] ^
    -compose Mathematics -define compose:args=0,%WT2%,%WT1%,-0.5 -composite ^
  ) ^
  +depth ^
  %OUTFILE%


call echoRestore

endlocal & set sxywOUTFILE=%OUTFILE%

slopeXYmag.bat

rem Given %1 is slopeXY structure (thus contains 2 images),
rem returns %2 conventional RGB image
rem with channels set to magnitude.

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

@setlocal

@call echoOffSave

call %PICTBAT%setInOut %1 sxym

if not "%2"=="" set OUTFILE=%2

%IM%convert ^
  %INFILE% ^
  -channel RGB ^
  -solarize 50%% -level 50,0%% ^
  +level 0,70.71067811865475%% ^
  -evaluate Pow 2 ^
  -separate ^
  ( -clone 0,3 -compose plus -composite ) ^
  ( -clone 1,4 -compose plus -composite ) ^
  ( -clone 2,5 -compose plus -composite ) ^
  -delete 0-5 ^
  -evaluate Pow 0.5 ^
  -combine ^
  +depth ^
  %OUTFILE%

call echoRestore

endlocal & set sxymOUTFILE=%OUTFILE%

slopeXYdiv.bat

rem Given %1 is slopeXY structure (thus contains 2 images)
rem returns %2 scalar image, the divergence of %1.
@rem
@rem The divergence of %1 is the x-slope of the x component,
@rem plus the y-slope of the y component.
@rem See Perez and https://en.wikipedia.org/wiki/Divergence.
@rem (Yeah, I think this is weird.)
@rem We find slope in the same way as slopeXY.bat.


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

@setlocal

@call echoOffSave

call %PICTBAT%setInOut %1 sxyd

if not "%2"=="" if not "%2"=="." set OUTFILE=%2

%IM32f%convert ^
  ( %INFILE%[0] ^
    -alpha off ^
    -define convolve:scale="50%%^!" -bias 50%% ^
    -morphology Convolve 3x1:1,0,-1 ^
  ) ^
  ( %INFILE%[1] ^
    -alpha off ^
    -define convolve:scale="50%%^!" -bias 50%% ^
    -morphology Convolve 1x3:1,0,-1 ^
  ) ^
  -compose Mathematics -define compose:args=0,1,1,-0.5 -composite ^
  +depth ^
  -depth 32 ^
  -define "quantum:format=floating-point" ^
  %OUTFILE%

call echoRestore

endlocal & set sxydOUTFILE=%OUTFILE%

shpDiv.bat

rem From colour image %1,
rem returns %2 scalar image, the divergence of %1.


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

@setlocal

@call echoOffSave

call %PICTBAT%setInOut %1 shd

if not "%2"=="" set OUTFILE=%2

%IM%convert ^
  %INFILE% ^
  -define convolve:scale="400%%^!" -bias 50%% ^
  -morphology Convolve 3x3:0,1,0,1,-4,1,0,1,0 ^
  %OUTFILE%

call echoRestore

endlocal & set shdOUTFILE=%OUTFILE%

autoLevMid.bat

rem Makes auotolevel version, such that 50% remains at 50%.
rem Output will have 0% or 100%, but generally not both.

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

@setlocal

@call echoOffSave

call %PICTBAT%setInOut %1 alm

if not "%2"=="" set OUTFILE=%2


for /F "usebackq" %%L in (`%IM%convert ^
  %INFILE% ^
  -format "dm=%%[fx:abs(minima-0.5)>abs(maxima)?minima:maxima]" ^
  info:`) do set %%L

echo dm=%dm%

for /F "usebackq" %%L in (`%IM%identify ^
  -format "dm=%%[fx:100*(%dm%>0.5?1-%dm%:%dm%)]" ^
  xc:`) do set %%L

echo dm=%dm%

for /F "usebackq" %%L in (`%IM%identify ^
  -format "dmo=%%[fx:100-%dm%]" ^
  xc:`) do set %%L

echo dmo=%dmo%

%IM%convert ^
  %INFILE% ^
  -level %dm%,%dmo%%% ^
  %OUTFILE%


call echoRestore

endlocal & set almOUTFILE=%OUTFILE%&

All images on this page were created by the commands shown, using:

%IM%identify -version
Version: ImageMagick 6.9.5-3 Q16 x86 2016-07-22 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2015 ImageMagick Studio LLC
License: http://www.imagemagick.org/script/license.php
Visual C++: 180040629
Features: Cipher DPC Modules OpenMP 
Delegates (built-in): bzlib cairo flif 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 slopes.h1. To re-create this web page, run "procH1 slopes".


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 31-October-2016.

Page created 17-Nov-2016 19:04:01.

Copyright © 2016 Alan Gibson.