uint16
축소 및 변환하려는 데이터의 매우 큰 이미지 배열을 다루고 uint8
있습니다.
이 작업을 수행하는 초기 방법은 MemoryError
중간 float64
배열로 인해 발생했습니다 .
img = numpy.ones((29632, 60810, 3), dtype=numpy.uint16)
if img.dtype == numpy.uint16:
multiplier = numpy.iinfo(numpy.uint8).max / numpy.iinfo(numpy.uint16).max
img = (img * multiplier).astype(numpy.uint8, order="C")
그런 다음 다음과 같은 방법으로 곱셈을 시도했습니다.
if img.dtype == numpy.uint16:
multiplier = numpy.iinfo(numpy.uint8).max / numpy.iinfo(numpy.uint16).max
img *= multiplier
img = img.astype(numpy.uint8, order="C")
하지만 다음 오류가 발생합니다.
TypeError: Cannot cast ufunc multiply output from dtype('float64') to dtype('uint16') with casting rule 'same_kind'
메모리 공간을 최소화하면서이 작업을 수행하는 방법을 알고 있습니까?
오류 메시지에 언급 된 캐스팅 규칙은 어디에서 변경할 수 있나요?
이러한 경우 Numba 또는 Cython을 사용할 수도 있습니다.
임시 배열을 명시 적으로 피할 수 있습니다. 코드는 조금 더 길지만 이해하기 쉽고 빠릅니다.
예
import numpy as np
import numba as nb
@nb.njit(parallel=True)
def conv_numba(img):
multiplier = np.iinfo(np.uint8).max / np.iinfo(np.uint16).max
img_out=np.empty(img.shape,dtype=np.uint8)
for i in nb.prange(img.shape[0]):
for j in range(img.shape[1]):
for k in range(img.shape[2]):
img_out[i,j,k]=img[i,j,k]*multiplier
return img_out
#img_in have to be contigous, otherwise reshape will fail
@nb.njit(parallel=True)
def conv_numba_opt(img_in):
multiplier = np.iinfo(np.uint8).max / np.iinfo(np.uint16).max
shape=img_in.shape
img=img_in.reshape(-1)
img_out=np.empty(img.shape,dtype=np.uint8)
for i in nb.prange(img.shape[0]):
img_out[i]=img[i]*multiplier
return img_out.reshape(shape)
def conv_numpy(img):
np.multiply(img, multiplier, out=img, casting="unsafe")
img = img.astype(np.uint8, order="C")
return img
타이밍
img = np.ones((29630, 6081, 3), dtype=np.uint16)
%timeit res_1=conv_numpy(img)
#990 ms ± 2.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit res_2=conv_numba(img)
#with parallel=True
#122 ms ± 17.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
#with parallel=False
#571 ms ± 2.99 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다