programing

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

css3 2023. 6. 4. 22:26

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

저는 이미지를 찍어서 이미지의 스케일을 바꾸고 싶은데, 그것은 numpy 배열입니다.

예를 들어, 저는 코카콜라 병의 이미지를 가지고 있습니다: bottle-1.

그것은 형태의 엉터리 배열로 해석됩니다.(528, 203, 3)그리고 저는 이 두 번째 이미지의 크기를 말하기 위해 크기를 조정하고 싶습니다: bottle-2.

은 을모양하있는것고의의 있습니다.(140, 54, 3).

원래 이미지를 유지하면서 이미지 크기를 특정 모양으로 변경하려면 어떻게 해야 합니까?다른 답변들은 다른 모든 또는 세 번째 행을 제거할 것을 제안하지만, 제가 하고 싶은 것은 기본적으로 이미지 편집기를 통해 파이썬 코드로 하는 것처럼 이미지를 축소하는 것입니다.numpy/SciPy에서 이것을 할 수 있는 라이브러리가 있습니까?

예, 설할수 있니다를 설치할 수 .opencv(이미지 처리 및 컴퓨터 비전에 사용되는 라이브러리입니다.) 기능을 사용합니다.예를 들어 다음을 사용합니다.

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에 보간법

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

Numpy를 단독으로 사용하여 이 작업을 수행할 수는 있지만 이 작업은 기본 제공되지 않습니다.그렇긴 하지만, 당신은 사용할 수 있습니다.scikit-image(numpy를 기반으로 함) 이런 종류의 이미지 조작을 수행합니다.

Scikit-Image 리스케일링 설명서는 여기에 있습니다.

예를 들어 이미지에서 다음 작업을 수행할 수 있습니다.

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

이것은 당신을 위해 인터폴, 앤티앨리어싱 등을 처리할 것입니다.

다운샘플링을 위한 한 줄 numpy 솔루션(2개):

smaller_img = bigger_img[::2, ::2]

업샘플링(2회):

bigger_img = smaller_img.repeat(2, axis=0).repeat(2, axis=1)

(이것은 HxWxC 모양의 이미지를 가정합니다.이 메서드는 전체 정수 크기 조정만 허용합니다(예: 2배이지만 1.5배는 허용되지 않음).

구글에서 이곳으로 오는 사람들을 위해 이미지를 다운샘플링하는 빠른 방법을 찾고 있습니다.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)

그레이스케일 영상의 경우 다음을 변경합니다.31다음과 같이:

채널 첫 번째 순서

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

이 방법은 최대 풀링과 동등한 값을 사용합니다.이것이 제가 찾은 가장 빠른 방법입니다.

추가 라이브러리를 사용하지 않고 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 배열에서 잘 작동합니다.

numpy 배열 배치의 크기를 조정(보간)하려는 사용자를 위해, 파이토치는 더 빠른 함수 이름 torch.n.functional을 제공합니다.batchxWxHx3에서 batchx3xWxH로 채널을 변경하려면 np.transpose를 먼저 사용해야 합니다.

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

size – 요청한 크기(픽셀), 2-튜플: (폭, 높이).
resample – 재샘플링 필터(선택 사항).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

몇 년 후에 우연히 이 사실을 알게 되었습니다.지금까지의 답변은 다음과 같은 몇 가지 범주 중 하나로 분류됩니다.

  1. 외부 라이브러리 사용(OpenCV, SciPy 등)
  2. 사용자의 2배 확장
  3. 가장 가까운 이웃 사용

이 솔루션들은 모두 존경할 만한 것들이기 때문에, 저는 이것을 완전성을 위해서만 제공합니다.위에 비해 세 가지 이점이 있습니다. (1) 2의 거듭제곱이 아닌 스케일링 팩터에서도 임의 해상도를 수용할 수 있습니다. (2) 외부 라이브러리가 없는 순수 Python+Numpy를 사용합니다. (3) 모든 픽셀을 보간하여 '더 좋아 보이는' 결과를 얻을 수 있습니다.

Numpy를 잘 사용하지 않으므로 특히 큰 이미지의 경우 속도가 빠르지 않습니다.더 작은 이미지의 크기만 조정하는 경우에는 문제가 없습니다.사용자의 재량에 따라 Apache 또는 MIT 라이센스로 제공합니다.

import math
import numpy

def resize_linear(image_matrix, new_height:int, new_width:int):
    """Perform a pure-numpy linear-resampled resize of an image."""
    output_image = numpy.zeros((new_height, new_width), dtype=image_matrix.dtype)
    original_height, original_width = image_matrix.shape
    inv_scale_factor_y = original_height/new_height
    inv_scale_factor_x = original_width/new_width

    # This is an ugly serial operation.
    for new_y in range(new_height):
        for new_x in range(new_width):
            # If you had a color image, you could repeat this with all channels here.
            # Find sub-pixels data:
            old_x = new_x * inv_scale_factor_x
            old_y = new_y * inv_scale_factor_y
            x_fraction = old_x - math.floor(old_x)
            y_fraction = old_y - math.floor(old_y)

            # Sample four neighboring pixels:
            left_upper = image_matrix[math.floor(old_y), math.floor(old_x)]
            right_upper = image_matrix[math.floor(old_y), min(image_matrix.shape[1] - 1, math.ceil(old_x))]
            left_lower = image_matrix[min(image_matrix.shape[0] - 1, math.ceil(old_y)), math.floor(old_x)]
            right_lower = image_matrix[min(image_matrix.shape[0] - 1, math.ceil(old_y)), min(image_matrix.shape[1] - 1, math.ceil(old_x))]

            # Interpolate horizontally:
            blend_top = (right_upper * x_fraction) + (left_upper * (1.0 - x_fraction))
            blend_bottom = (right_lower * x_fraction) + (left_lower * (1.0 - x_fraction))
            # Interpolate vertically:
            final_blend = (blend_top * y_fraction) + (blend_bottom * (1.0 - y_fraction))
            output_image[new_y, new_x] = final_blend

    return output_image

샘플 크기 조정:

원본:

절반으로 축소:

1 및 1/4로 상향 조정:

numpy/SciPy에서 이 작업을 수행할 라이브러리가 있습니까?

물론입니다. OpenCV, 스크킷 이미지 또는 PIL 없이도 이 작업을 수행할 수 있습니다.

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

영상의 좌표는 정수여야 하므로(매트릭스로 생각) 매핑된 좌표에 십진수 값이 있는 경우 픽셀 값을 보간하여 정수 위치에 근접시켜야 합니다(예: 해당 위치에 가장 가까운 픽셀을 얻는 것을 근거리 보간이라고 함).

당신에게 필요한 것은 이 보간을 해주는 기능입니다.SciPy가.

Numpy 배열의 이미지 크기를 조정하는 데 사용할 수 있습니다.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이면 각 채널에 대해 보간을 수행해야 합니다.

좀 더 이해하고 싶다면, 이미지 크기 조정 - 컴퓨터 파일을 보는 것을 추천합니다.

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)

언급URL : https://stackoverflow.com/questions/48121916/numpy-resize-rescale-image