วิธีการปรับขนาดภาพด้วย OpenCV2.0 และ Python2.6


163

ฉันต้องการใช้ OpenCV2.0 และ Python2.6 เพื่อแสดงภาพที่ปรับขนาดแล้ว ผมใช้และนำมาใช้ตัวอย่างที่http://opencv.willowgarage.com/documentation/python/cookbook.htmlแต่โชคร้ายรหัสนี้สำหรับ OpenCV2.1 และดูเหมือนจะไม่ได้ทำงานกับ 2.0 นี่รหัสของฉัน:

import os, glob
import cv

ulpath = "exampleshq/"

for infile in glob.glob( os.path.join(ulpath, "*.jpg") ):
    im = cv.LoadImage(infile)
    thumbnail = cv.CreateMat(im.rows/10, im.cols/10, cv.CV_8UC3)
    cv.Resize(im, thumbnail)
    cv.NamedWindow(infile)
    cv.ShowImage(infile, thumbnail)
    cv.WaitKey(0)
    cv.DestroyWindow(name)

เนื่องจากฉันไม่สามารถใช้

cv.LoadImageM

ฉันใช้

cv.LoadImage

แทนซึ่งไม่มีปัญหาในแอปพลิเคชันอื่น อย่างไรก็ตาม cv.iplimage ไม่มีแถวแอตทริบิวต์, cols หรือขนาด ทุกคนสามารถให้คำแนะนำฉันวิธีแก้ปัญหานี้ได้อย่างไร ขอบคุณ


4
หากคำตอบใด ๆ ถูกต้องโปรดทำเครื่องหมายว่าจะช่วยผู้อื่น
Michał

คำตอบ:


342

หากคุณต้องการใช้ CV2 คุณจะต้องใช้ resizeฟังก์ชั่น

ตัวอย่างเช่นนี่จะปรับขนาดทั้งสองแกนโดยครึ่งหนึ่ง:

small = cv2.resize(image, (0,0), fx=0.5, fy=0.5) 

และสิ่งนี้จะปรับขนาดภาพให้มี 100 cols (กว้าง) และ 50 แถว (สูง):

resized_image = cv2.resize(image, (100, 50)) 

ตัวเลือกอื่นคือใช้scipyโมดูลโดยใช้:

small = scipy.misc.imresize(image, 0.5)

มีตัวเลือกเพิ่มเติมอย่างชัดเจนที่คุณสามารถอ่านได้ในเอกสารของฟังก์ชั่นเหล่านั้น ( cv2.resize , scipy.misc.imresize )


อัปเดต:
ตามเอกสาร SciPy :

imresizeถูกเลิกใช้ใน SciPy 1.0.0 และจะถูกลบใน 1.2.0
ใช้skimage.transform.resizeแทน

ทราบว่าหากคุณกำลังมองหาเพื่อปรับขนาดโดยปัจจัยskimage.transform.rescaleคุณจริงอาจต้องการ


1
ฟังก์ชั่นปรับขนาด () ไม่ทำให้ภาพสูญเสียข้อมูลเกี่ยวกับตัวเอง?

8
ใช่คุณไม่สามารถลดขนาดของภาพโดยไม่ทำให้ข้อมูลสูญหาย
Rafael_Espericueta

1
การใช้งาน opencv (0.05ms ต่อภาพ) ดูเหมือนว่าจะเร็วกว่าการใช้งาน scipy (0.33ms ภาพ) ฉันปรับขนาดรูปภาพ 210x160x1 เป็น 84x84x1 ด้วยการแก้ไขสองทาง
gizzmole

@gizzmole ข้อมูลเชิงลึกที่น่าสนใจ ฉันไม่ได้ทดสอบประสิทธิภาพของการใช้งานหรือเปรียบเทียบผลลัพธ์ - ดังนั้นผลลัพธ์อาจแตกต่างกันเล็กน้อย คุณทดสอบเพื่อดูภาพที่ปรับขนาดแล้วหรือไม่
emem

Thaks สำหรับการชี้ให้เห็นว่าฟังก์ชั่นการปรับขนาดใช้ (W * H) ในขณะที่พิมพ์ cv2 เป็น (H * W)
Shivam Kotwalia

59

ตัวอย่างการเพิ่มขนาดของภาพเป็นสองเท่า

การปรับขนาดภาพมีสองวิธี ขนาดใหม่สามารถระบุได้:

  1. ด้วยตนเอง

    height, width = src.shape[:2]

    dst = cv2.resize(src, (2*width, 2*height), interpolation = cv2.INTER_CUBIC)

  2. โดยการปรับสัดส่วน

    dst = cv2.resize(src, None, fx = 2, fy = 2, interpolation = cv2.INTER_CUBIC)โดยที่fxคือตัวประกอบสเกลตามแนวแกนนอนและfyตามแกนตั้ง

หากต้องการย่อขนาดรูปภาพโดยทั่วไปแล้วจะดูดีที่สุดเมื่อใช้การแก้ไข INTER_AREA ในขณะที่การขยายภาพโดยทั่วไปจะดูดีที่สุดด้วย INTER_CUBIC (ช้า) หรือ INTER_LINEAR (เร็วขึ้น แต่ก็ดูดีกว่า)

ตัวอย่างภาพย่อขนาดให้พอดีกับความสูง / ความกว้างสูงสุด (รักษาอัตราส่วน)

import cv2

img = cv2.imread('YOUR_PATH_TO_IMG')

height, width = img.shape[:2]
max_height = 300
max_width = 300

# only shrink if img is bigger than required
if max_height < height or max_width < width:
    # get scaling factor
    scaling_factor = max_height / float(height)
    if max_width/float(width) < scaling_factor:
        scaling_factor = max_width / float(width)
    # resize image
    img = cv2.resize(img, None, fx=scaling_factor, fy=scaling_factor, interpolation=cv2.INTER_AREA)

cv2.imshow("Shrinked image", img)
key = cv2.waitKey()

ใช้รหัสของคุณกับ cv2

import cv2 as cv

im = cv.imread(path)

height, width = im.shape[:2]

thumbnail = cv.resize(im, (round(width / 10), round(height / 10)), interpolation=cv.INTER_AREA)

cv.imshow('exampleshq', thumbnail)
cv.waitKey(0)
cv.destroyAllWindows()

โซลูชันของคุณที่ใช้ตัวคูณสเกลจะส่งคืนข้อผิดพลาดใน cv2.resize () ที่บอกว่า 'src ไม่ใช่อาเรย์ numpy ไม่ใช่สเกลาร์' กรุณาแนะนำ?
BenP

คุณทำ: src = cv2.imread('YOUR_PATH_TO_IMG')และแก้ไข 'YOUR_PATH_TO_IMG' ไปยังเส้นทางของภาพของคุณเองหรือไม่?
João Cartucho

จะcv2.resizeใช้การขยายโดยอัตโนมัติ ขนาดของหน้าต่างที่สร้างขึ้นโดยใช้ขนาดเอาต์พุตที่ต้องการเป็น(width/10, height/10)เท่าใด
seralouk

@makaros คุณจะได้ภาพที่เล็กลง 10 เท่าทั้งความกว้างและความสูง
João Cartucho

@ JoãoCartuchoใช่ฉันเข้าใจสิ่งนี้ แต่เมื่อใช้ชิปที่ใกล้เคียงที่สุดแล้วก็ควรใช้หน้าต่างด้านหลังฉาก นี่คือสิ่งที่ฉันกำลังขอ ..
seralouk

8

คุณสามารถใช้ฟังก์ชัน GetSize เพื่อรับข้อมูลเหล่านั้น cv.GetSize (im) จะคืนค่า tuple ด้วยความกว้างและความสูงของรูปภาพ คุณสามารถใช้ im.depth และ img.nChan เพื่อรับข้อมูลเพิ่มเติม

และเพื่อปรับขนาดภาพฉันจะใช้กระบวนการที่แตกต่างกันเล็กน้อยโดยใช้รูปภาพอื่นแทนเมทริกซ์ มันจะดีกว่าที่จะพยายามที่จะทำงานร่วมกับชนิดเดียวกันของข้อมูล:

size = cv.GetSize(im)
thumbnail = cv.CreateImage( ( size[0] / 10, size[1] / 10), im.depth, im.nChannels)
cv.Resize(im, thumbnail)

หวังว่านี่จะช่วยได้;)

มั๊ย


6
def rescale_by_height(image, target_height, method=cv2.INTER_LANCZOS4):
    """Rescale `image` to `target_height` (preserving aspect ratio)."""
    w = int(round(target_height * image.shape[1] / image.shape[0]))
    return cv2.resize(image, (w, target_height), interpolation=method)

def rescale_by_width(image, target_width, method=cv2.INTER_LANCZOS4):
    """Rescale `image` to `target_width` (preserving aspect ratio)."""
    h = int(round(target_width * image.shape[0] / image.shape[1]))
    return cv2.resize(image, (target_width, h), interpolation=method)

ไม่cv2.resizeโดยอัตโนมัติใช้ padding? ขนาดของหน้าต่างที่สร้างขึ้นโดยใช้(w, target_height)อาร์กิวเมนต์คืออะไร
seralouk

4

นี่คือฟังก์ชั่นเพื่อยกระดับหรือลดขนาดภาพตามความกว้างหรือความสูงที่ต้องการในขณะที่ยังคงอัตราส่วนไว้

# Resizes a image and maintains aspect ratio
def maintain_aspect_ratio_resize(image, width=None, height=None, inter=cv2.INTER_AREA):
    # Grab the image size and initialize dimensions
    dim = None
    (h, w) = image.shape[:2]

    # Return original image if no need to resize
    if width is None and height is None:
        return image

    # We are resizing height if 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)
    # We are resizing width if height is none
    else:
        # Calculate the ratio of the width and construct the dimensions
        r = width / float(w)
        dim = (width, int(h * r))

    # Return the resized image
    return cv2.resize(image, dim, interpolation=inter)

การใช้

import cv2

image = cv2.imread('1.png')
cv2.imshow('width_100', maintain_aspect_ratio_resize(image, width=100))
cv2.imshow('width_300', maintain_aspect_ratio_resize(image, width=300))
cv2.waitKey()

ใช้ภาพตัวอย่างนี้

ป้อนคำอธิบายรูปภาพที่นี่

เพียงลดระดับลงเป็นwidth=100(ซ้าย) หรือเลื่อนขึ้นไปเป็นwidth=300(ขวา)

ป้อนคำอธิบายรูปภาพที่นี่ ป้อนคำอธิบายรูปภาพที่นี่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.