Here is one result :
CODE START
#################################################
PImage img;
// Global constant for maximum depth of the quadtree
final int MAX_DEPTH = 10; // You can adjust this value as needed
//#####################################################################
// you can use trigonometric RGB colors using this formula :
// k is a random RGB color channel
// sc is the sin or cos trigonometric functions
// t_scale is the scale parameter that will change the values from [-1,1]->[-127.5,127.5]
// t_shift is the shift parameter that will change the values from [-127.5,127.5]->[0,255]
// t_scale=127.5;
// t_shift=127.5;
// int((sc(k)*t_scale)+t_shift);
//#####################################################################
void setup() {
size(1000,1000);
background(242-140,239-140,213-140);
smooth(8);
img = loadImage("Images/SQ10.png"); // Load your image
img.resize(width, height); // Resize to fit the canvas
noLoop();
}
void draw() {
drawQuadTree(0, 0, width, height, 0);
save("OUT/Frame10.png");
}
void drawQuadTree(float x, float y, float w, float h, int depth) {
int variation;
float r,g,b;
//float k;
ellipseMode(CENTER);
strokeCap(SQUARE);
if (shouldSubdivide(x, y, w, h, depth)) {
float halfWidth = w / 2;
float halfHeight = h / 2;
// Recursively subdivide the quadrant
drawQuadTree(x, y, halfWidth, halfHeight, depth + 1);
drawQuadTree(x + halfWidth, y, halfWidth, halfHeight, depth + 1);
drawQuadTree(x, y + halfHeight, halfWidth, halfHeight, depth + 1);
drawQuadTree(x + halfWidth, y + halfHeight, halfWidth, halfHeight, depth + 1);
} else {
// Draw the quadrant with its average color
//color avgColor = getAverageBrightnessColor(x, y, w, h);
//k=int(map(avgColor,0,255,0,255));
//color avgColor2 = getAverageColor(x, y, w, h);
r=getRedAverageColor(x, y, w, h);
g=getGreenAverageColor(x, y, w, h);
b=getBlueAverageColor(x, y, w, h);
variation=int(random(1,4));
switch(variation){
case 1:
//k=random(-PI/2,PI/2+1);
fill((r*0.9)%256,(g*0.85)%256,(b*0.8)%256);
//fill(r%256,g%256,b%256);
noStroke();
ellipse(x+w/2, y+h/2, w, h);
break;
case 2:
noStroke();
//fill((r*0.9)%256,(g*0.85)%256,(b*0.8)%256);
fill(r%256,g%256,b%256);
triangle(x+w/2,y,x,y+h,x+w,y+h);
break;
case 3:
noStroke();
//fill((r*0.9)%256,(g*0.85)%256,(b*0.8)%256);
fill(r%256,g%256,b%256);
triangle(x,y,x+w/2,y+h,x+w,y);
break;
}
}
}
boolean shouldSubdivide(float x, float y, float w, float h, int depth) {
float varianceThreshold = 600.0; // Adjust this threshold as needed
float variance = calculateColorVariance(x, y, w, h);
return variance > varianceThreshold && depth < MAX_DEPTH;
}
color getAverageColor(float x, float y, float w, float h) {
float totalR = 0, totalG = 0, totalB = 0;
int count = 0;
// Iterate over the pixels in the quadrant
for (int i = int(x); i < x + w; i++) {
for (int j = int(y); j < y + h; j++) {
// Get the color of the pixel
color c = img.get(i, j);
totalR += red(c);
totalG += green(c);
totalB += blue(c);
count++;
}
}
// Calculate the average color
float avgR = totalR / count;
float avgG = totalG / count;
float avgB = totalB / count;
// Return the average color
return color(avgR, avgG, avgB);
}
float getRedAverageColor(float x, float y, float w, float h) {
float totalR = 0;
int count = 0;
// Iterate over the pixels in the quadrant
for (int i = int(x); i < x + w; i++) {
for (int j = int(y); j < y + h; j++) {
// Get the color of the pixel
color c = img.get(i, j);
totalR += red(c);
count++;
}
}
// Calculate the average color
float avgR = totalR / count;
// Return the average color
return avgR;
}
float getGreenAverageColor(float x, float y, float w, float h) {
float totalG = 0;
int count = 0;
// Iterate over the pixels in the quadrant
for (int i = int(x); i < x + w; i++) {
for (int j = int(y); j < y + h; j++) {
// Get the color of the pixel
color c = img.get(i, j);
totalG += green(c);
count++;
}
}
// Calculate the average color
float avgG = totalG / count;
// Return the average color
return avgG;
}
float getBlueAverageColor(float x, float y, float w, float h) {
float totalB = 0;
int count = 0;
// Iterate over the pixels in the quadrant
for (int i = int(x); i < x + w; i++) {
for (int j = int(y); j < y + h; j++) {
// Get the color of the pixel
color c = img.get(i, j);
totalB += blue(c);
count++;
}
}
// Calculate the average color
float avgB = totalB / count;
// Return the average color
return avgB;
}
color getAverageBrightnessColor(float x, float y, float w, float h) {
float totalBrightness = 0;
int count = 0;
// Iterate over the pixels in the quadrant
for (int i = int(x); i < x + w; i++) {
for (int j = int(y); j < y + h; j++) {
// Get the color of the pixel
color c = img.get(i, j);
totalBrightness += brightness(c);
count++;
}
}
// Calculate the average brightness
float avgBrightness = totalBrightness / count;
// Return a color with the average brightness
// Assuming a grayscale color, where R, G, B are all equal to the brightness value
return color(avgBrightness);
}
float calculateColorVariance(float x, float y, float w, float h) {
float avgR = 0, avgG = 0, avgB = 0;
int count = 0;
for (int i = int(x); i < x + w; i++) {
for (int j = int(y); j < y + h; j++) {
color c = img.get(i, j);
avgR += red(c);
avgG += green(c);
avgB += blue(c);
count++;
}
}
// Calculate average color
avgR /= count;
avgG /= count;
avgB /= count;
float variance = 0;
// Calculate variance
for (int i = int(x); i < x + w; i++) {
for (int j = int(y); j < y + h; j++) {
color c = img.get(i, j);
variance += sq(red(c) - avgR) + sq(green(c) - avgG) + sq(blue(c) - avgB);
}
}
return variance / count;
}
#################################################
CODE END