J'utilise Python 3 et la dernière version d'openCV. J'essaie de redimensionner une image à l'aide de la fonction de redimensionnement fournie, mais après le redimensionnement, l'image est très déformée. Code:
import cv2
file = "/home/tanmay/Desktop/test_image.png"
img = cv2.imread(file , 0)
print(img.shape)
cv2.imshow('img' , img)
k = cv2.waitKey(0)
if k == 27:
cv2.destroyWindow('img')
resize_img = cv2.resize(img , (28 , 28))
cv2.imshow('img' , resize_img)
x = cv2.waitKey(0)
if x == 27:
cv2.destroyWindow('img')
L'image originale est de 480 x 640 (RVB donc j'ai passé le 0 pour le faire passer en niveaux de gris)
Existe-t-il un moyen de le redimensionner et d’éviter les distorsions avec OpenCV ou toute autre bibliothèque? J'ai l'intention de faire une reconnaissance manuscrite des chiffres et j'ai formé mon réseau de neurones en utilisant les données MNIST. J'ai donc besoin que l'image soit au format 28x28.
Vous pouvez essayer ci-dessous. La fonction conservera le taux d'aspect de l'image d'origine.
def image_resize(image, width = None, height = None, inter = cv2.INTER_AREA):
# initialize the dimensions of the image to be resized and
# grab the image size
dim = None
(h, w) = image.shape[:2]
# if both the width and height are None, then return the
# original image
if width is None and height is None:
return image
# check to see if the width is None
if width is None:
# calculate the ratio of the height and construct the
# dimensions
r = height / float(h)
dim = (int(w * r), height)
# otherwise, the height is None
else:
# calculate the ratio of the width and construct the
# dimensions
r = width / float(w)
dim = (width, int(h * r))
# resize the image
resized = cv2.resize(image, dim, interpolation = inter)
# return the resized image
return resized
Voici un exemple d'utilisation.
image = image_resize(image, height = 800)
J'espère que cela t'aides.
Essayez cette fonction simple en python qui utilise opencv. il suffit de passer l'image et de mentionner la taille du carré que vous voulez.
def get_square(image,square_size):
height,width=image.shape
if(height>width):
differ=height
else:
differ=width
differ+=4
mask = np.zeros((differ,differ), dtype="uint8")
x_pos=int((differ-width)/2)
y_pos=int((differ-height)/2)
mask[y_pos:y_pos+height,x_pos:x_pos+width]=image[0:height,0:width]
mask=cv2.resize(mask,(square_size,square_size),interpolation=cv2.INTER_AREA)
return mask
usage: squared_image = get_square (image, 28)
explication: function prend une entrée de toute taille et crée une image vierge de forme carrée de taille supérieure à la hauteur et à la largeur de l'image d'entrée . elle place ensuite l'image d'origine au centre de l'image vierge. et ensuite, il redimensionne cette image carrée à la taille souhaitée afin de préserver la forme du contenu de l'image d'origine.
J'espère que ceci vous aidera
J'ai un jeu de données de dessins à la main et j'avais besoin de créer de petites images carrées à partir de dessins asymétriques.
Merci à @vijay jha i créé images carrées tout en maintenant le rapport de format de l'image d'origine. Un problème cependant était que plus vous réduisiez, plus d’informations étaient perdues.
512x256 à 64x64 ressemblerait à ceci:
J'ai modifié un peu le code d'origine pour réduire progressivement l'image.
from skimage.transform import resize, pyramid_reduce
def get_square(image, square_size):
height, width = image.shape
if(height > width):
differ = height
else:
differ = width
differ += 4
# square filler
mask = np.zeros((differ, differ), dtype = "uint8")
x_pos = int((differ - width) / 2)
y_pos = int((differ - height) / 2)
# center image inside the square
mask[y_pos: y_pos + height, x_pos: x_pos + width] = image[0: height, 0: width]
# downscale if needed
if differ / square_size > 1:
mask = pyramid_reduce(mask, differ / square_size)
else:
mask = cv2.resize(mask, (square_size, square_size), interpolation = cv2.INTER_AREA)
return mask
512x256 -> 64x64
512x256 -> 28x28
La réponse fournie par @vijay jha est aussi spécifique à la casse. Comprend également un remplissage inutile supplémentaire. Je propose le code fixe ci-dessous:
def resize2SquareKeepingAspectRation(img, size, interpolation):
h, w = img.shape[:2]
c = None if len(img.shape) < 3 else img.shape[2]
if h == w: return cv2.resize(img, (size, size), interpolation)
if h > w: dif = h
else: dif = w
x_pos = int((dif - w)/2.)
y_pos = int((dif - h)/2.)
if c is None:
mask = np.zeros((dif, dif), dtype=img.dtype)
mask[y_pos:y_pos+h, x_pos:x_pos+w] = img[:h, :w]
else:
mask = np.zeros((dif, dif, c), dtype=img.dtype)
mask[y_pos:y_pos+h, x_pos:x_pos+w, :] = img[:h, :w, :]
return cv2.resize(mask, (size, size), interpolation)
Le code redimensionne une image en la rendant carrée et en conservant le rapport d'aspect en même temps. De plus, le code convient également aux images à 3 canaux (couleurs) . Exemple d'utilisation:
resized = resize2SquareKeepingAspectRation(img, size, cv2.INTER_AREA)
Si vous devez modifier la résolution de l’image et conserver votre rapport de format, utilisez la fonction imutils (consultez la documentation). quelque chose comme ça:
img = cv2.imread(file , 0)
img = imutils.resize(img, width=1280)
cv2.imshow('image' , img)
espérons que cela aide, bonne chance!
Le code reçoit un window_height
qui calcule la variable window_width
tout en maintenant les proportions de l'image. Afin d'éviter toute distorsion.
import cv2
def resize(self,image,window_height = 500):
aspect_ratio = float(image.shape[1])/float(image.shape[0])
window_width = window_height/aspect_ratio
image = cv2.resize(image, (int(window_height),int(window_width)))
return image
img = cv2.imread(img_source) #image location
img_resized = resize(img,window_height = 800)
cv2.imshow("Resized",img_resized)
cv2.waitKey(0)
cv2.destroyAllWindows()
La citation ne correspond peut-être pas à la question d'origine, mais j'ai atterri ici pour chercher une réponse à une question similaire.
import cv2
def resize_and_letter_box(image, rows, cols):
"""
Letter box (black bars) a color image (think pan & scan movie shown
on widescreen) if not same aspect ratio as specified rows and cols.
:param image: numpy.ndarray((image_rows, image_cols, channels), dtype=numpy.uint8)
:param rows: int rows of letter boxed image returned
:param cols: int cols of letter boxed image returned
:return: numpy.ndarray((rows, cols, channels), dtype=numpy.uint8)
"""
image_rows, image_cols = image.shape[:2]
row_ratio = rows / float(image_rows)
col_ratio = cols / float(image_cols)
ratio = min(row_ratio, col_ratio)
image_resized = cv2.resize(image, dsize=(0, 0), fx=ratio, fy=ratio)
letter_box = np.zeros((int(rows), int(cols), 3))
row_start = int((letter_box.shape[0] - image_resized.shape[0]) / 2)
col_start = int((letter_box.shape[1] - image_resized.shape[1]) / 2)
letter_box[row_start:row_start + image_resized.shape[0], col_start:col_start + image_resized.shape[1]] = image_resized
return letter_box
img = cv2.resize(img, (int(img.shape[1]/2), int(img.shape[0]/2)))
redimensionnera l'image à la moitié de la taille d'origine. Vous pouvez le modifier pour tout autre ratio . Notez que le premier argument transmis à resize () est img.shape [1] et non img.shape [0]. Cela peut être contre-intuitif. Il est facile d’ignorer ce retournement et d’obtenir une image très déformée.