-
Notifications
You must be signed in to change notification settings - Fork 256
/
focal_blur.py
96 lines (73 loc) · 2.68 KB
/
focal_blur.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
from __future__ import print_function
from pymol import cmd
from tempfile import mkdtemp
from shutil import rmtree
from math import sin, cos, pi, sqrt
from PIL import Image
def FocalBlur(aperture=2.0, samples=10, ray=0, width=0, height=0):
'''
DESCRIPTION
Creates fancy figures by introducing a focal blur to the image. The object
at the origin will be in focus.
AUTHOR
Jarl Underhaug
University of Bergen
jarl_dot_underhaug_at_gmail_dot_com
Updates by Jason Vertrees and Thomas Holder
USAGE
FocalBlur aperture=float, samples=int, ray=0/1, width=int, height=int
EXAMPELS
FocalBlur aperture=1, samples=100
FocalBlur aperture=2, samples=100, ray=1, width=600, height=400
'''
# Formalize the parameter types
ray = (ray in ("True", "true", 1, "1"))
aperture, samples = float(aperture), int(samples)
width, height = int(width), int(height)
# Create a temporary directory
tmpdir = mkdtemp()
# Get the orientation of the protein and the light
light = cmd.get('light')[1:-1]
light = [float(s) for s in light.split(',')]
view = cmd.get_view()
# Rotate the protein and the light in order to create the blur
for frame in range(samples):
# Angles to rotate protein and light
# Populate angles as Fermat's spiral
theta = frame * pi * 110.0 / 144.0
radius = 0.5 * aperture * sqrt(frame / float(samples - 1))
x = cos(theta) * radius
y = sin(theta) * radius
xr = x / 180.0 * pi
yr = y / 180.0 * pi
# Rotate the protein
cmd.turn('x', x)
cmd.turn('y', y)
# Rotate the light
ly = light[1] * cos(xr) - light[2] * sin(xr)
lz = light[2] * cos(xr) + light[1] * sin(xr)
lx = light[0] * cos(yr) + lz * sin(yr)
lz = lz * cos(yr) - lx * sin(yr)
cmd.set('light', [lx, ly, lz])
curFile = "%s/frame-%04d.png" % (tmpdir, frame)
print("Created frame %i/%i (%0.0f%%)" % (frame + 1, samples, 100 * (frame + 1) / samples))
# Save the image to temporary directory
if ray:
cmd.ray(width, height)
cmd.png(curFile)
else:
cmd.png(curFile, quiet=1)
# Create the average/blured image
try:
avg = Image.blend(avg, Image.open(curFile), 1.0 / (frame + 1))
except:
avg = Image.open(curFile)
# Return the protein and the light to the original orientation
cmd.set('light', light)
cmd.set_view(view)
# Load the blured image
avg.save('%s/avg.png' % (tmpdir))
cmd.load('%s/avg.png' % (tmpdir))
# Delete the temporary files
rmtree(tmpdir)
cmd.extend('FocalBlur', FocalBlur)