OpenCV 和 Python - 图像太大而无法显示

问题描述 投票:0回答:14

我的图像尺寸为 6400 × 3200,而我的屏幕为 1280 x 800。因此,仅需要调整图像大小以供显示。我正在使用 Python 和 OpenCV 2.4.9。 根据 OpenCV 文档

如果需要显示大于屏幕分辨率的图像,则需要在imshow之前调用namedWindow("", WINDOW_NORMAL)。

这就是我正在做的,但是图像不适合屏幕,只显示了一部分,因为它太大了。我也尝试过使用 cv2.resizeWindow,但没有任何区别。

import cv2
cv2.namedWindow("output", cv2.WINDOW_NORMAL)        # Create window with freedom of dimensions
# cv2.resizeWindow("output", 400, 300)              # Resize window to specified dimensions
im = cv2.imread("earth.jpg")                        # Read image
cv2.imshow("output", im)                            # Show image
cv2.waitKey(0)                                      # Display the image infinitely until any keypress
python image opencv image-processing computer-vision
14个回答
154
投票

虽然我期待一个自动解决方案(自动适应屏幕),但调整大小也可以解决问题。

import cv2
cv2.namedWindow("output", cv2.WINDOW_NORMAL)    # Create window with freedom of dimensions
im = cv2.imread("earth.jpg")                    # Read image
imS = cv2.resize(im, (960, 540))                # Resize image
cv2.imshow("output", imS)                       # Show image
cv2.waitKey(0)                                  # Display the image infinitely until any keypress

60
投票

其他答案执行固定的

(width, height)
调整大小。如果您想在保持纵横比的同时调整到特定尺寸,请使用此

def ResizeWithAspectRatio(image, width=None, height=None, inter=cv2.INTER_AREA):
    dim = None
    (h, w) = image.shape[:2]

    if width is None and height is None:
        return image
    if width is None:
        r = height / float(h)
        dim = (int(w * r), height)
    else:
        r = width / float(w)
        dim = (width, int(h * r))

    return cv2.resize(image, dim, interpolation=inter)

示例

image = cv2.imread('img.png')
resize = ResizeWithAspectRatio(image, width=1280) # Resize by width OR
# resize = ResizeWithAspectRatio(image, height=1280) # Resize by height 

cv2.imshow('resize', resize)
cv2.waitKey()

25
投票

以此为例:

cv2.namedWindow('finalImg', cv2.WINDOW_NORMAL)
cv2.imshow("finalImg",finalImg)

24
投票

resizeWindow
对我有用的唯一方法就是在
imshow
之后获得它。这是我使用的顺序:

# Create a Named Window
cv2.namedWindow(win_name, cv2.WINDOW_NORMAL)

# Move it to (X,Y)
cv2.moveWindow(win_name, X, Y)
    
# Show the Image in the Window
cv2.imshow(win_name, image)
    
# Resize the Window
cv2.resizeWindow(win_name, width, height)
    
# Wait for <> miliseconds
cv2.waitKey(wait_time)

12
投票

在 OpenCV 中,

cv2.namedWindow()
只是创建一个窗口对象,但不会调整原始图像的大小。您可以使用
cv2.resize(img, resolution)
来解决问题。

这是它显示的内容,分辨率为 740 * 411 的图像。 The original image

image = cv2.imread("740*411.jpg")
cv2.imshow("image", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

这里显示的是调整大小后100 * 200分辨率的图像。请记住分辨率参数先使用列,然后才是行。

Image after resizing

image = cv2.imread("740*411.jpg")
image = cv2.resize(image, (200, 100))
cv2.imshow("image", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

6
投票

此代码将调整图像大小,以便它可以保留其纵横比,并且仅占据屏幕区域的指定部分。

它会根据您的屏幕尺寸和图像尺寸自动调整。

使用区域变量更改您希望图像能够占据的最大屏幕区域。该示例显示它以屏幕尺寸的四分之一显示。

import cv2
import tkinter as tk
from math import *

img = cv2.imread("test.jpg")
area = 0.25

h, w = img.shape[:2]
root = tk.Tk()
screen_h = root.winfo_screenheight()
screen_w = root.winfo_screenwidth()
vector = sqrt(area)
window_h = screen_h * vector
window_w = screen_w * vector

if h > window_h or w > window_w:
    if h / window_h >= w / window_w:
        multiplier = window_h / h
    else:
        multiplier = window_w / w
    img = cv2.resize(img, (0, 0), fx=multiplier, fy=multiplier)

cv2.imshow("output", img)
cv2.waitKey(0)

我还制作了一个类似的函数,其中面积仍然是一个参数,但窗口高度和窗口宽度也是一个参数。

如果没有输入区域,那么它将使用您希望图像适合的窗口大小的定义高度和宽度(window_h,window_w)。

如果为所有参数都提供了输入,则优先考虑“区域”。

import cv2
import tkinter as tk
from math import *

def resize_image(img, area=0.0, window_h=0, window_w=0):
    h, w = img.shape[:2]
    root = tk.Tk()
    screen_h = root.winfo_screenheight()
    screen_w = root.winfo_screenwidth()

    if area != 0.0:
        vector = math.sqrt(area)
        window_h = screen_h * vector
        window_w = screen_w * vector

    if h > window_h or w > window_w:
        if h / window_h >= w / window_w:
            multiplier = window_h / h
        else:
            multiplier = window_w / w
        img = cv2.resize(img, (0, 0), fx=multiplier, fy=multiplier)

    return img

# using area
initial_image = cv2.imread("test.jpg")
resized_image = resize_image(initial_image, area=0.25))
cv2.imshow("output", resized_image)
cv2.waitKey(0)

# using window height and width
initial_image = cv2.imread("test.jpg")
resized_image = resize_image(initial_image, window_h = 480, window_w = 270))
cv2.imshow("output", resized_image)
cv2.waitKey(0)

4
投票

看起来 opencv lib 对传递给方法的参数非常敏感。以下代码对我使用 opencv 4.3.0 有用:

win_name = "visualization"  #  1. use var to specify window name everywhere
cv2.namedWindow(win_name, cv2.WINDOW_NORMAL)  #  2. use 'normal' flag
img = cv2.imread(filename)
h,w = img.shape[:2]  #  suits for image containing any amount of channels
h = int(h / resize_factor)  #  one must compute beforehand
w = int(w / resize_factor)  #  and convert to INT
cv2.resizeWindow(win_name, w, h)  #  use variables defined/computed BEFOREHAND
cv2.imshow(win_name, img)

3
投票

试试这个:

image = cv2.imread("img/Demo.jpg")
image = cv2.resize(image,(240,240))

image
现已调整大小。显示它将以 240x240 呈现。


1
投票

cv2.WINDOW_NORMAL 选项工作正常,但第一次以标准尺寸显示窗口。

如果像计算机中的任何其他窗口一样调整窗口大小,请将鼠标放在要调整大小的窗口边缘上,然后将鼠标拖动到所需位置。如果您将窗口的宽度和高度都执行到您想要获得的尺寸。

下次刷新窗口时,通过执行代码,OpenCV 将生成上次显示或修改大小的窗口。


1
投票

试试这个代码:

img = cv2.imread("Fab2_0.1 X 1.03MM GRID.jpg", cv2.IMREAD_GRAYSCALE)
image_scale_down = 3
x = (int)(img.shape[0]/image_scale_down)
y = (int)(img.shape[1]/image_scale_down)
image = cv2.resize(img, (x,y))
cv2.imshow("image_title", image)
cv2.waitKey(5000)
cv2.destroyAllWindows()

0
投票

最多点赞的答案很完美! 我只是为那些想要根据比例进行“动态”调整大小处理的人添加代码。

import cv2
from win32api import GetSystemMetrics

def get_resized_for_display_img(img):
    screen_w, screen_h = GetSystemMetrics(0), GetSystemMetrics(1)
    print("screen size",screen_w, screen_h)
    h,w,channel_nbr = img.shape
    # img get w of screen and adapt h
    h = h * (screen_w / w)
    w = screen_w
    if h > screen_h: #if img h still too big
        # img get h of screen and adapt w
        w = w * (screen_h / h)
        h = screen_h
    w, h = w*0.9, h*0.9 # because you don't want it to be that big, right ?
    w, h = int(w), int(h) # you need int for the cv2.resize
    return cv2.resize(img, (w, h))

0
投票

仅根据您的喜好或屏幕分辨率更改 downscaling_factor。

# if img is your mask or image

downscaling_factor = 0.70  # for example 70%


resized = tuple(int(x * downscaling_factor) for x in np.shape(img)[::-1])
img_resized = cv2.resize(img, resized  )   
cv2.imshow('Name of Image', img_resized)
cv2.waitKey(0)
cv2.destroyAllWindows()

-2
投票

尝试使用此代码:

from PIL import Image

Image.fromarray(image).show()

-2
投票

试试这个代码

img = cv2.resize(img,(1280,800))
© www.soinside.com 2019 - 2024. All rights reserved.