Numpy Resize / Rescale Image


98

मैं एक छवि लेना चाहता हूं और छवि के पैमाने को बदलना चाहता हूं, जबकि यह एक सुस्पष्ट सरणी है।

उदाहरण के लिए मेरे पास कोका-कोला बोतल की यह छवि है: बोतल -1

जो आकार की एक सुव्यवस्थित सारणी में अनुवाद करता है (528, 203, 3)और मैं इस दूसरी छवि के आकार को कहने के लिए इसका आकार बदलना चाहता हूं: बोतल -2

जिसका आकार है (140, 54, 3)

मूल छवि को बनाए रखते हुए मैं छवि के आकार को एक निश्चित आकार में कैसे बदलूं? अन्य उत्तर हर दूसरी या तीसरी पंक्ति को अलग करने का सुझाव देते हैं, लेकिन मैं जो करना चाहता हूं वह मूल रूप से छवि को सिकोड़ना है कि आप एक छवि संपादक के माध्यम से लेकिन अजगर कोड में कैसे करेंगे। वहाँ किसी भी पुस्तकालयों ऐसा करने के लिए numpy / SciPy में हैं?


क्या आप अपने संख्यात्मक सरणी के लिए कोड दिखा सकते हैं?
ShpielMeister 22


2
@sascha आपके द्वारा लिंक किए गए पृष्ठ के अनुसार, अस्वीकृत।
पॉल पैंजर

@ शेफिल्मिस्टर मैं इंटेलीज को पूरी तरह से सुन्न सरणी को प्रिंट करने के लिए नहीं मिल सकता है, किसी कारण से जब आउटपुट बड़ा होता है ... सभी समय में, इसलिए मैं केवल कंसोल में सरणी आउटपुट का हिस्सा देख सकता हूं
ब्रायन हैमिल

जवाबों:


122

हाँ, आप स्थापित कर सकते हैं opencv(यह छवि प्रसंस्करण, और कंप्यूटर दृष्टि के लिए उपयोग किया जाने वाला पुस्तकालय है), और cv2.resizeफ़ंक्शन का उपयोग करें । और उदाहरण के लिए उपयोग करें:

import cv2
import numpy as np

img = cv2.imread('your_image.jpg')
res = cv2.resize(img, dsize=(54, 140), interpolation=cv2.INTER_CUBIC)

यहाँ imgइस प्रकार, मूल छवि से युक्त एक numpy सरणी है जबकि resयुक्त एक numpy सरणी है आकृति परिवर्तन छवि। एक महत्वपूर्ण पहलू interpolationपैरामीटर है: एक छवि का आकार बदलने के कई तरीके हैं। खासकर जब से आप छवि को स्केल करते हैं, और मूल छवि का आकार आकार की छवि के आकार का एक से अधिक नहीं है। संभावित प्रक्षेप स्कीमा हैं:

  • INTER_NEAREST - एक निकटतम पड़ोसी प्रक्षेप
  • INTER_LINEAR - एक बिलिनियर इंटरपोलेशन (डिफ़ॉल्ट रूप से उपयोग किया जाता है)
  • INTER_AREA- पिक्सेल क्षेत्र संबंध का उपयोग कर फिर से खोलना। यह चित्रण के लिए एक पसंदीदा तरीका हो सकता है, क्योंकि यह moire'-free परिणाम देता है। लेकिन जब छवि को ज़ूम किया जाता है, तो यह INTER_NEARESTविधि के समान है ।
  • INTER_CUBIC - 4x4 पिक्सेल पड़ोस पर एक बाइबिकिक प्रक्षेप
  • INTER_LANCZOS4 - 8x8 पिक्सेल के पड़ोस में एक लैंक्ज़ोस प्रक्षेप

अधिकांश विकल्पों की तरह, इस अर्थ में कोई "सर्वश्रेष्ठ" विकल्प नहीं है कि हर आकार के स्कीमा के लिए, ऐसे परिदृश्य हैं जहां एक रणनीति को दूसरे पर पसंद किया जा सकता है।


5
मैंने अभी इस कोड को आज़माया है और यह काम करता है! बस एक परिवर्तन यह है कि जैसा dsizeहोना चाहिए dsize=(54, 140)वह तब x होता है, तब, जहाँ एक सुप्त व्यूह y के रूप में आकार दिखाता है, तब x (y पंक्तियों की संख्या और x स्तंभों की संख्या है)
ब्रायन हैमिल

6
मैं cv2 से बचने की कोशिश करता हूं, यह बीजीआर चैनल प्रारूप में आयाम और भार स्वैप करता है। मैं पसंद skimage.io.imread('image.jpg')और skimage.transform.resize(img)scikit-image.org/docs/dev/install.html
एडुआर्डो

1
@EduardoPignatelli मैं skimage.transform.resize से बचता हूं क्योंकि आपके पास इसके उपयोग करने वाले प्रक्षेप एल्गोरिथ्म पर नियंत्रण नहीं है। लेकिन, यह महत्वपूर्ण नहीं हो सकता है, जो लोगों के उपयोग के मामलों पर निर्भर करता है।
डेकर

2
@Decker skimage.transform.resize 'ऑर्डर'-पैरामीटर के माध्यम से कुछ नियंत्रण प्रदान करता है। आदेश = 0 निकटतम पड़ोसी है, 1 = द्वि-रेखीय, 2 = द्वि-द्विघात, 3 = द्वि-घन इत्यादि। हालांकि कोई क्षेत्र माध्य या लैंकोज प्रक्षेप नहीं है।
तापियो

1
@TapioFriberg आह, मैं सही खड़ा हूँ; मैं skimage.transform.warp के 'ऑर्डर' पैरामीटर के लिए प्रलेखन के तहत परिभाषित एल्गोरिदम को देखता हूं। कुछ बिंदुओं पर डॉक्स को अपडेट करने में मदद मिल सकती है, प्रकारों के संदर्भों को शामिल करने के लिए, "द्वि-चतुर्थक", उदाहरण के लिए, प्रलेखन में कहीं और परिभाषित नहीं किया गया है, (10 दिसंबर 2019 तक) - एक-लाइनर हो सकता है भविष्य के उपयोगकर्ताओं के लिए फायदेमंद हो।
डेकर

67

हालांकि ऐसा करने के लिए अकेले खस्ता का उपयोग करना संभव हो सकता है, ऑपरेशन अंतर्निहित नहीं है। scikit-imageइस तरह की छवि में हेरफेर करने के लिए , आपने कहा (जो कि numpy पर बनाया गया है) का उपयोग कर सकते हैं ।

Scikit-Image rescaling प्रलेखन यहाँ है

उदाहरण के लिए, आप अपनी छवि के साथ निम्न कार्य कर सकते हैं:

from skimage.transform import resize
bottle_resized = resize(bottle, (140, 54))

यह आपके लिए प्रक्षेप, एंटी-अलियासिंग, आदि जैसी चीजों का ध्यान रखेगा।


2
धन्यवाद! यह उत्तर भी काम करता है! हालाँकि मुझे anti_aliasingध्वज के साथ कुछ समस्या मिल रही है , ऐसा लगता है कि इसे 0.13.1
ब्रायन हैमिल

8
यह रिटर्न छवि के रूप में नाव ndarray भले ही अपनी मूल छवि है uint8
sziraqui

3
यह एक अच्छी तकनीक है क्योंकि यह किसी भी संख्या में चैनलों के साथ काम करती है। मैंने आरजीबी डेटा के साथ गहराई बिंदु क्लाउड डेटा के साथ संयुक्त रूप से यह कोशिश की और इसने मेरे जैसे रिश्ते को संरक्षित किया।
डार्थ एलीगस

@DarthEgregious, jakevdp -> जब मैंने आपके द्वारा बताई गई विधि की तरह (64,64) सरणी का आकार बदला (137,236,3) सरणी, तो यह एकल रंग में मेरा यादृच्छिक शोर डेटा बना दिया। क्या यह सामान्य है क्योंकि ऐसा लगता है कि इसने सारी जानकारी खो दी है?
देशवाल

1
ऐसा नहीं होना चाहिए (64,64,3)
डार्थ

14

Google से यहां आने वाले लोगों के numpyलिए मशीन लर्निंग एप्लिकेशन में उपयोग के लिए सरणियों में छवियों को डाउन करने के लिए एक तेज़ तरीका ढूंढ रहा है , यहां एक सुपर फास्ट विधि ( यहां से अनुकूलित ) है। यह विधि केवल तब काम करती है जब इनपुट आयाम कई आउटपुट आयाम होते हैं।

निम्नलिखित उदाहरण 128x128 से 64x64 तक नीचे आते हैं (इसे आसानी से बदला जा सकता है)।

चैनल अंतिम आदेश देते हैं

# large image is shape (128, 128, 3)
# small image is shape (64, 64, 3)
input_size = 128
output_size = 64
bin_size = input_size // output_size
small_image = large_image.reshape((output_size, bin_size, 
                                   output_size, bin_size, 3)).max(3).max(1)

चैनल पहले ऑर्डर कर रहा है

# large image is shape (3, 128, 128)
# small image is shape (3, 64, 64)
input_size = 128
output_size = 64
bin_size = input_size // output_size
small_image = large_image.reshape((3, output_size, bin_size, 
                                      output_size, bin_size)).max(4).max(2)

ग्रेस्केल छवियों बस बदलने के लिए 3एक करने के लिए 1इस तरह:

चैनल पहले ऑर्डर कर रहा है

# large image is shape (1, 128, 128)
# small image is shape (1, 64, 64)
input_size = 128
output_size = 64
bin_size = input_size // output_size
small_image = large_image.reshape((1, output_size, bin_size,
                                      output_size, bin_size)).max(4).max(2)

यह विधि अधिकतम पूलिंग के बराबर का उपयोग करती है। यह ऐसा करने का सबसे तेज़ तरीका है जो मैंने पाया है।


4
big_image [:, :: 2, :: 2] हल के साथ छवि लौटाता है।
एल। किर्केनिन

1
@ LasseKärkkäinen लेकिन यह नीचे नहीं गिरा, यह केवल हर दूसरे पिक्सेल का चयन करता है। अंतर यह है कि अंतिम फ़ंक्शन 'मैक्स' को पिक्सेल को कुछ बेहतर तरीकों से चुनने या गणना करने के लिए बदला जा सकता है (उदाहरण के लिए 'मिनट' या 'मीन' का उपयोग करके)। आपकी विधि उपयोगी (और तेज) है, अगर यह कोई फर्क नहीं पड़ता।
वायलॉन फ्लिन

@ L.Kärkkäinen इसके दोहरे संकल्प के विपरीत क्या है?
रेज़िनज़

2
@rayzinnznp.repeat(np.repeat(a, 2, axis=0), 2, axis=1)
L. Kärkkäinen

11

यदि कोई भी अतिरिक्त पुस्तकालयों का उपयोग किए बिना, पाइथन में एक छवि को स्केल / आकार बदलने के लिए एक सरल विधि की तलाश में यहां आया था, तो यहां एक बहुत ही सरल छवि आकार फ़ंक्शन है:

#simple image scaling to (nR x nC) size
def scale(im, nR, nC):
  nR0 = len(im)     # source number of rows 
  nC0 = len(im[0])  # source number of columns 
  return [[ im[int(nR0 * r / nR)][int(nC0 * c / nC)]  
             for c in range(nC)] for r in range(nR)]

उदाहरण उपयोग: (30 x 30) छवि का आकार (100 x 200):

import matplotlib.pyplot as plt

def sqr(x):
  return x*x

def f(r, c, nR, nC):
  return 1.0 if sqr(c - nC/2) + sqr(r - nR/2) < sqr(nC/4) else 0.0

# a red circle on a canvas of size (nR x nC)
def circ(nR, nC):
  return [[ [f(r, c, nR, nC), 0, 0] 
             for c in range(nC)] for r in range(nR)]

plt.imshow(scale(circ(30, 30), 100, 200))

आउटपुट: स्केल की गई छवि

यह छवियों को छोटा / स्केल करने के लिए काम करता है, और सुन्न सरणियों के साथ ठीक काम करता है।


4

SciPy का imresize()तरीका एक और आकार बदलने वाला तरीका था, लेकिन इसे SciPy v 1.3.0 के साथ शुरू कर दिया जाएगा। SciPy PIL छवि आकार परिवर्तन विधि को संदर्भित करता है :Image.resize(size, resample=0)

आकार - पिक्सेल में अनुरोधित आकार, 2-ट्यूपल के रूप में: (चौड़ाई, ऊंचाई)।
resample - एक वैकल्पिक resampling फ़िल्टर। यह PIL.Image.NEAREST (निकटतम पड़ोसी का उपयोग करें), PIL.Image.BILINEAR (रैखिक प्रक्षेप), PIL.Image.BICUBIC (घन वर्तनी प्रक्षेप), या PIL.Image.LANCZOS (एक उच्च गुणवत्ता वाला डाउनसमलिंग फ़िल्टर हो सकता है) )। यदि छोड़ा गया है, या यदि छवि में "1" या "P" मोड है, तो यह PIL.Image.NEAREST सेट है।

यहां लिंक करें: https://pillow.readthedocs.io/en/3.1.x/reference/Image.html#PIL.Image.Image.resize


3
दुर्भाग्य से, imresize () पदावनत है, इसे SciPy 1.3.0 में निकाल दिया जाएगा
MiniQuark

1

वहाँ किसी भी पुस्तकालयों ऐसा करने के लिए numpy / SciPy में हैं

ज़रूर। आप इसे OpenCV, स्किट-इमेज या PIL के बिना कर सकते हैं।

छवि का आकार बदलना मूल छवि से प्रत्येक पिक्सेल के निर्देशांक को मूल रूप से आकार में मैप करना है।

चूंकि एक छवि के निर्देशांक पूर्णांक होना चाहिए (इसे मैट्रिक्स के रूप में सोचो), यदि मैप किए गए समन्वय में दशमलव मान हैं, तो आपको पूर्णांक स्थिति में अनुमानित करने के लिए पिक्सेल मान को प्रक्षेपित करना चाहिए (उदाहरण के लिए उस स्थिति में निकटतम पिक्सेल प्राप्त करना) के रूप में निकटतम पड़ोसी प्रक्षेप )।

आपको बस एक फ़ंक्शन की आवश्यकता है जो आपके लिए यह प्रक्षेप करता है। SciPy है interpolate.interp2d

आप इसका उपयोग arrइस प्रकार है:

W, H = arr.shape[:2]
new_W, new_H = (600,300)
xrange = lambda x: np.linspace(0, 1, x)

f = interp2d(xrange(W), xrange(H), arr, kind="linear")
new_arr = f(xrange(new_W), xrange(new_H))

बेशक, यदि आपकी छवि RGB है, तो आपको प्रत्येक चैनल के लिए प्रक्षेप करना होगा।

यदि आप अधिक समझना चाहते हैं, तो मैं सुझाव दे रहा हूं कि आकार बदलने वाली छवियां - कंप्यूटरफाइल


इस उत्तर के आधार पर काम नहीं कर सकते: stackoverflow.com/questions/37872171/…
random_dsp_guy

0
import cv2
import numpy as np

image_read = cv2.imread('filename.jpg',0) 
original_image = np.asarray(image_read)
width , height = 452,452
resize_image = np.zeros(shape=(width,height))

for W in range(width):
    for H in range(height):
        new_width = int( W * original_image.shape[0] / width )
        new_height = int( H * original_image.shape[1] / height )
        resize_image[W][H] = original_image[new_width][new_height]

print("Resized image size : " , resize_image.shape)

cv2.imshow(resize_image)
cv2.waitKey(0)

4
StackOverflow में आपका स्वागत है। महान कि आप उनके सवालों के जवाब देकर दूसरों की मदद करना चाहते हैं। हालाँकि, मैं यह नहीं देखता कि मौजूदा उत्तर की तुलना में आपका उत्तर कैसे मूल्य जोड़ता है जो पहले से ही उपयोग cv2और उपयोग करता है एक "उप-इष्टतम" आकार बदलने वाले फ़ंक्शन को फिर से लागू करने के बजाय एक उचित रिसाइज़ फ़ंक्शन का उपयोग करता है जो निकटतम पड़ोसी प्रक्षेप से भी बदतर है।
15
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.