I'm having problems converting an image to polar coordinates. In Photoshop it's easy :) so this is new territory for me.
I've the following image:
and it should end up looking like this:
I've had a look here and I've got the basics, but still a bit confused with squaring the circle:
import math
from PIL import Image, ImageDraw
# image size
imgX = 200
imgY = 200
image = Image.new("RGB", (imgX, imgY))
draw = ImageDraw.Draw(image)
#fill with white first
colour = "#ffffff"
box = [0,0, imgX, imgY]
image.paste(colour, box)
# draw line near base
draw.line((0,180, 200, 180), fill="#FF0000", width=2)
print "Line done!"
image.save("line.png", "PNG")
# there's got to be a way to get the current image
# without having to open it up again
im = Image.open("line.png")
rgb_im = im.convert("RGB")
# rectangle to polar coordinates
maxradius = math.sqrt(imgX**2 + imgY**2)/2
rscale = imgX / maxradius
tscale = imgY / (2*math.pi)
for y in range(0, imgY):
dy = y - imgY/2
for x in range(0, imgX):
dx = x - imgX/2
t = math.atan2(dy,dx)%(2*math.pi)
r = math.sqrt(dx**2+dy**2)
r, g, b = rgb_im.getpixel((x, y))
# this is where it goes wrong
col = b * 65536 + g * 256 + r
image.putpixel((x, y), b * 65536 + g * 256 + r
image.save("polar.png", "PNG")
I'm nearly there only a bit confused as to how to redraw the image. And a caveat: due to administrative restrictions I want to avoid using external libraries like Numpy.
The following code worked for me. Main changes:
Created separate variables for the line_image
and the circle_image
. There is no reason to reload the image, you can just reuse the line_image
...
The t
and r
will give you the image coordinates that you want to access in the line image for each corresponding x
and y
in the circle image. They were there already, you just had to effectively use them as indices to fetch the pixel colors.
Applied the rscale
and tscale
to r
and t
, so that 2×pi corresponds to the right edge of the image. You definitely need to change this scale of r
to be able to see this circle in the output, either that or drawing the line way up closer to the top (e.g. at line 100 instead of 180).
I also included a boundary check for the line image access.
```
import math
from PIL import Image, ImageDraw
# image size
imgX = 200
imgY = 200
line_image = Image.new("RGB", (imgX, imgY))
draw = ImageDraw.Draw(line_image)
#fill with white first
colour = "#ffffff"
box = [0,0, imgX, imgY]
line_image.paste(colour, box)
# draw line near base
draw.line((0,180, 200, 180), fill="#FF0000", width=2)
print "Line done!"
line_image.save("line.png", "PNG")
circle_image = Image.new("RGB", (imgX, imgY))
# rectangle to polar coordinates
maxradius = math.sqrt(imgX**2 + imgY**2)/2
rscale = imgX / maxradius
tscale = imgY / (2*math.pi)
for y in range(0, imgY):
dy = y - imgY/2
for x in range(0, imgX):
dx = x - imgX/2
t = math.atan2(dy,dx)%(2*math.pi)*tscale
r = math.sqrt(dx**2+dy**2)*rscale
if 0<= t < imgX and 0 <= r < imgY:
r, g, b = line_image.getpixel((t, r))
# this is where it goes wrong
col = b * 65536 + g * 256 + r
circle_image.putpixel((x, y), col)
circle_image.save("polar.png", "PNG")
```