Reputation: 2082
I want to scale some images and i want to set the pixels count to some spesific number. For example, if there is an image with width=400px height=100
I can scale it by 0.5 to set the resolution 10000px
But the code below may produce some new_width*new_height values like 9999 or 10001 some other width and height values. Total number of pixels must be 10000.
import os
import cv2
TOTAL_PIXEL_NUMBER = 10000
path = 'path/to/images/folder'
for img in os.listdir(path):
try:
img_array = cv2.imread(os.path.join(path,img), cv2.IMREAD_GRAYSCALE)
height, width = img_array.shape
aspect_ratio = width/height
new_height = np.sqrt(TOTAL_PIXEL_NUMBER/aspect_ratio)
new_width = new_height * aspect_ratio
new_array = cv2.resize(img_array, (new_width,new_height))
data.append(new_array)
except Exceptinon as e:
print(e)
I want to keep the ratio same to not distort the images. But it is not mandatory to stay 'exactly' the same. For example if the original ratio is 0.35 it can be 0.36 or 0.34 in resized image to make the number of total pixels 10000. But how can i pick the optimal ratio to make the resolution constant? Or if there is some opencv function to do that it would be great.
Upvotes: 0
Views: 200
Reputation: 80325
Make a list of ratios including values (10000/1, 5000/2, etc)
[10000, 2500, 625, 400, 156.25, 100, 39.065, 25, 16, 6.25, 4, 1.5625, 1...0.0001]
or ready-to use tuples with ratio, width and height:
[(10000, 10000, 1), (2500, 5000, 2), (625, 2500, 4) ...]
and inverses of the first part of this list.
For given ratio w/h find the closest value from the list and use corresponding width and height to make resulting rectangle.
For example, you have 300x200
image with ratio 1.5
. The best value is 1.5625
, so result rectangle is 125x80
and scale coefficients are 125/300
and 80/200
l = []
for i in range(1, 10001):
if (10000 % i == 0):
w = i
h = 10000 // i
r = w / h
l.append((r, w, h))
ww, hh = 1920, 1080
rr = ww / hh
mn = 100000
for i in range(len(l)):
cmn = max(rr / l[i][0], l[i][0] / rr)
if (cmn < mn):
bestidx = i
mn = cmn
new_width = l[bestidx][1]
new_height = l[bestidx][2]
Upvotes: 2
Reputation: 3421
you can use the fx and fy parameters to set this.
#creating ratio
rate=1/np.sqrt(height*width/10000)
new_array = cv2.resize(img_array, (0,0), fx=rate, fy=rate)
#this will resize the image to 10000 pixels in 3 channels.
Upvotes: 1