What does keras.preprocessing.image.load_img do during image resizing?
In the following statement, target size is set to 128x128.
image1 = img_to_array(image.load_img(img, target_size=(128,128))) / 255
What if I load 100x100 size image?
Will it leave the image as it is or will it zoom to 128x128 size?
It will actually resize it to the target size!
If the image size is smaller than the target size it will be stretched to fit the desired size.
Related
I've got some tasks about classification and Object ROI.
So I got images and labels like class and x1,y2,x2,y2 (standard box)
But images are different in sizes, is there some solution to get box coordinates after resizing?
So what i mean - i got image 300 px H and 400 px W and box coordinates (x1,y1,x2,y2). Before train my Dl model - i have to resize all images to the same W and H, for example I choose 200*200, so is there some solution to calculate new box coordinates x1new_after_resizing, y1new_after_resizing, x2new_after_resizing,y2new_after_resizing?
And are there some tips about what H and H to choose for resizing? Mean of all images? Median?
Thanks!
If you want to get new coordinates from image size of orig_width and orig_height to new_width and new_height, you can use scale the box coordinates in the following way
width_scaled = new_width/orig_width
height_scaled = new_height/orig_height
x1_new = x1*width_scaled
y1_new = y1*height_scaled
x2_new = x2*width_scaled
y2_new = y2*height_scaled
You can plot these coordinates on the new image and check if you would like
There is no fixed method on how to choose the dimension of resizing images. It depends on various factors like the network, the GPU memory you have, batch size, and the shape of the smallest/largest image in the dataset. Ideally, it should not be too small/stretched out such that the images are incomprehensible or extremely stretched out
You can refer to this post to get an idea of image resizing
I have about 1000 images in a cvs file. I have already managed to put those images in my Python programm by doing the following:
df = pd.read_csv("./Testes_small.csv")
# Creates the dataframe
training_set = pd.DataFrame({'Images': training_imgs,'Labels': training_labels})
train_dataGen = ImageDataGenerator(rescale=1./255)
train_generator = train_dataGen.flow_from_dataframe(dataframe = training_set, directory="",
x_col="Images", y_col="Labels",
class_mode="categorical",
target_size=(224, 224),batch_size=32)
##Steps to plot the images
imgs,labels = next(train_generator)
for i in range(batch_size): # range de 0 a 31
image = imgs[i]
plt.imshow(image)
plt.show()
So now I have the train_generator variable of type python.keras.preprocessing.image.DataframeIterator Its size is (32,224,224,3).
In the function ImageDataGenerator I want to put my own preprocessing function to resize the images. I want to do this because I have some rectangular images that when resized lose its ratio.
Per examples these images before(upper image) and after(the lower one) resizing:
Clearly the secong image loses shape
I found this function(it's the answer to a previous thread):
def resize_image(self, image: Image, length: int) -> Image:
"""
Resize an image to a square. Can make an image bigger to make it fit or smaller if it doesn't fit. It also crops
part of the image.
:param self:
:param image: Image to resize.
:param length: Width and height of the output image.
:return: Return the resized image.
"""
"""
Resizing strategy :
1) We resize the smallest side to the desired dimension (e.g. 1080)
2) We crop the other side so as to make it fit with the same length as the smallest side (e.g. 1080)
"""
if image.size[0] < image.size[1]:
# The image is in portrait mode. Height is bigger than width.
# This makes the width fit the LENGTH in pixels while conserving the ration.
resized_image = image.resize((length, int(image.size[1] * (length / image.size[0]))))
# Amount of pixel to lose in total on the height of the image.
required_loss = (resized_image.size[1] - length)
# Crop the height of the image so as to keep the center part.
resized_image = resized_image.crop(
box=(0, required_loss / 2, length, resized_image.size[1] - required_loss / 2))
# We now have a length*length pixels image.
return resized_image
else:
# This image is in landscape mode or already squared. The width is bigger than the heihgt.
# This makes the height fit the LENGTH in pixels while conserving the ration.
resized_image = image.resize((int(image.size[0] * (length / image.size[1])), length))
# Amount of pixel to lose in total on the width of the image.
required_loss = resized_image.size[0] - length
# Crop the width of the image so as to keep 1080 pixels of the center part.
resized_image = resized_image.crop(
box=(required_loss / 2, 0, resized_image.size[0] - required_loss / 2, length))
# We now have a length*length pixels image.
return resized_image
I'm trying to insert it like this img_datagen = ImageDataGenerator(rescale=1./255, preprocessing_function = resize_image but it doesn't work because I'm not giving an im. Do you have any ideas on how can I do this?
Check the documentation for providing custom functions to the ImageDataGenerator. It says and quote,
"preprocessing_function: function that will be applied on each input. The function will run after the image is resized and augmented. The function should take one argument: one image (Numpy tensor with rank 3), and should output a Numpy tensor with the same shape."
From the above documentation we can note the following:
When will this function be executed:
after resizing image.
after any data augmentation which has to be done.
Function argument requirements:
only one argument.
this argument is for only one numpy image.
the image should be numpy tensor of rank 3
Function output requirements:
one output image.
should be same shape as input
This last point is really important for your question. Since your function is resizing the image it's output will not be the same shape as input and so you cannot do this directly.
One alternative to get this done is to do your resizing of dataset before passing to ImageDataGenerator.
I have this original image of size 800 x 600px
What I have to do is to resize the image to 625 x 480px and filter all the land areas. I have found that the BGR values of the land part is (95,155,212). This is the code I used to filter all the and areas:
image[np.where((image == [95,155,212]).all(axis = 2))] = [0,0,0]
If I resize first, then filter, here is the output:
If I filter first then resize, I get my desired output:
So my first question is what happened to the image's pixels when it is resized?
I have this original image of size 712 x 480px
When I applied filtering to remove the land area, I get an output like the second image from the top. 2nd question, is there any way for me to fix this problem?
most likely the resizing changes the border colors to something between land color and black outline.
This screws up your filter because you need higher ranges for land color and also the border line color (Black) can have color artifacts. These artifact are what is left after filtering in your example. If you pick their colors they should be outside your selected range.
How to repair?
use nearest neighbor resizing
this will left the colors as are but the resized image is not as pretty ...
change filters to handle close colors not just range of color
so change to something like flood fill and fill all pixels that do not differ too much from each other. You need 2 thresholds for this:
absolute (is the color range total big one)
relative (is the max change of neighboring pixels small one)
now just recolor the resized image or change the filter function to this ...
Image sizes onscreen and in print
The size of an image when you view it onscreen is different from its size when you print it. If you understand these differences, you can develop a better understanding of which settings to change when you resize an image.
Screen size
The screen resolution of your monitor is the number of pixels it can display. For example, a monitor with a screen resolution of 640 x 480 pixels displays 640 pixels for the width and 480 pixels for the height. There are several different screen resolutions you can use, and the physical size of the monitor screen usually determines the resolutions available. For example, large monitors typically display higher resolutions than small monitors because they have more pixels.
Image size onscreen
Images are of a fixed pixel size when they appear on your monitor. Your screen resolution determines how large the image appears onscreen. A monitor set to 640 x 480 pixels displays fewer pixels than a monitor displaying 1024 x 768 pixels. Therefore, each of the pixel on the 640 x 480 pixel monitor is larger than each pixel displayed on the 1024 x 768 pixel monitor.
A 100 x 100-pixel image uses about one-sixth of the screen at 640 x 480, but it takes up only about one-tenth of the screen at 1024 x 768. Therefore, the image looks smaller at 1024 x 768 pixels than at 640 x 480 pixels
The Following Parameters change when you resize an image
Pixel dimensions: The width and height of the image.
Image size :
Document size: Physical size of the image when printed, including a width and height.
Image resolution when printed: This value appears in pixels per inch or pixels per centimeter.
In Photoshop the physical size, resolution, and pixel dimensions of an image are calculated as follows:
Physical size = resolution x pixel dimensions
Resolution = physical size / pixel dimensions
Pixel dimensions = physical size / resolution
For more info on this you can check Adobe's Document on Image resizing
I am very new in Python and this is going to be a very basic question.I have a website which is image based and i am developing it using Django.Now i want to resize the image or you can say i want to minimize the size of the images.There are different size of images are avaible,some images are largest in width,some images are largest in height and i want to resize images without changing there shape.
Here are some example what dimensions images are using in my website.
Here the First image is largest in width and the second image is largest in height and they are really big in Dimension.so they need to be resized or rather these images are need to be minimized in size.So i have used the PIL as below.
from PIL import Image,ImageDraw, ImageFont, ImageEnhance
def image_resize(request,image_id):
photo = Photo.objects.get(pk=image_id)
img = Image.open(photo.photo.file)
image = img.resize((1000, 560), Image.ANTIALIAS)
image.save()
so this function returns all the images with width of 1000 and height of 560.But i don't want to resize all the images with same width and height,rather i want to resize each images maintaining there own shape. That is there shape will be same but the images will be resized.How can i do this? i am really new in python.
Do you want to have all images with same width 1000? Try this code. It will resize to at most 1000 as width (if the image's width is less than 1000, nothing changes)
def image_resize(request,image_id):
photo = Photo.objects.get(pk=image_id)
image = Image.open(photo.photo.file)
(w,h) = image.size
if (w > 1000):
h = int(h * 1000. / w)
w = 1000
image = image.resize((w, h), Image.ANTIALIAS)
image.save()
I recall doing this sometime back without any problem except that I used thumbnail method rather than resize. Try it. You need not assign img to image. You can process img and save the same.
# open img
img.thumbnail((1000,560), Image.ANTIALIAS)
# save img
I need to find a way to re-size an input raster image (such as jpg) to a specified width/height resolution (given in pixels). It would be great if PyQt while resizing a new image would keep an original image's aspect ratio (so there is no stretching but scaling only).
src = '/Users/usrName/Images/originalImage.jpg' (2048x1024) (rectangular image 2:1 ratio)
dest= '/Users/usrName/Images/originalImage_thumb.jpg' (64x64) (output image is square 1:1 ratio).
Thanks in advance!
POSTED RESULTED FUNC:
...could be used to resize and to convert an image to any format QT supports so far... such as: 'bmp', 'gif', 'jpg', 'jpeg', 'png', 'pbm', 'tiff', 'svg', 'xbm'
def resizeImageWithQT(src, dest):
pixmap = QtGui.QPixmap(src)
pixmap_resized = pixmap.scaled(720, 405, QtCore.Qt.KeepAspectRatio)
if not os.path.exists(os.path.dirname(dest)): os.makedirs(os.path.dirname(dest))
pixmap_resized.save(dest)
Create a pixmap:
pixmap = QtGui.QPixmap(path)
and then use QPixmap.scaledToWidth or QPixmap.scaledToHeight:
pixmap2 = pixmap.scaledToWidth(64)
pixmap3 = pixmap.scaledToHeight(64)
With a 2048x1024 image, the first method would result in an image that is 64x32, whilst the second would be 128x64. Obviously it is impossible to resize a 2048x1024 image to 64x64 whilst keeping the same aspect ratio (because the ratios are different).
To avoid choosing between width or height, you can use QPixmap.scaled:
pixmap4 = pixmap.scaled(64, 64, QtCore.Qt.KeepAspectRatio)
which will automatically adjust to the largest size possible.
To resize the image to an exact size, do:
pixmap5 = pixmap.scaled(64, 64)
Of course, in this case, the resulting image won't keep the same aspect ratio, unless the original image was also 1:1.