Part 3-2
This article is about “A Guide to ‘Fractal-Based’ Image Compression and Function Approximation” found at http://links.uwaterloo.ca/papers/waterloo/vr95.pdf. It is meant as a study aid to be read in parallel with the article. Python stuff is in bold.
I am going to talk about the one different IFSM in each part. The IFSM functions can be found in the library HGF.py which can be found here: http://paste.pocoo.org/show/556565/.
“Over the centuries the difference between representation and symbol tends to fade away. Once a meaning is established, the pictures we draw can become so stretched and distorted that their originators would barely recognize them. What begins as a representation, a crude picture, becomes stylized and abstracted until—as in the elaborate Chinese and Japanese ideographs called kanji—no more than a hint of the original image remains. But as long as we can distinguish one image from another, the meanings can be preserved.” - George Johnson, Fire in the Mind
The first thing that I thought that I would explore was the rotation and reflection functions. Not because the article said as much but because this might be the pathway to the elusive superfractal (that’s right, the mother of all fractals).
Remember the physics demonstration where there was glycerin in a flask and the demonstrator puts colored die in and then winds it up and winds it back (Laminar Flow http://www.youtube.com/watch?v=p08_KlTKP50). I was going to wind this image up into a fractal and just unwind it back into the image. When I looked at my eight tranformation functions it was obvious that there were only two functions rotation and reflection and that all I needed was a IFSM that could pass the angle to the function. The only extra number that I had was the gray value so naturally I wrote an IFSM that passes the gray value with the x and y coordinates. The graymaps made with this new IFSM showed some interesting structures but the hole function that I was using at the time just returned a zero and after repeated iterations zeros overtook the image. I decided that I needed a different hole function. Long story short I tried all kinds of stuff and finally settled on a function that just switches the real and imaginary parts of a complex number. To me it is a type of residual value, an invariant measure.
Lets take a look at the IFSM.
Some imports,
import Image, ImageDraw
import math,random,itertools
from HGF import *
some functions,
def imgtouxm(fname):
img = Image.open(file(fname,’rb’))
img = img .resize((512,512))
img = img .convert(‘L’)
imgdata = img.getdata()
uxm = zip(*[iter( imgdata )]*img.size[0])
return uxm
def imggray(gray,fname):
im = Image.new(‘L’,(len(gray[int(len(gray)/2)]),len(gray)))
for c,i in enumerate(gray):
for k,l in enumerate(i):
if l == None:
l= 0
elif l> 255:
l = 255
elif l < 0:
l = 0.
im.putpixel((k,c),int(l))
im.save(file(fname,’wb’))
def rotation(z):
x,y,Th = z[0],z[1],z[2]
Th = Th.real*360.
x_prime = x* math.cos(Th) - y * math.sin(Th)
y_prime = x* math.sin(Th) + y * math.cos(Th)
return (x_prime*0.21 +.5,y_prime*0.21 + .5,z[2])
def reflection(z):
x,y,Th = z[0],z[1],z[2]
Th = Th.real*360.
x_prime = x* math.cos(Th)*2 + y * math.sin(Th)*2
y_prime = x* math.sin(Th)*2 - y * math.cos(Th)*2
return (x_prime*.21 + .5, y_prime*.21 +.5, z[2])
thetavalsadd = [0.3 for i in range(8)]
thetavals = [.5 for i in range(8)]
def Idxy1(x):
return x*thetavals[0] + thetavalsadd[0]
def Idxy2(x):
return x*thetavals[1]+ thetavalsadd[1]
def Idxy3(x):
return x*thetavals[2] +thetavalsadd[2]
def Idxy4(x):
return x*thetavals[3] +thetavalsadd[3]
def Idxy5(x):
return x*thetavals[4]+ thetavalsadd[4]
def Idxy6(x):
return x*thetavals[5] +thetavalsadd[5]
def Idxy7(x):
return x*thetavals[6]+ thetavalsadd[6]
def Idxy8(x):
return x*thetavals[7]+thetavalsadd[7]
the IFSmapping.
fnlist = [rotation, reflection]
Idxlist = [Idxy1,Idxy2,Idxy3,Idxy4,
Idxy5,Idxy6,Idxy7,Idxy8]
uxmlena = imgtouxm(‘lena.png’)
uxmlena = [[complex(float(di)/255.,float(di)/255.) for di in j] for j in uxmlena ]
fsm = IFSmapping(fnlist,[(0.,0.,0.),(0.,0.,1.),(0.,1.,1.),
(0.,1.,0.),(1.,0.,0.),(1.,0.,1.),(1.,1.,1.),(1.,1.,0.)])
A look at the graymap.
for i in range(40):
func,theta,gray = IFSM3d(uxmlena ,fsm,Idxlist)
testreal = [[int(float(di.real)*255.) for di in j] for j in gray ]
testimag = [[int(float(di.imag)*255.) for di in j] for j in gray ]
imggray( testreal ,’testrotref’ + str(i) +’.png’)
imggray( testimag ,’testrotrefI’ + str(i) +’.png’)
uxmlena = gray
One time.
Real.

Imaginary.

Five times.
Real.

Imaginary.

Twenty times.
Real.

Imaginary.

Forty times.
Real.

Imaginary.

I really don’t know what the squares are. I think that they are visual representations of Banach’s Contraction Mapping Theorem of the outer edge of the picture that because of the theta values are Contraction maps.
So now that I have my glycerin flask I’m just going to unwind it.
some translation functions
def unrotation(z):
x,y,Th = z[0],z[1],z[2]
Th = -Th.real*360.
x_prime = x* math.cos(Th) - y * math.sin(Th)
y_prime = x* math.sin(Th) + y * math.cos(Th)
return (x_prime*0.21 +.5,y_prime*0.21 + .5,z[2])
def unreflection(z):
x,y,Th = z[0],z[1],z[2]
Th = -Th.real*360.
x_prime = x* math.cos(Th)*2 + y * math.sin(Th)*2
y_prime = x* math.sin(Th)*2 - y * math.cos(Th)*2
return (x_prime*.21 + .5, y_prime*.21 +.5, z[2])
A function to look at the fractal.
def fractimg(finalimg,fsm):
klist = [[j.next() for j in i] for i in fsm.IFSlist]
for j in klist:
for k in j:
x,y,pt = int(k[0].real*512),int(k[1].real*512),abs(k[2])*255
if x < 0:
x = 0
if y < 0:
y = 0
if x > 511:
x=511
if y > 511:
y=511
if pt > 255:
pt = 255
finalimg[y][x] = (finalimg[y][x] + pt)/2.
return finalimg
Make a list compatible with the translation functions.
newlist = []
for cy,i in enumerate(uxmlena):
for cx,j in enumerate(i):
newlist.append((float(cx)/len(i),float(cy)/len(uxmlena),abs(j)))
Our IFSmapping.
fsm = IFSmapping([unrotation,unreflection],newlist)
An empty uxm.
finalimg = [[0 for i in range(512)] for j in range(512)]
and fill it up.
finalimg = fractimg(finalimg,fsm)
imggray(finalimg,’testfinalimgA.bmp’)

finalimg = fractimg(finalimg,fsm)
imggray(finalimg,’testfinalimgB.bmp’)

And just for fun here’s Lena.
First pass.

second pass

Neither of these look like Lena.
What if I iterated the image through the process that I outlined in part 3-1. An interesting thing happens during the first pass.
fnlist = [rotation, reflection]
Idxlist = [Idxy1,Idxy2,Idxy3,Idxy4,
Idxy5,Idxy6,Idxy7,Idxy8]
uxmlena = imgtouxm(‘lena.png’)
uxmlena = [[complex(float(di)/255.,float(di)/255.) for di in j] for j in uxmlena ]
fsm = IFSmapping(fnlist,[(0.,0.,0.),(0.,0.,1.),(0.,1.,1.),
(0.,1.,0.),(1.,0.,0.),(1.,0.,1.),(1.,1.,1.),(1.,1.,0.)])
for i in range(7):
func,theta,gray = IFSM3d(uxmlena ,fsm,Idxlist)
testreal = [[int(float(di.real)*255.) for di in j] for j in gray ]
testimag = [[int(float(di.imag)*255.) for di in j] for j in gray ]
imggray( testreal ,’testgray’ + str(i) +’.png’)
imggray( testimag ,’testgrayI’ + str(i) +’.png’)
newmat = [[sum([Fct(Ui) for Fct in Fi]) + Ui for Ui,Fi in zip(U,F)] for U,F in zip( uxmlena ,theta)]
diffmat = [[Ni-Gi for Gi,Ni in zip(G,N)] for G,N in zip(gray,newmat)]
divmat = [[ Di /len( Fi ) for Fi , Di in zip(F,D)] for F,D in zip(func, diffmat )]
testreal = [[int(float(di.real)*255.) for di in j] for j in divmat ]
testimag = [[int(float(di.imag)*255.) for di in j] for j in divmat ]
imggray( testreal ,’testlena’ + str(i) +’.png’)
imggray( testimag ,’testlenaI’ + str(i) +’.png’)
uxmlena = divmat
First gray real.

First gray Imaginary.

First divmat real.

First divmat imaginary.

Last gray real.

last gray Imaginary.

Last divmat real.

Last divmat imaginary.

Those concentric rings reminded me of deplictions of electron clouds. Go back and look at the first IFSM from the article (x*.6 + .4, x* .6) and notice how much it is like the double slit experiment.
I’m going to look at the fractal.
newlist = []
for cy,i in enumerate(uxmlena):
for cx,j in enumerate(i):
newlist.append((float(cx)/len(i),float(cy)/len(uxmlena),abs(j)))
finalimg = [[0 for i in range(512)] for j in range(512)]
fsm = IFSmapping([unrotation,unreflection],newlist)
finalimg = fractimg(finalimg,fsm)
imggray(finalimg,’testfinalimgA.bmp’)

finalimg = fractimg(finalimg,fsm)
imggray(finalimg,’testfinalimgB.bmp’)

How about the last graymap.
newlist = []
for cy,i in enumerate(gray):
for cx,j in enumerate(i):
newlist.append((float(cx)/len(i),float(cy)/len(uxmlena),abs(j)))
finalimg = [[0 for i in range(512)] for j in range(512)]
fsm = IFSmapping([unrotation,unreflection],newlist)
finalimg = fractimg(finalimg,fsm)
imggray(finalimg,testfinalimgC.bmp’)

finalimg = fractimg(finalimg,fsm)
imggray(finalimg,’testfinalimgD.bmp’)

Those don’t look like Lena either.
The Laminar flow theory of derfractalization was turning out to be a bust.
I was going to try one more thing.
def rotation(z):
x,y,Th = z[0],z[1],z[2]
Th = Th.real*360.
x_prime = x* math.cos(Th) - y * math.sin(Th)
y_prime = x* math.sin(Th) + y * math.cos(Th)
return (x_prime*0.21 +.5,y_prime*0.21 + .5,z[2])
def reflection(z):
x,y,Th = z[0],z[1],z[2]
Th = Th.real*360.
x_prime = x* math.cos(Th)*2 + y * math.sin(Th)*2
y_prime = x* math.sin(Th)*2 - y * math.cos(Th)*2
return (x_prime*.21 + .5, y_prime*.21 +.5, z[2])
def rotation2(z):
x,y,Th = z[0],z[1],z[2]
Th = Th.real*360.
x_prime = x* math.cos(Th) - y * math.sin(Th)
y_prime = x* math.sin(Th) + y * math.cos(Th)
return (x_prime*0.21 + .5,y_prime*0.105 + .25,z[2])
def reflection2(z):
x,y,Th = z[0],z[1],z[2]
Th = Th.real*360.
x_prime = x* math.cos(Th)*2 + y * math.sin(Th)*2
y_prime = x* math.sin(Th)*2 - y * math.cos(Th)*2
return (x_prime*.21+.5, y_prime*0.105+ .25, z[2])
def rotation3(z):
x,y,Th = z[0],z[1],z[2]
Th = Th.real*360.
x_prime = x* math.cos(Th) - y * math.sin(Th)
y_prime = x* math.sin(Th) + y * math.cos(Th)
return (x_prime*0.21+.5,y_prime*0.105 + .75,z[2])
def reflection3(z):
x,y,Th = z[0],z[1],z[2]
Th = Th.real*360.
x_prime = x* math.cos(Th)*2 + y * math.sin(Th)*2
y_prime = x* math.sin(Th)*2 - y * math.cos(Th)*2
return (x_prime*0.21+.5,y_prime*0.105 + .75,z[2])
def rotation4(z):
x,y,Th = z[0],z[1],z[2]
Th = Th.real*360.
x_prime = x* math.cos(Th) - y * math.sin(Th)
y_prime = x* math.sin(Th) + y * math.cos(Th)
return (x_prime*0.105+.25,y_prime*0.21+.5,z[2])
def reflection4(z):
x,y,Th = z[0],z[1],z[2]
Th = Th.real*360.
x_prime = x* math.cos(Th)*2 + y * math.sin(Th)*2
y_prime = x* math.sin(Th)*2 - y * math.cos(Th)*2
return (x_prime*0.105+.25,y_prime*0.21+.5,z[2])
def rotation5(z):
x,y,Th = z[0],z[1],z[2]
Th = Th.real*360.
x_prime = x* math.cos(Th) - y * math.sin(Th)
y_prime = x* math.sin(Th) + y * math.cos(Th)
return (x_prime*0.105 +.75,y_prime*0.21 +.5,z[2])
def reflection5(z):
x,y,Th = z[0],z[1],z[2]
Th = Th.real*360.
x_prime = x* math.cos(Th)*2 + y * math.sin(Th)*2
y_prime = x* math.sin(Th)*2 - y * math.cos(Th)*2
return (x_prime*0.105 +.75,y_prime*0.21 +.5,z[2])
fnlist = [rotation,rotation2,rotation3,rotation4
,rotation5,reflection,reflection2,reflection3
,reflection4,reflection5]
Idxlist = [Idxy1,Idxy2,Idxy3,Idxy4,
Idxy5,Idxy6,Idxy7,Idxy8,Idxy1,Idxy1]
uxmlena = imgtouxm(‘c:\python27\tom\lena.png’)
uxmlena = [[complex(float(di)/255.,float(di)/255.) for di in j] for j in uxmlena ]
fsm = IFSmapping(fnlist,[(0.,0.,0.),(0.,0.,1.),(0.,1.,1.), (0.,1.,0.),
(1.,0.,0.),(1.,0.,1.),(1.,1.,1.),(1.,1.,0.)])
for i in range(7):
func,theta,gray = IFSM3d(uxmlena ,fsm,Idxlist)
testreal = [[int(float(di.real)*255.) for di in j] for j in gray ]
testimag = [[int(float(di.imag)*255.) for di in j] for j in gray ]
imggray( testreal ,’testgray’ + str(i) +’.png’)
imggray( testimag ,’testgrayI’ + str(i) +’.png’)
newmat = [[sum([Fct(Ui) for Fct in Fi]) + Ui for Ui,Fi in zip(U,F)] for U,F in zip( uxmlena ,theta)]
diffmat = [[Ni-Gi for Gi,Ni in zip(G,N)] for G,N in zip(gray,newmat)]
divmat = [[ Di /len( Fi ) for Fi , Di in zip(F,D)] for F,D in zip(func, diffmat )]
testreal = [[int(float(di.real)*255.) for di in j] for j in divmat ]
testimag = [[int(float(di.imag)*255.) for di in j] for j in divmat ]
imggray( testreal ,’testlena’ + str(i) +’.png’)
imggray( testimag ,’testlenaI’ + str(i) +’.png’)
uxmlena = divmat
First gray real.

First gray Imaginary.

First divmat real.

First divmat imaginary.

Last gray real.

last gray Imaginary.

Last divmat real.

Last divmat imaginary.

I’m going to look at the fractal.
Functions first.
def unrotation(z):
x,y,Th = z[0],z[1],z[2]
Th = -Th.real*360.
x_prime = x* math.cos(Th) - y * math.sin(Th)
y_prime = x* math.sin(Th) + y * math.cos(Th)
return (x_prime*0.21 +.5,y_prime*0.21 + .5,z[2])
def unreflection(z):
x,y,Th = z[0],z[1],z[2]
Th = -Th.real*360.
x_prime = x* math.cos(Th)*2 + y * math.sin(Th)*2
y_prime = x* math.sin(Th)*2 - y * math.cos(Th)*2
return (x_prime*.21 + .5, y_prime*.21 +.5, z[2])
def unrotation2(z):
x,y,Th = z[0],z[1],z[2]
Th = -Th.real*360.
x_prime = x* math.cos(Th) - y * math.sin(Th)
y_prime = x* math.sin(Th) + y * math.cos(Th)
return (x_prime*0.21 + .5,y_prime*0.105 + .25,z[2])
def unreflection2(z):
x,y,Th = z[0],z[1],z[2]
Th = -Th.real*360.
x_prime = x* math.cos(Th)*2 + y * math.sin(Th)*2
y_prime = x* math.sin(Th)*2 - y * math.cos(Th)*2
return (x_prime*.21+.5, y_prime*0.105+ .25, z[2])
def unrotation3(z):
x,y,Th = z[0],z[1],z[2]
Th = -Th.real*360.
x_prime = x* math.cos(Th) - y * math.sin(Th)
y_prime = x* math.sin(Th) + y * math.cos(Th)
return (x_prime*0.21+.5,y_prime*0.105 + .75,z[2])
def unreflection3(z):
x,y,Th = z[0],z[1],z[2]
Th = -Th.real*360.
x_prime = x* math.cos(Th)*2 + y * math.sin(Th)*2
y_prime = x* math.sin(Th)*2 - y * math.cos(Th)*2
return (x_prime*0.21+.5,y_prime*0.105 + .75,z[2])
def unrotation4(z):
x,y,Th = z[0],z[1],z[2]
Th = -Th.real*360.
x_prime = x* math.cos(Th) - y * math.sin(Th)
y_prime = x* math.sin(Th) + y * math.cos(Th)
return (x_prime*0.105+.25,y_prime*0.21+.5,z[2])
def unreflection4(z):
x,y,Th = z[0],z[1],z[2]
Th = -Th.real*360.
x_prime = x* math.cos(Th)*2 + y * math.sin(Th)*2
y_prime = x* math.sin(Th)*2 - y * math.cos(Th)*2
return (x_prime*0.105+.25,y_prime*0.21+.5,z[2])
def unrotation5(z):
x,y,Th = z[0],z[1],z[2]
Th = -Th.real*360.
x_prime = x* math.cos(Th) - y * math.sin(Th)
y_prime = x* math.sin(Th) + y * math.cos(Th)
return (x_prime*0.105 +.75,y_prime*0.21 +.5,z[2])
def unreflection5(z):
x,y,Th = z[0],z[1],z[2]
Th = -Th.real*360.
x_prime = x* math.cos(Th)*2 + y * math.sin(Th)*2
y_prime = x* math.sin(Th)*2 - y * math.cos(Th)*2
return (x_prime*0.105 +.75,y_prime*0.21 +.5,z[2])
newlist = []
for cy,i in enumerate(uxmlena):
for cx,j in enumerate(i):
newlist.append((float(cx)/len(i),float(cy)/len(uxmlena),abs(j)))
finalimg = [[0 for i in range(512)] for j in range(512)]
fsm = IFSmapping([unrotation,unrotation2,unrotation3,unrotation4,
unrotation5,unreflection,unreflection2,unreflection3,
unreflection4,unreflection5],newlist)
finalimg = fractimg(finalimg,fsm)
imggray(finalimg,’c:\python27\tom\testfinalimg32A.bmp’)

finalimg = fractimg(finalimg,fsm)
imggray(finalimg,’c:\python27\tom\testfinalimg32B.bmp’)

This graymap IFSmapping causes a memory error on my system so you’ll have to do it yourself.
This looks very familiar to nuclear physics images but still no Lena.
I like the process, the process is golden but the tranformation functions are just not taking me to where I want to go. I decided I would go back to the article and do those affine transformations.
some functions and process.
def scrunch1(z):
x,y,Th = z[0],z[1],z[2]
x = x* .5 + .5
y = y
return (x,y,z[2])
def scrunch2(z):
x,y,Th = z[0],z[1],z[2]
x = x * .5
y = y
return (x,y,z[2])
def scrunch3(z):
x,y,Th = z[0],z[1],z[2]
x = x
y = y * .5 + .5
return (x,y,z[2])
def scrunch4(z):
x,y,Th = z[0],z[1],z[2]
x = x
y = y * .5
return (x,y,z[2])
def scrunch5(z):
x,y,Th = z[0],z[1],z[2]
x = x * .5
y = y * .5
return (x,y,z[2])
def scrunch6(z):
x,y,Th = z[0],z[1],z[2]
x = x * .5 + .5
y = y * .5 + .5
return (x,y,z[2])
def scrunch7(z):
x,y,Th = z[0],z[1],z[2]
x = x * .5 + .5
y = y * .5
return (x,y,z[2])
def scrunch8(z):
x,y,Th = z[0],z[1],z[2]
x = x * .5
y = y * .5 + .5
return (x,y,z[2])
thetavalsadd = [0.3 for i in range(8)]
thetavals = [.5 for i in range(8)]
def Idxy1(x):
return x*thetavals[0] + thetavalsadd[0]
def Idxy2(x):
return x*thetavals[1]+ thetavalsadd[1]
def Idxy3(x):
return x*thetavals[2] +thetavalsadd[2]
def Idxy4(x):
return x*thetavals[3] +thetavalsadd[3]
def Idxy5(x):
return x*thetavals[4]+ thetavalsadd[4]
def Idxy6(x):
return x*thetavals[5] +thetavalsadd[5]
def Idxy7(x):
return x*thetavals[6]+ thetavalsadd[6]
def Idxy8(x):
return x*thetavals[7]+thetavalsadd[7]
fnlist = [scrunch1,scrunch2,scrunch3,scrunch4,
scrunch5,scrunch6,scrunch7,scrunch8]
Idxlist = [Idxy1,Idxy2,Idxy3,Idxy4,
Idxy5,Idxy6,Idxy7,Idxy8]
uxmlena = imgtouxm(‘lena.png’)
uxmlena = [[complex(float(di)/255.,float(di)/255.) for di in j] for j in uxmlena ]
fsm = IFSmapping(fnlist,[(0.,0.,0.),(0.,0.,1.),(0.,1.,1.),
(0.,1.,0.),(1.,0.,0.),(1.,0.,1.),(1.,1.,1.),(1.,1.,0.)])
for i in range(13):
func,theta,gray = IFSM3d(uxmlena ,fsm,Idxlist)
newmat = [[sum([Fct(Ui) for Fct in Fi]) + Ui for Ui,Fi in zip(U,F)] for U,F in zip( uxmlena ,theta)]
diffmat = [[Ni-Gi for Gi,Ni in zip(G,N)] for G,N in zip(gray,newmat)]
divmat = [[ Di /len( Fi ) for Fi , Di in zip(F,D)] for F,D in zip(func, diffmat )]
testreal = [[int(float(di.real)*255.) for di in j] for j in divmat ]
testimag = [[int(float(di.imag)*255.) for di in j] for j in divmat ]
imggray( testreal ,’testlena’ + str(i) +’.png’)
imggray( testimag ,’testlenaI’ + str(i) +’.png’)
uxmlena = divmat
testlena 0

testlena 3

testlena 8

testlena 12

Now that looks more like a fractal.
I’m going to try an unscrunch
def unscrunch1(z):
x,y,Th = z[0],z[1],z[2]
x = x/ .5 - .5
y = y
return (x,y,z[2])
def unscrunch2(z):
x,y,Th = z[0],z[1],z[2]
x = x / .5
y = y
return (x,y,z[2])
def unscrunch3(z):
x,y,Th = z[0],z[1],z[2]
x = x
y = y / .5 - .5
return (x,y,z[2])
def unscrunch4(z):
x,y,Th = z[0],z[1],z[2]
x = x
y = y / .5
return (x,y,z[2])
def unscrunch5(z):
x,y,Th = z[0],z[1],z[2]
x = x / .5
y = y / .5
return (x,y,z[2])
def unscrunch6(z):
x,y,Th = z[0],z[1],z[2]
x = x/ .5 - .5
y = y / .5 - .5
return (x,y,z[2])
def unscrunch7(z):
x,y,Th = z[0],z[1],z[2]
x = x / .5 - .5
y = y / .5
return (x,y,z[2])
def unscrunch8(z):
x,y,Th = z[0],z[1],z[2]
x = x / .5
y = y / .5 - .5
return (x,y,z[2])
A new fractal viewer.
def fractimg(finalimg,fsm):
klist = [[j.next() for j in i] for i in fsm.IFSlist]
for j in klist:
for k in j:
x,y,pt = int(k[0].real*512)+756,int(k[1].real*512)+756,k[2]*355 - 100
if x < 0:
x = 0
if y < 0:
y = 0
if x > 2047:
x=2047
if y > 2047:
y=2047
if pt > 255:
pt = 255
finalimg[y][x] = pt
return finalimg
newlist = []
for cy,i in enumerate(uxmlena):
for cx,j in enumerate(i):
newlist.append((float(cx)/len(i),float(cy)/len(uxmlena),j.real))
finalimg = [[0. for i in range(2056)] for j in range(2056)]
fsm = IFSmapping([unscrunch1,unscrunch2,unscrunch3,unscrunch4,
unscrunch5,unscrunch6,unscrunch7,unscrunch8],newlist)
finalimg = fractimg(finalimg,fsm)
imggray(finalimg,’c:\python27\tom\testfinalimgscrunchA.bmp’)

finalimg = fractimg(finalimg,fsm)
imggray(finalimg,’c:\python27\tom\testfinalimgscrunchB.bmp’)

newlist = []
for cy,i in enumerate(uxmlena):
for cx,j in enumerate(i):
newlist.append((float(cx)/len(i),float(cy)/len(uxmlena),j.imag))
finalimg = [[255. for i in range(2056)] for j in range(2056)]
fsm = IFSmapping([unscrunch1,unscrunch2,unscrunch3,unscrunch4,
unscrunch5,unscrunch6,unscrunch7,unscrunch8],newlist) finalimg = fractimg(finalimg,fsm) imggray(finalimg,testfinalimgscrunchA.bmp’)
finalimg = fractimg(finalimg,fsm)
imggray(finalimg,’testfinalimgscrunchB.bmp’)

Hard to see but it is a fractal. Now we’ll do that tiling thing with the new fractal maker.
A new fractaling function for the 16 x 16 tiles
def fractimg(finalimg,fsm):
klist = [[j.next() for j in i] for i in fsm.IFSlist]
for j in klist:
for k in j:
x,y,pt = int(k[0].real*len(finalimg[0])),int(k[1].real*len(finalimg)),abs(k[2])#+(len(finalimg[0])/2)
if x < 0:
x = 0
if y < 0:
y = 0
if x >= len(finalimg[0]):
x=len(finalimg[0])-1
if y >= len(finalimg):
y=len(finalimg)-1
finalimg[y][x] = pt
return finalimg
prepare the blocks.
Idxlist = [Idxy1,Idxy2,Idxy3,Idxy4,
Idxy5,Idxy6,Idxy7,Idxy8]
lena = Image.open(file(‘c:\python27\tom\lena.png’,’rb’))
lena = lena.convert(‘L’)
Parent_block = [[(i+k,j+l) for k,l in itertools.product(range(16),range(16))] for i,j in itertools.product(range(0,lena.size[0],16),range(0,lena.size[1],16))]
child_block = []
for i in Parent_block:
child_block.append( [i[:int(len(i)/4)],i[int(len(i)/4):int(len(i)/2)],i[int(len(i)/2):int(len(i)/2)+int(len(i)/4)],i[int(len(i)/2)+int(len(i)/4):]])
A function for the process.
def nwefunc(uxm,fsm,Idxlist):
func,theta,gray = IFSM3d(uxm ,fsm,Idxlist)
newmat = [[sum([Fct(Ui) for Fct in Fi]) + Ui for Ui,Fi in zip(U,F)] for U,F in zip( uxmlena ,theta)]
diffmat = [[Ni-Gi for Gi,Ni in zip(G,N)] for G,N in zip(gray,newmat)]
divmat = [[ Di /len( Fi ) for Fi , Di in zip(F,D)] for F,D in zip(func, diffmat )]
return divmat
A list to put the little fractals in.
IDlist = []
Go through the Parent Blocks make a fractal and put it in the list.
for ct in range(len(Parent_block)):
uxm = map(lena.getpixel,Parent_block[ct])
uxm = zip(*[iter(uxm)]*16)
fnlist = [scrunch1,scrunch2,scrunch3,scrunch4,
scrunch5,scrunch6,scrunch7,scrunch8]
fsm = IFSmapping(fnlist,[(0.,0.,0.),(0.,0.,1.),(0.,1.,1.),(0.,1.,0.),(1.,0.,0.),(1.,0.,1.),(1.,1.,1.),(1.,1.,0.)])
newgray = nwefunc(uxm,fsm,Idxlist)
for i in range(9):
newgray = nwefunc(newgray,fsm,Idxlist)
IDlist.append(newgray)
A list for each little image that has been unscrunched.
finalimglist = []
finalimglist2 = []
fnlist = [unscrunch1,unscrunch2,unscrunch3,unscrunch4,unscrunch5,unscrunch6,unscrunch7,unscrunch8]
Go through the little fractal list, unscrunch and put the small images into the appropriate list.
for count,hh in enumerate(IDlist):
newlist = []
for cy,i in enumerate(hh):
for cx,j in enumerate(i):
newlist.append((float(cx.real)/len(i),float(cy.real)/len(uxm3r),j))
finalimg = [[0. for i in range(16)] for j in range(16)]
fsmu = IFSmapping(fnlist,newlist)
fsm = IFSmapping([FnCx],newlist)
finalimg = fractimg(finalimg,fsm)
finalimglist.append(finalimg)
finalimg2 = [[random.uniform(.25,.35) for i in range(32)] for j in range(32)]
finalimg2 = fractimg(finalimg2,fsmu)
finalimglist2.append(finalimg2)
make a new image and paste the tiles into it.
newImage = Image.new(‘L’,(lena.size[0],lena.size[1]),255)
Parent_block = [[(i+k,j+l) for k,l in itertools.product(range(16),range(16))] for i,j in itertools.product(range(0,newImage.size[0],16),range(0,newImage.size[1],16))]
for ii,j in zip(finalimglist,Parent_block):
im = Image.new(‘L’,(len(ii[int(len(ii)/2)]),len(ii)))
for c,i in enumerate(ii):
for k,l in enumerate(i):
if l == None:
l= 0
im.putpixel((c,k),int(l.real*255))
newImage.paste(im,j[0])
newImage.save(file(‘lenabigger.bmp’,’wb’))

newImage = Image.new(‘L’,(lena.size[0]*2,lena.size[1]*2),255)
Parent_block = [[(i+k,j+l) for k,l in itertools.product(range(32),range(32))] for i,j in itertools.product(range(0,newImage.size[0],32),range(0,newImage.size[1],32))]
for ii,j in zip(finalimglist2,Parent_block):
im = Image.new(‘L’,(len(ii[int(len(ii)/2)]),len(ii)))
draw = ImageDraw.Draw(im)
for c,i in zip(range(len(ii)),ii):
for k,l in zip(range(len(i)),i):
if l == None:
l= 0
draw.rectangle((c,k,c+4,k+4),fill = int(l.real*255)+int(l.imag*255))
newImage.paste(im,j[0])
newImage.save(file(‘c:\python27\tom\lenabigger2.bmp’,’wb’))

Not very visually apealing but I do feel that I have achieved a decent collage. In the next part I am going to try to use that collage to produce a formula for the image.
Comming soon part 3-3
The golden path.

So it has come to this. An ignorant, ill informed giggle wrapped in a chuckle and stuffed with monkey business in an all out battle royal against the greatest intelectual minds of our time, or not.
Consider this mess.
scrunchfactor = .24
scrunchadd = complex(.01,.01)
def scrunchandjulia1(z):
x,y,j = z[0].real,z[0].imag,z[1]
x = x* .5 + .5
y = y
x_p = z[0]*scrunchfactor + scrunchadd
Th = (j+x_p)/2.
try:
Th = Th**2 + complex(0,Th.imag)
except OverflowError:
Th = 1.
return (complex(x,y),Th)
def scrunchandjulia2(z):
x,y,j = z[0].real,z[0].imag,z[1]
x = x * .5
y = y
x_p = z[0]*scrunchfactor + scrunchadd
Th = (j+x_p)/2.
try:
Th = Th**2 + complex(0,Th.imag)
except OverflowError:
Th = 1.
return (complex(x,y),Th)
def scrunchandjulia3(z):
x,y,j = z[0].real,z[0].imag,z[1]
x = x
y = y * .5 + .5
x_p = z[0]*scrunchfactor + scrunchadd
Th = (j+x_p)/2.
try:
Th = Th**2 + complex(0,Th.imag)
except OverflowError:
Th = 1.
return (complex(x,y),Th)
def scrunchandjulia4(z):
x,y,j = z[0].real,z[0].imag,z[1]
x = x
y = y * .5
x_p = z[0]*scrunchfactor + scrunchadd
Th = (j+x_p)/2.
try:
Th = Th**2 + complex(0,Th.imag)
except OverflowError:
Th = 1.
return (complex(x,y),Th)
def scrunchandjulia5(z):
x,y,j = z[0].real,z[0].imag,z[1]
x = x * .5
y = y * .5
x_p = z[0]*scrunchfactor + scrunchadd
Th = (j+x_p)/2.
try:
Th = Th**2 + complex(0,Th.imag)
except OverflowError:
Th = 1.
return (complex(x,y),Th)
def scrunchandjulia6(z):
x,y,j = z[0].real,z[0].imag,z[1]
x = x * .5 + .5
y = y * .5 + .5
x_p = z[0]*scrunchfactor + scrunchadd
Th = (j+x_p)/2.
try:
Th = Th**2 + complex(0,Th.imag)
except OverflowError:
Th = 1.
return (complex(x,y),Th)
def scrunchandjulia7(z):
x,y,j = z[0].real,z[0].imag,z[1]
x = x * .5 + .5
y = y * .5
x_p = z[0]*scrunchfactor + scrunchadd
Th = (j+x_p)/2.
try:
Th = Th**2 + complex(0,Th.imag)
except OverflowError:
Th = 1.
return (complex(x,y),Th)
def scrunchandjulia8(z):
x,y,j = z[0].real,z[0].imag,z[1]
x = x * .5
y = y * .5 + .5
x_p = z[0]*scrunchfactor + scrunchadd
Th = (j+x_p)/2.
try:
Th = Th**2 + complex(0,Th.imag)
except OverflowError:
Th = 1.
return (complex(x,y),Th)
def fnCX1(j):
try:
return j**2 + complex(0,j.imag)
except OverflowError:
return 1.




































