Ask Your Question
0

How do I make the image not fit the window?

asked 2020-04-12 11:11:24 -0600

rrky1 gravatar image

updated 2020-04-12 11:52:41 -0600

I want a square window, but I don't want the image to fit the window, I want it to either scale to height or scale to width. Example:

image = cv.imread("image.png")

width = 300
height = 70
dim = (width, height)

resized = cv.resize(image, dim, interpolation =cv.INTER_AREA)

cv.namedWindow("image", cv.WINDOW_NORMAL) 
cv.resizeWindow("image", 300, 300)
cv.moveWindow("image", 50, 50)

cv.imshow("image", resized)

I want a 300x70 image centered inside a 300x300 window, but every time I try it, the image gets stretched kind of like this:

image description

vs

image description

Also, is there a way of having a fixed image size? So even if I change the window size with my mouse later the size doesn't change, but stay the same on the center of the window, example:

image description

edit retag flag offensive close merge delete

Comments

For the aspect ratio, you should see the flags for namedWindow https://docs.opencv.org/2.4/doc/tutor...

mvuori gravatar imagemvuori ( 2020-04-12 11:28:32 -0600 )edit

Thanks, I keep the aspect ratio on my actual code, removed the calculation from the example to keep it simple

rrky1 gravatar imagerrky1 ( 2020-04-12 11:46:40 -0600 )edit

2 answers

Sort by ยป oldest newest most voted
1

answered 2020-04-15 04:24:04 -0600

updated 2020-04-15 07:39:04 -0600

supra56 gravatar image

Code:

import cv2 
import numpy as np

def resizeAndPad(img, size, padColor=0):
    h, w = img.shape[:2]
    sh, sw = size

# interpolation method
if h > sh or w > sw: # shrinking image
interp = cv2.INTER_AREA
else: # stretching image
interp = cv2.INTER_CUBIC

# aspect ratio of image
aspect = w/h  # if on Python 2, you might need to cast as a float: float(w)/h

# compute scaling and pad sizing
if aspect > 1: # horizontal image
new_w = sw
new_h = np.round(new_w/aspect).astype(int)
pad_vert = (sh-new_h)/2
pad_top, pad_bot = np.floor(pad_vert).astype(int), np.ceil(pad_vert).astype(int)
pad_left, pad_right = 0, 0
elif aspect < 1: # vertical image
new_h = sh
new_w = np.round(new_h*aspect).astype(int)
pad_horz = (sw-new_w)/2
pad_left, pad_right = np.floor(pad_horz).astype(int), np.ceil(pad_horz).astype(int)
pad_top, pad_bot = 0, 0
else: # square image
new_h, new_w = sh, sw
pad_left, pad_right, pad_top, pad_bot = 0, 0, 0, 0

# set pad color
if len(img.shape) is 3 and not isinstance(padColor, (list, tuple, np.ndarray)): # color image but only one color provided
padColor = [padColor]*3

# scale and pad
scaled_img = cv2.resize(img, (new_w, new_h), interpolation=interp)
scaled_img = cv2.copyMakeBorder(scaled_img, pad_top, pad_bot, pad_left, pad_right, borderType=cv2.BORDER_CONSTANT, value=padColor)

return scaled_img

v_img = cv2.imread('v.jpg') # vertical image scaled_v_img = resizeAndPad(v_img, (200,200), 127)
h_img = cv2.imread('h.jpg') # horizontal image scaled_h_img = resizeAndPad(h_img, (200,200), 127)
sq_img = cv2.imread('sq.jpg') # square image scaled_sq_img = resizeAndPad(sq_img, (200,200), 127)
edit flag offensive delete link more
0

answered 2020-04-14 23:07:51 -0600

rrky1 gravatar image

updated 2020-04-14 23:11:56 -0600

For future reference:

Fixed the first part of the question with this function:

import cv2
import numpy as np

def resizeAndPad(img, size, padColor=0):

    h, w = img.shape[:2]
    sh, sw = size

    # interpolation method
    if h > sh or w > sw: # shrinking image
    interp = cv2.INTER_AREA
    else: # stretching image
    interp = cv2.INTER_CUBIC

    # aspect ratio of image
    aspect = w/h  # if on Python 2, you might need to cast as a float: float(w)/h

    # compute scaling and pad sizing
    if aspect > 1: # horizontal image
    new_w = sw
    new_h = np.round(new_w/aspect).astype(int)
    pad_vert = (sh-new_h)/2
    pad_top, pad_bot = np.floor(pad_vert).astype(int), np.ceil(pad_vert).astype(int)
    pad_left, pad_right = 0, 0
    elif aspect < 1: # vertical image
    new_h = sh
    new_w = np.round(new_h*aspect).astype(int)
    pad_horz = (sw-new_w)/2
    pad_left, pad_right = np.floor(pad_horz).astype(int), np.ceil(pad_horz).astype(int)
    pad_top, pad_bot = 0, 0
    else: # square image
    new_h, new_w = sh, sw
    pad_left, pad_right, pad_top, pad_bot = 0, 0, 0, 0

    # set pad color
    if len(img.shape) is 3 and not isinstance(padColor, (list, tuple, np.ndarray)): # color image but only one color provided
    padColor = [padColor]*3

    # scale and pad
    scaled_img = cv2.resize(img, (new_w, new_h), interpolation=interp)
    scaled_img = cv2.copyMakeBorder(scaled_img, pad_top, pad_bot, pad_left, pad_right, borderType=cv2.BORDER_CONSTANT, value=padColor)

    return scaled_img

v_img = cv2.imread('v.jpg') # vertical image
scaled_v_img = resizeAndPad(v_img, (200,200), 127)

h_img = cv2.imread('h.jpg') # horizontal image
scaled_h_img = resizeAndPad(h_img, (200,200), 127)

sq_img = cv2.imread('sq.jpg') # square image
scaled_sq_img = resizeAndPad(sq_img, (200,200), 127)

padding

Source

Don't know if you can make the output image a fixed size even after manually resizing the window though.

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2020-04-12 11:04:46 -0600

Seen: 5,763 times

Last updated: Apr 15 '20