How to show image in true size in a full screen opencv window?

Viewed 2085

I am trying to create a fullscreen opencv window (size 1920x1080) which should show an image (620x365) in mid center position of the opencv window. Unfortunately, the image gets expanded to fullscreen as well. How could this be done? Which properties need to be set? I am using opencv version 2.4.12.

import cv2

imgwindow = 'show my image'
image = cv2.imread('./myimage.jpg')
cv2.namedWindow(imgwindow, cv2.WINDOW_NORMAL)
cv2.setWindowProperty(imgwindow, cv2.WND_PROP_FULLSCREEN, cv2.cv.CV_CAP_PROP_FORMAT)
cv2.imshow(imgwindow,image)
cv2.waitKey(0)
cv2.destroyAllWindows()

when I use the following example, I get a full screen opencv window and a true size image but in the upper left corner of the window instead of mid-center position.

import cv2
import win32gui
import win32con
import ctypes

user32 = ctypes.windll.user32
winW, winH = [user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)]

imgwindow = 'show my image'
image = cv2.imread('./myimage.jpg')
cv2.namedWindow(imgwindow, cv2.WINDOW_AUTOSIZE)
cv2.cv.CV_WINDOW_FULLSCREEN)
cv2.imshow(imgwindow,image)
simHndl = win32gui.GetForegroundWindow()
win32gui.MoveWindow(simHndl, 0,0, winW, winH, win32con.TRUE)

cv2.waitKey(0)
cv2.destroyAllWindows()

This is the example picture when the window contains the true image picture and is placed mid-center:

enter image description here

This is the example picture when the window is fullscreen but the image is expanded to full screen as well:

enter image description here

And this is the situation I am looking for: a fullscreen window and the true size image placed mid-center:

enter image description here

2 Answers

OpenCV loads the image in its original size if you just use cv2.imshow without first declaring it using cv2.namedWindow.

So by skipping cv2.namedWindow you can achieve your target of loading the image in its original size. From there you can move the window using cv2.moveWindow. All you need is to calculate the position for it to load. The formula in presented in the code below:

import cv2
import ctypes

# Get the window size and calculate the center
user32 = ctypes.windll.user32
win_x, win_y = [user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)] 
win_cnt_x, win_cnt_y = [user32.GetSystemMetrics(0)/2, user32.GetSystemMetrics(1)/2] 

# load image
imgwindow = 'show my image'
image = cv2.imread('./myimage.jpg')

# Get the image size information
off_height, off_width = image.shape[:2]
off_height /= 2
off_width /= 2

# Show image and move it to center location
image = cv2.resize(image,(win_x, win_y))
cv2.imshow(imgwindow,image)

cv2.moveWindow(imgwindow,0,0)
cv2.waitKey(0)
cv2.destroyAllWindows()

I, too, had this requirement. The behaviour of imshow determines what you can do in openCV.

Case 1: load image and display immediately - you get the correctly sized image in a window with a title bar the same size as the image

Case 2: created a named fullscreen window and load image - you get an image automatically scaled to the fullscreen (not sure why, sure there's a good reason)

Case 3: create a named fullscreen window and resize it to the image then show the image - you get the same as case 1 without the title bar

My "solution" was to create an image the same size as the full screen and "add" the smaller image centered in it (pretty easy) Here is a fragment of how I chose to do that:

# screenx and screeny are size of screen, 1280 by 720 for example
# image is the image to center on the screen, sized imagex by imagey

# create a black image as big as the screen
bg_img = np.zeros((screeny, screenx, 3), np.uint8)
bg_img[:, 0:screeny] = (0, 0, 0)
# add a white border to define the region
cv2.rectangle(bg_img, (0, 0), (screenx-2, screeny-2), color=(255, 255, 255), thickness=1)
# calculate the offsets required to center the image
x_offset = (screenx - imagex)//2
y_offset = (screeny - imagey)//2
# insert the samller image into the larger image, centered
bg_image[y_offset:y_offset+image.shape[0], x_offset:x_offset+image.shape[1]] = image

PS - I found in Win10 that the Display setting for Scale and Layout will affect the screen resolution considerably...just be aware of that. At 100% you may have 2560x1440 but with 150% scale you get 1707x960.

Related