... 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:
[[ 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 |
|
set STYL=starrynt_t.png |
Match histograms. This works on channels independently.
Match RGB histograms: call %PICTBAT%matchHisto %CONT% %STYL% sx_mh.png |
|
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= |
|
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= |
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 |
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 |
|
%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 |
How about partitioning an image:
For convenience, .bat scripts are also available in a single zip file. See Zipped BAT files.
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.