Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to keep the aspect ratio of image window in opencv?

Tags:

python

opencv

From documantation, it says that we can keep the image ratio by CV_WINDOW_KEEPRATIO but the windows still lost aspect ratio after I adjust it. Would anyone kindly help?

Example code:

import cv2

# load the image, clone it, and setup the mouse callback function
image = cv2.imread('1.jpg')
cv2.namedWindow('image', cv2.WINDOW_KEEPRATIO)
# keep looping until the 'q' key is pressed
while True:
    # display the image and wait for a keypress
    cv2.imshow('image', image)
    key = cv2.waitKey()

    if key == 27:
        break

# close all open windows
cv2.destroyAllWindows()
like image 753
kai06046 Avatar asked Jun 06 '17 10:06

kai06046


1 Answers

Are you trying to constrain the window or the image? You cannot constrain the window size, only the image size.

Note that in the documentation for namedWindow it says at the bottom

By default, flags == CV_WINDOW_AUTOSIZE | CV_WINDOW_KEEPRATIO | CV_GUI_EXPANDED

So setting cv2.WINDOW_KEEPRATIO will not affect ratio scaling (as it does not affect ratio by default).

I imagine that what you want to accomplish is to be able to move the window size and have that affect your displayed image size. Is that correct? If so, that is not possible with OpenCV, at least not built-in. Image windows are simply containers to show your image, and thus they will not affect your image at all. You can, of course, adjust your image size prior to display with cv2.resize().


Edit: Okay, so I'm not even sure if the above is what you want, but I said resizing the window is impossible with current OpenCV. In fact, it is kind of possible. You can create a trackbar, which will put a slider on your image. Then when you move the slider, it will call a function that you define with the slider's position as the argument. You could then take that position, convert it to a number between 0 and 1, and then multiply your image size by that number to get a smaller image size. Then you could resize your image by that scale, and redisplay it to your window. I'm pretty sure this is way overkill for what you need, but it was interesting so I decided to try it.

import cv2

def trackbar_change(pos):
    pos = pos/100 # get a scaling factor from trackbar pos
    image = cv2.imread('image.jpg') # read image
    h = int(image.shape[0]*pos) # scale h
    w = int(image.shape[1]*pos) # scale w
    rsz_image = cv2.resize(image, (w, h)) # resize image
    cv2.resizeWindow('image_window', w, h) # resize window
    cv2.imshow('image_window', rsz_image) # display resized image
    return

image = cv2.imread('image.jpg')
cv2.namedWindow('image_window', cv2.WINDOW_NORMAL)
starting_trackbar_val = 100
quant_trackbar_vals = 100
cv2.createTrackbar('Image scale', 'image_window', \
    starting_trackbar_val, quant_trackbar_vals, trackbar_change)

cv2.imshow('image_window', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
like image 79
alkasm Avatar answered Oct 20 '22 03:10

alkasm