Ich verwende Python 3 und die neueste Version von openCV. Ich versuche, die Größe eines Bildes mithilfe der Funktion zur Größenänderung zu ändern. Nach der Größenänderung ist das Bild jedoch sehr verzerrt. 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')
Das Originalbild ist 480 x 640 (RGB, daher habe ich die 0 übergeben, um Graustufenbilder zu erhalten).
Gibt es eine Möglichkeit, die Größe zu ändern und die Verzerrung mithilfe von OpenCV oder einer anderen Bibliothek möglicherweise zu vermeiden? Ich beabsichtige, einen handschriftlichen Ziffernerkenner anzufertigen, und ich habe mein neuronales Netzwerk mit den MNIST-Daten trainiert.
Sie können es unten versuchen. Die Funktion behält die Seitenrate des Originalbilds bei.
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
Hier ist eine Beispielanwendung.
image = image_resize(image, height = 800)
Hoffe das hilft.
Probieren Sie diese einfache Funktion in Python aus, die opencv verwendet. Übergeben Sie einfach das Bild und geben Sie die gewünschte Quadratgröße an.
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 (Bild, 28)
erklärung: Die Funktion nimmt eine beliebige Größe an und erzeugt ein quadratisches leeres Bild mit einer Größe, die größer als die Höhe und Breite des Eingabebildes ist. Sie legt das Originalbild in der Mitte des leeren Bildes ab. Anschließend wird dieses quadratische Bild in die gewünschte Größe gebracht, sodass die Form des ursprünglichen Bildinhalts erhalten bleibt.
hoffe, das wird dir helfen
Ich habe einen Datensatz von Handzeichnungen und ich musste kleine quadratische Bilder aus asymmetrischen Zeichnungen erstellen.
Dank @vijay jha habe ich square-Bilder erstellt und dabei das Seitenverhältnis des Originalbildes beibehalten. Ein Problem war jedoch, dass je mehr Sie herabgestuft wurden, desto mehr Informationen gingen verloren.
512x256 bis 64x64 würde folgendermaßen aussehen:
Ich habe den ursprünglichen Code ein wenig geändert, um das Bild reibungslos herunterzukalieren.
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
Die Antwort von @vijay jha ist zu fallspezifisch. Schließt auch zusätzliche unnötige Auffüllung ein. Ich schlage folgenden festen Code vor:
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)
Der Code ändert die Größe eines Bildes, um es quadratisch zu machen und gleichzeitig das Seitenverhältnis beizubehalten. Der Code eignet sich auch für 3-Kanal-Bilder (farbig) .. _. Anwendungsbeispiel:
resized = resize2SquareKeepingAspectRation(img, size, cv2.INTER_AREA)
Wenn Sie die Bildauflösung ändern und das Seitenverhältnis beibehalten müssen, verwenden Sie die Funktion imutils (siehe Dokumentation). etwas wie das:
img = cv2.imread(file , 0)
img = imutils.resize(img, width=1280)
cv2.imshow('image' , img)
hoffe das hilft, viel glück!
Der Code erhält einen window_height
, mit dem er die window_width
-Variable berechnet, während das Seitenverhältnis des Bildes beibehalten wird. Um zu verhindern, dass es zu Verzerrungen kommt.
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()
Ich kann nicht mit dem zitieren, was die ursprüngliche Frage stellt, aber ich bin hier gelandet und habe nach einer Antwort auf eine ähnliche Frage gesucht.
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)))
verkleinert das Bild auf die Hälfte der Originalgröße. Sie können es für jedes andere Verhältnis ändern Beachten Sie, dass das erste an resize () übergebene Argument img.shape [1] und nicht img.shape [0] ist. Dies kann kontraintuitiv sein. Es ist leicht, diese Umkehrung zu übersehen und ein sehr verzerrtes Bild zu erhalten.