snibgo's ImageMagick pages

Style transfer

... or making a photo look like a painting.

We make an output image that has content from one image and style from another image. This can be used to make a photograph look as if it had been painted in the style of an artist, or a particular painting, or whatever.

This raises the question: how do we define content and style? For the purpose of this page:

Some style-transfer methods operate in patches, so content elements from the style input are visible in the result, as if they have been cut-and-pasted. This page doesn't consider those methods.

The following are building-blocks for this page:

Sample images

[[ All work on this page is performed on full-size camera images, about 7500x5000 pixels. The results are shrunk and converted to JPG for this web page.

set WEB_SIZE=-resize 600x400

]]

set CONT=toes.png
toes.jpg
set STYL=starrynt_t.png
starrynt_t.pngjpg

Match histograms. This works on channels independently.

Match RGB histograms:

call %PICTBAT%matchHisto %CONT% %STYL% sx_mh.png
sx_mh.pngjpg

Match Lab histograms:

set mhCOL_SP_IN=-colorspace Lab -set colorspace sRGB
set mhCOL_SP_OUT=-set colorspace Lab -colorspace sRGB

call %PICTBAT%matchHisto %CONT% %STYL% sx_mh2.png

set mhCOL_SP_IN=
set mhCOL_SP_OUT=
sx_mh2.pngjpg

Match LCH histograms:

set mhCOL_SP_IN=-colorspace LCH -set colorspace sRGB
set mhCOL_SP_OUT=-set colorspace LCH -colorspace sRGB

call %PICTBAT%matchHisto %CONT% %STYL% sx_mh3.png

set mhCOL_SP_IN=
set mhCOL_SP_OUT=
sx_mh3.pngjpg

I like the LCH version best. However, it has a green colour that is not obvious on the Starry Night image.

(A transformation that copied the covariance matrix would be useful. Calculating the matrix is easy, but transferring it needs eigenvectors and eigenvalues, which need an external package, such as GMIC.)

(Cute if toes took the circular texture, and grass took buildings texture.)

Split the style image into base and detail. For diplay, we add 50% to the detail image so mid-gray is at zero.

goto skipgf
call %PICTBAT%guideFilt ^
  %STYL% in out ^
  . . 20x20 0.001

:skipgf
%IMG7%magick ^
  %STYL% ^
  ( +clone ^
    -selective-blur 0x10+10%% ^
    -write sx_sn_base.png ^
  ) ^
  -define compose:clamp=off ^
  -compose MinusSrc -composite ^
  +write sx_sn_det.miff ^
  -evaluate Add 50%% ^
  sx_sn_det_pl.png
sx_sn_base.pngjpg sx_sn_det_pl.pngjpg

Add the detail to sx_mh3.png:

%IMG7%magick ^
  sx_mh3.png ^
  sx_sn_det.miff ^
  -define compose:clamp=off ^
  -compose Add -composite ^
  sx_mh3_pl.png
sx_mh3_pl.pngjpg
%IMG7%magick ^
  sx_mh3.png ^
  ( sx_sn_det.miff -auto-level ^
    -evaluate Subtract 50%% ^
  ) ^
  -define compose:clamp=off ^
  -compose Add -composite ^
  -auto-level ^
  sx_mh3_pl2.png
sx_mh3_pl2.pngjpg

How about partitioning an image:

Scripts

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

alignGausPyr.bat

rem Find translation-only alignment of two Gaussian pyramids %1 and %2 with same structure.
rem Assumes %pyPREFIX% is the prefix of an appropriate blk.lis file.
@rem
@rem Optional:
@rem   %3 Factor for initial search window eg 0.66.
@rem
@rem Updated:
@rem   22-August-2022 Upgraded for IM v7.
@rem

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

@setlocal enabledelayedexpansion

@call echoOffSave

call %PICTBAT%setInOut %1 agp


set SRC1=%1
set SRC2=%2

set SRCH_WIND=%3
if "%SRCH_WIND%"=="." set SRCH_WIND=
if "%SRCH_WIND%"=="" set SRCH_WIND=0.6667


if "%pyPREFIX%"=="" (
  echo %0: pyPREFIX not set
  exit /B 1
)

for /F "tokens=*" %%L in (%pyPREFIX%blk.lis) do set %%L

if "%NUM_OCTAVES%"=="" (
  echo %0: NUM_OCTAVES not set in %pyPREFIX%blk.lis
  exit /B 1
)

set /A iOct=%NUM_OCTAVES%-1


for /F "usebackq" %%L in (`%IMG7%magick identify ^
  -format "SrchW=%%[fx:int(!N_BLK_W.%iOct%!*%SRCH_WIND%+0.5)]\nSrchH=%%[fx:int(!N_BLK_H.%iOct%!*%SRCH_WIND%+0.5)]" ^
  xc:`) do set %%L


rem Get dims multiplied by magic overlap factor for first search.

call %PICTBAT%alignBF ^
  %SRC1%[%iOct%] %SRC2%[%iOct%] ^
  !N_BLK_W.%iOct%! !N_BLK_H.%iOct%! -%SrchW% -%SrchH% %SrchW% %SrchH%

set DODGY=%abfDODGY%

call :ReadBlkLis


for /L %%i in (%iOct%,-1,1) do (

  echo %~n0: BESTX=!BESTX! BESTY=!BESTY!
  echo %~n0: N_BLK_W.%%i=!N_BLK_W.%%i!
  echo %~n0: N_BLK_H.%%i=!N_BLK_H.%%i!

  set /A PrevOct=%%i-1

  call :GetPrev %%i !PrevOct!

  echo %~n0: FirstX=!FirstX! FirstY=!FirstY! LastX=!LastX! LastY=!LastY!

  call %PICTBAT%alignBF ^
    %SRC1%[!PrevOct!] %SRC2%[!PrevOct!] ^
    !BW! !BH! !FirstX! !FirstY! !LastX! !LastY!

  if "!abfDODGY!"=="1" set DODGY=1

  call :ReadBlkLis
)

echo %~n0: COMP=%COMP% abfDATAFILE=%abfDATAFILE%

call echoRestore

@endlocal & set agpDATAFILE=%abfDATAFILE%& set agpDODGY=%DODGY%

exit /B 0

::---------------- Subroutines ----------------
:ReadBlkLis

  rem type %abfDATAFILE%

  for /F "tokens=1-9 delims=," %%A in (!abfDATAFILE!) do (
    set COMP=%%A
    set BESTX=%%B
    set BESTY=%%C
    set W=%%D
    set H=%%E
    set X1=%%F
    set Y1=%%G
    set X2=%%H
    set Y2=%%I
  )
  echo %~n0: !COMP! !X! !Y! X1=!X1! Y1=!Y1! X2=!X2! Y2=!Y2!

  exit /B

:GetPrev
  echo %~n0: N_BLK_W.%2=!N_BLK_W.%2!
  echo %~n0: N_BLK_H.%2=!N_BLK_H.%2!

  set /A BW=!N_BLK_W.%2!
  set /A BH=!N_BLK_H.%2!
  set /A FirstX=^(!BESTX!-1^)*!N_BLK_W.%2!/!N_BLK_W.%1!
  set /A FirstY=^(!BESTY!-1^)*!N_BLK_H.%2!/!N_BLK_H.%1!
  set /A LastX=^(!BESTX!+1^)*!N_BLK_W.%2!/!N_BLK_W.%1!
  set /A LastY=^(!BESTY!+1^)*!N_BLK_H.%2!/!N_BLK_H.%1!

  exit /B

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

%IMG7%magick -version
Version: ImageMagick 7.1.0-49 Q16-HDRI x64 7a3f3f1:20220924 https://imagemagick.org
Copyright: (C) 1999 ImageMagick Studio LLC
License: https://imagemagick.org/script/license.php
Features: Cipher DPC HDRI OpenCL 
Delegates (built-in): bzlib cairo freetype gslib heic jng jp2 jpeg jxl lcms lqr lzma openexr pangocairo png ps raqm raw rsvg tiff webp xml zip zlib
Compiler: Visual Studio 2022 (193331630)
%IM7DEV%magick -version
Version: ImageMagick 7.1.0-20 Q32-HDRI x86_64 2021-12-29 https://imagemagick.org
Copyright: (C) 1999-2021 ImageMagick Studio LLC
License: https://imagemagick.org/script/license.php
Features: Cipher DPC HDRI Modules OpenMP(4.5) 
Delegates (built-in): bzlib cairo fontconfig fpx freetype jbig jng jpeg lcms ltdl lzma pangocairo png raqm rsvg tiff webp wmf x xml zip zlib
Compiler: gcc (11.2)

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

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


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 2-December-2020.

Page created 13-Nov-2022 06:17:25.

Copyright © 2022 Alan Gibson.