1
$\begingroup$

The following code is written by Luji.

uniqueColorQ[x1_, x2_, y1_, y2_] := 
  0.01 > Max@Abs@Variance@Flatten[data[[y1 ;; y2, x1 ;; x2]], 1];

circleData[width_, height_, color_] := 
 Table[If[(j - width/2)^2 + (i - height/2)^2 <= (Quotient[
       Min[height, width], 2])^2, color, {1, 1, 1}], {i, height}, {j, 
   width}]

normalizeColor[x1_, x2_, y1_, y2_] := 
 circleData[x2 - x1 + 1, y2 - y1 + 1, 
  Mean@Flatten[data[[y1 ;; y2, x1 ;; x2]], 1]]

blockMatrix[a11_, a12_, a21_, a22_] := 
 Join[Join[a11, a12, 2], Join[a21, a22, 2]] 
quadTreeArt[x1_, x2_, y1_, y2_] := 
 If[((x2 - x1) <= 1 || (y2 - y1) <= 1) || 
   uniqueColorQ[x1, x2, y1, y2], normalizeColor[x1, x2, y1, y2], 
  blockMatrix[
   quadTreeArt[x1, Quotient[x1 + x2, 2], y1, Quotient[y1 + y2, 2]], 
   quadTreeArt[Quotient[x1 + x2, 2] + 1, x2, y1, 
    Quotient[y1 + y2, 2]], 
   quadTreeArt[x1, Quotient[x1 + x2, 2], Quotient[y1 + y2, 2] + 1, 
    y2], quadTreeArt[Quotient[x1 + x2, 2] + 1, x2, 
    Quotient[y1 + y2, 2] + 1, y2]]]

image = Import["https://i.stack.imgur.com/GxCYF.jpg"];
img = ImageResize[image, {500, 420}];
data = ImageData[img][[1 ;; 420, 80 ;; 500]];
Image@quadTreeArt[1, 400, 1, 400]

apple

What other ingenious methods can be used to achieve this effect? quadtree apple

$\endgroup$
3
  • $\begingroup$ Code does not work for me on V12 Mac OS. "Image::imgarray: The specified argument {{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}, <<391>>, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}}, <<399>>} should be an array of rank 2 or 3 with machine-sized numbers." $\endgroup$ – Rohit Namjoshi Jan 30 '20 at 2:29
  • $\begingroup$ You need to manually replace the image in the question code with the image in the link. $\endgroup$ – A little mouse on the pampas Jan 30 '20 at 3:03
  • 1
    $\begingroup$ @PleaseCorrectGrammarMistakes just put the thing that calls image = Import[...] before the code that uses it and it'll all work fine $\endgroup$ – b3m2a1 Jan 30 '20 at 3:50
2
$\begingroup$

Not particularly efficient buy an easy to write recursion

ClearAll[splitMerge]
splitMerge[i_, maxSt_, minSize_, newImage_] :=
 ImageAssemble@Map[If[
     And[
      Max@ImageMeasurements[#, "StandardDeviation"] > maxSt,
      And @@ Thread[ImageDimensions[#] > minSize]
      ],
     splitMerge[ImagePartition[#, {Scaled[{1/2, 1/2}]}], maxSt, 
      minSize, newImage],
     newImage[#]
     ] &,
   i, {-1}]

Using these two functions to simplify the leaves

constantImage[i_] := 
 ImageAdd[ImageMultiply[i, 0], ImageMeasurements[i, "Mean"]]
diskImage[i_] := Block[
  {dims, mask},
  dims = ImageDimensions[i];
  mask = Image[DiskMatrix[Floor[Min[dims]/2], Reverse[dims]]];
  SetAlphaChannel[ImageMultiply[ColorConvert[
     mask,
     ImageColorSpace[i]
     ], ImageMeasurements[i, "Mean"]],
   mask
   ]
  ]

I get

splitMerge[ImageCrop[image, {400, 400}], .1, 20, constantImage]
splitMerge[ImageCrop[image, {400, 400}], .1, 10, diskImage]

decompositions

You can also try other types of matrices.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.