Numpy 크기 조정 / 크기 조정 이미지


98

이미지를 가져 와서 이미지의 크기를 변경하고 싶지만 numpy 배열입니다.

예를 들어 코카콜라 병 이미지가 있습니다. bottle-1

이것은 numpy 배열의 모양으로 변환되며 (528, 203, 3)두 번째 이미지의 크기를 말하도록 크기를 조정하고 싶습니다. bottle-2

모양이 (140, 54, 3).

원본 이미지를 유지하면서 이미지 크기를 특정 모양으로 변경하려면 어떻게합니까? 다른 답변은 다른 모든 행 또는 세 번째 행을 제거하는 것이 좋지만 기본적으로 이미지 편집기를 사용하지만 Python 코드로 이미지를 축소하는 것입니다. numpy / SciPy에서이를 수행 할 라이브러리가 있습니까?


numpy 배열에 대한 코드를 보여줄 수 있습니까?
ShpielMeister


2
@sascha 링크 한 페이지에 따르면 더 이상 사용되지 않습니다.
Paul Panzer

@ShpielMeister 나는 IntelliJ가 numpy 배열을 완전히 출력하도록 할 수 없습니다. 어떤 이유로 출력이 클 때 항상 출력하므로 콘솔에서 배열 출력의 일부만 볼 수 있습니다
Brian Hamill

답변:


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-픽셀 영역 관계를 사용한 리샘플링. 무아레없는 결과를 제공하므로 이미지 데시 메이션에 선호되는 방법 일 수 있습니다. 그러나 이미지를 확대하면 INTER_NEAREST방법 과 비슷합니다 .
  • INTER_CUBIC -4x4 픽셀 이웃에 대한 쌍 입방 보간
  • INTER_LANCZOS4 -8x8 픽셀 이웃에 대한 Lanczos 보간

대부분의 옵션과 마찬가지로 모든 크기 조정 스키마에 대해 하나의 전략이 다른 전략보다 선호 될 수있는 시나리오가 있다는 점에서 "최상의"옵션은 없습니다.


5
방금이 코드를 사용해 보았는데 작동합니다! 단지 하나의 변화 즉 dsize되어야 dsize=(54, 140)는 다음 예를 X 걸리는 Y로서 NumPy와 배열 쇼 형태로 다음 X (Y 행의 수이고, x는 열 번호) 여기서로
브라이언 해밀을

6
나는 cv2를 피하려고 노력하고, 크기를 바꾸고 BGR 채널 형식으로로드합니다. 나는 선호 skimage.io.imread('image.jpg')하고 skimage.transform.resize(img). scikit-image.org/docs/dev/install.html
Eduardo Pignatelli

1
@EduardoPignatelli 사용하는 보간 알고리즘을 제어 할 수 없기 때문에 skimage.transform.resize를 피합니다. 그러나 사람들의 사용 사례에 따라 중요하지 않을 수 있습니다.
Decker

2
@Decker skimage.transform.resize는 'order'매개 변수를 통해 일부 제어를 제공합니다. order = 0은 가장 가까운 이웃, 1 = bi-linear, 2 = bi-quadratic, 3 = bi-cubic 등입니다. 그러나 면적 평균이나 lanczos 보간은 없습니다.
Tapio

1
@TapioFriberg 아 예, 정정되었습니다. skimage.transform.warp의 'order'매개 변수에 대한 문서에 정의 된 알고리즘이 있습니다. 예를 들어 문서의 다른 곳에서 정의되지 않은 "Bi-quartic"유형에 대한 참조를 포함하도록 문서를 업데이트하는 것이 어느 시점에서 도움이 될 수 있습니다 (2019 년 12 월 10 일 기준). 미래 사용자에게 유익합니다.
Decker

67

이를 위해 numpy 만 사용하는 것이 가능할 수 있지만이 작업은 내장되어 있지 않습니다. 즉, scikit-image(numpy에 구축 된)을 사용하여 이러한 종류의 이미지 조작을 수행 할 수 있습니다 .

Scikit-Image rescaling 문서는 여기에 있습니다 .

예를 들어 이미지로 다음을 수행 할 수 있습니다.

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

이것은 보간, 앤티 앨리어싱 등과 같은 것들을 처리 할 것입니다.


2
감사합니다! 이 답변도 작동합니다! anti_aliasing플래그에 문제가 있지만 0.13.1의
Brian Hamill

8
원본 이미지가 uint8 인 경우에도 이미지를 float ndarray 로 반환합니다.
sziraqui

3
이것은 여러 채널에서 작동하기 때문에 좋은 기술입니다. 깊이 포인트 클라우드 데이터와 결합 된 rgb 데이터로 이것을 시도했고 내가 원하는대로 관계를 유지했습니다.
Darth Egregious 2019

@DarthEgregious, jakevdp-> 설명한 방법과 같이 (137,236,3) 배열의 크기를 (64,64)로 조정했을 때 내 임의의 노이즈 데이터를 단색으로 만들었습니다. 모든 정보를 잃어버린 것처럼 보이므로 정상입니까?
Deshwal

1
(64,64,3)
Darth

14

numpy머신 러닝 애플리케이션에서 사용하기 위해 배열 에서 이미지를 다운 샘플링하는 빠른 방법을 찾고있는 Google에서 여기에 오는 사람들을 위해 여기에서 채택한 초고속 방법이 있습니다 . 이 방법은 입력 차원이 출력 차원의 배수 인 경우에만 작동합니다.

다음 예제는 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
large_image [:, :: 2, :: 2]는 해상도가 절반 인 이미지를 반환합니다.
L. Kärkkäinen

1
@ LasseKärkkäinen이지만 다운 샘플링하지 않고 다른 모든 픽셀 만 선택합니다. 차이점은 최종 함수 'max'를 변경하여 약간 더 나은 방식으로 픽셀을 선택하거나 계산할 수 있다는 것입니다 (예 : 'min'또는 'mean'사용). 중요하지 않은 경우 귀하의 방법이 유용하고 빠릅니다.
Waylon Flinn

@ L.Kärkkäinen 이중 해상도의 반대는 무엇입니까?
rayzinnz

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

11

추가 라이브러리를 사용하지 않고 Python에서 이미지 크기를 조정 / 크기 조정하는 간단한 방법을 찾는 사람이 있다면 여기에 매우 간단한 이미지 크기 조정 기능이 있습니다.

#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))

산출: 축척 된 이미지

이것은 이미지를 축소 / 크기 조정하는 데 작동하며 numpy 배열에서 잘 작동합니다.


4

SciPy의 imresize()방법은 또 다른 크기 조정 방법 이었지만 SciPy v 1.3.0부터 제거됩니다. SciPy는 PIL 이미지 크기 조정 방법을 나타냅니다 .Image.resize(size, resample=0)

size – 요청 된 크기 (픽셀 단위), 2- 튜플 : (너비, 높이).
재 샘플 – 선택적 리샘플링 필터입니다. 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, scikit-image 또는 PIL없이이 작업을 수행 할 수 있습니다.

이미지 크기 조정은 기본적으로 원본 이미지의 각 픽셀 좌표를 크기 조정 된 위치로 매핑하는 것입니다.

이미지의 좌표는 정수 여야하므로 (매트릭스라고 생각하면) 매핑 된 좌표에 십진수 값이있는 경우 픽셀 값을 보간하여 정수 위치에 근사해야합니다 (예 : 해당 위치에 가장 가까운 픽셀을 얻는 것은 알려져 있음). 같은 가장 가까운 이웃 보간법 ).

이 보간을 수행하는 함수 만 있으면됩니다. SciPy에는 interpolate.interp2d.

이를 사용하여 arr다음과 같이 numpy 배열의 이미지 크기를 조정할 수 있습니다 .

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이 가장 가까운 이웃 보간보다 더 나쁜 "차선책"크기 조정 기능을 다시 구현하는 대신 적절한 크기 조정 기능 을 이미 사용 하고 사용하는 기존 답변과 비교하여 어떻게 가치를 추가하는지 알 수 없습니다 .
NOhs
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.