CITE THIS NOTEBOOK: Difference map generative art by George Varnavides. Wolfram Community FEB 3 2023.
I find I keep coming back to this application https://community.wolfram.com/groups/-/m/t/2135869 every time I learn of a new optimization technique!
This time, it’s projection onto (non-)convex sets, e.g. the “difference map” algorithm which was previously used to solve Sudoku puzzles (which is of-course another problem amenable to Linear Programming). A slightly longer walk-through of the projections I used can be found here.
Hope you find watching the algorithm trying to climb out of a local minimum as mesmerizing as I do!
This time, it’s projection onto (non-)convex sets, e.g. the “difference map” algorithm which was previously used to solve Sudoku puzzles (which is of-course another problem amenable to Linear Programming). A slightly longer walk-through of the projections I used can be found here.
Hope you find watching the algorithm trying to climb out of a local minimum as mesmerizing as I do!
Target Image
Target Image
In[]:=
Show[Image[obama=ImageData@ColorConvert[ImageResize[ImageCrop[ImageCrop[Import["https://upload.wikimedia.org/wikipedia/en/5/55/Barack_Obama_Hope_poster.jpg"],{225,235},Bottom],{225,225},Top],30],"Grayscale"]],ImageSize->300]
Out[]=
In[]:=
GraphicsRow[{Show[Image[obama],ImageSize->300],Show[createPict[tileDataGrayscale,arrayToKeepGS//Last],ImageSize300],Show[createPict[tileDataSmith,arrayToKeep//Last],ImageSize300]},ImageSize->900]
Out[]=
Dark Tiles
Dark Tiles
In[]:=
{darkCol,backgroundCol,lightCol}={Black,Gray,White};tileDataGrayscale=mkDarkTiles[backgroundCol,{darkCol,lightCol}];tileValuesGrayscale=First/@ColorConvert[tileDataGrayscale["tileColorValue"],"Grayscale"];tileDataGrayscale["allTilesImg"]
Out[]=
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
In[]:=
linearProgrammingSolution=partitionSolve[tileDataGrayscale,Image[obama],30];Show[createPict[tileDataGrayscale,linearProgrammingSolution],ImageSize300]
Out[]=
In[]:=
arrayGS=ConstantArray[N[RandomInteger[{0,1},Append[Dimensions[obama],Length[tileDataGrayscale["allTilesImg"]]]]],3];bestTilingErrorGS=100.;arrayToKeepGS={blockProjection[arrayGS//Mean].Range[Length[tileDataGrayscale["allTilesImg"]]]};
In[]:=
Do[arrayGS=differenceMapIteration[0.05][tileDataGrayscale["topologyH"],tileDataGrayscale["topologyV"],obama][0.125,tileValuesGrayscale][arrayGS];meanArrayGS=arrayGS//Mean;horizontalCostGS=horizontalTilingCost[tileDataGrayscale][meanArrayGS]*100;verticalCostGS=verticalTilingCost[tileDataGrayscale][meanArrayGS]*100;pixelValuesCostGS=pixelCost[obama,tileValuesGrayscale][meanArrayGS]*100;If[Mean[{horizontalCostGS,verticalCostGS}]<bestTilingErrorGS,bestTilingErrorGS=Mean[{horizontalCostGS,verticalCostGS}];bestArrayGS=meanArrayGS;];If[Mod[i,20]==0,AppendTo[arrayToKeepGS,blockProjection[meanArrayGS].Range[Length[tileDataGrayscale["allTilesImg"]]]]];errorGS=StringTemplate["Best Tiling Cost: `4` %-- Current Horizontal Tiling Cost: `1` %-- Current Vertical Tiling Cost: `2` %-- Current Pixel Values Cost: `3` %"][horizontalCostGS,verticalCostGS,pixelValuesCostGS,bestTilingErrorGS];,{i,10000}]
In[]:=
(*Dynamic[errorGS]*)
(*Dynamic[visualizeArray[tileDataGrayscale]/@{bestArrayGS,meanArrayGS}]*)
In[]:=
arrayToKeepGS=Import["dark-tiles_obama30x30_rrr05.mx"];
In[]:=
Export["dark-tiles_obama30x30_rrr05.mx",arrayToKeepGS]
Out[]=
dark-tiles_obama30x30_rrr05.mx
In[]:=
framesGS=Show[createPict[tileDataGrayscale,#],ImageSize300]&/@arrayToKeepGS;
In[]:=
Export["dark-tiles_obama30x30_rrr05.gif",framesGS]
Out[]=
dark-tiles_obama30x30_rrr05.gif
In[]:=
Iconize[arrayGS,"dark-tiles_obama30x30_rrr05_final-array"]
Out[]=
Smith Tiles
Smith Tiles
In[]:=
tileDataSmith=mkSmithTiles[{Black,Gray,White}];tileValuesSmith=First/@ColorConvert[tileDataSmith["tileColorValue"],"Grayscale"];tileDataSmith["allTilesImg"]
Out[]=
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
In[]:=
linearProgrammingSolutionSmith=partitionSolve[tileDataSmith,Image[obama],30];Show[createPict[tileDataSmith,linearProgrammingSolutionSmith],ImageSize300]
Out[]=
Tiling Initialization Functions
Tiling Initialization Functions
Projection Initialization Functions
Projection Initialization Functions