Reputation: 49
This is more theory than anything, but let's suppose that I have 2 images of the same object that were taken at different, but known, distances.
image_1, taken at distance_1 (further away, say 2 meters) image_2, taken at distance_2 (closer, say 1 meter)
If I want to digitally 'zoom' into the image_1, is this as simple as cropping distance_2/distance_1 pixels from image_1?
Below is my code trying to attempt a center digital zoom.
from PIL import Image
img = Image.open('example.jpg')
w, h = img.size
x = w // 2
y = h // 2
zoom2 = distance_2/distance_1
img = img.crop((x - w / zoom2, y - h / zoom2, x + w / zoom2, y + h / zoom2))
img.resize((w, h), Image.LANCZOS)
d = img.resize((w,h), resample=Image.BOX)
Main Question: Am I correctly choosing the 'zoom' factor by comparing the relationship of the distances?
Thank you for any help!
Related: PIL zoom into image at a particular point Python upscale image without blur PIL
Upvotes: 0
Views: 54
Reputation: 49
After the helpful advice of the above, here is what I was able to come up with:
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
img = Image.open('level.jpg') #open the image that you want to zoom into
img_save = img
w, h = img.size
distance = 2 # in this case this image will be zoomed in by 10
distance2 = 1
zm=distance/distance2 #should be bigger than 1 to make it work
wn = w // zm # this is the *new size* of the image after being zoomed in
hn = h // zm
widthStart = (w - wn) // 2
heightStart = (h - hn) // 2
widthEnd = widthStart + wn
heightEnd = heightStart + hn
img = img.crop((widthStart, heightStart, widthEnd, heightEnd))
img = img.resize((w, h), Image.LANCZOS)
plt.imshow(np.array(img))
plt.show()
plt.imshow(np.array(img_save))
plt.show()
Upvotes: 0
Reputation: 360
img = img.crop((x - w / zoom2, y - h / zoom2, x + w / zoom2, y + h / zoom2))
this part can raise problems since it uses orignal width as a summation (and extraction) causing a possible shift in center
For example if you have 2x zoom to CENTER you need from 1/4 of x to 3/4 of x and same for y if you have 5x zoom to center you want 4/10 of x to 6/10 of x and same for y. ho it works? simply for 5x zoom you get center 2/10 and multiply by 5 makes it 10/10 aka full picture before digital zoom to center.
for talking zm
times center zoom
so your crop will be targetted on from (zm-1)/zm2 to (zm+1)/zm2 for each axis.
so you can
zm=distance/distance2 #should be bigger than 1 to make it work
startPoint=(zm-1)/zm*2
endPoint=(zm+1)/zm*2
widthStart=Image.w * startPoint
heightStart=Image.h * startPoint
widthEnd=Image.w * endPoint
heightEnd=Image.h * endPoint
img = img.crop((widthStart, heightStart, widthEnd, heightEnd))
Then just upscale your image with the lanczos as you did.
This calculation allows you get center zoom without moving center. And makes sure your zoom calculation works.
Upvotes: 1