홈>
이미지 작업을 시작했으며 현재 이미지 크기를 조정하고 그레이 스케일하려고합니다 (크기 6000x4000->600x400)로 더 잘 작동합니다. 이를 위해 Numpy 및 PIL.Images를 사용하고 있습니다.
import PIL.Image as Img
import numpy as np
img = Img.open('rendering/testpic.jpg', 'r')
r, g, b = img.split()
channels = np.array([np.array(r), np.array(g), np.array(b)])
small_channels = []
for channel in channels:
x_len = len(channel)//10
y_len = len(channel[0])//10
for chunk_x in range(x_len):
for chunk_y in range(y_len):
pix_sum = 0
for x_in_chunk in range(10):
for y_in_chunk in range(10):
pix_sum += channel[chunk_x*10+x_in_chunk,chunk_y*10+y_in_chunk]
channel[chunk_x,chunk_y] = pix_sum // 100
small_channels.append(channel[:x_len,:y_len])
channels = np.array(small_channels)
grayscale = np.round((channels[0]*0.3+ channels[1]*0.6+ channels[2]*0.1)).astype('uint8')
pixels = np.stack([grayscale, grayscale, grayscale], axis = 2)
new_img = Img.fromarray(pixels)
new_img.show()
그래서 내가하고있는 일은 채널을 청크 크기 10으로 청크 한 다음 청크의 평균을 왼쪽 위 모서리에 매핑하는 것입니다. 결국 나는 그림의 나머지 부분을 잘라 냈다.
전체적으로 이것은 약 100 ~ 130 초가 걸립니다. 더 빠른 방법이 있습니까? 비효율적 인 곳은 어디입니까? 나는 새로운 것이므로 아마 많은 일을 잘못하고있을 것입니다. 예를 들어 Photoshop은 어떻게 사진을 빠르게 확대 및 축소합니까?
- 답변 # 1
- 답변 # 2
이 경우 루프를 사용하지 않을 것입니다.
cv2.resize()
일을 할 것입니다.다음은 세 가지 접근법 사이의 시간 비교입니다.
import PIL.Image as Img import numpy as np from time import perf_counter import cv2 def timer(method): def timed(*args, **kwargs): t1 = perf_counter() result = method(*args, **kwargs) t2 = perf_counter() print(f'{method.__name__} time: {t2 - t1} seconds') return result return timed @timer def resize_1(image_path, shrink): img = Img.open(image_path, 'r') r, g, b = img.split() channels = np.array([np.array(r), np.array(g), np.array(b)]) small_channels = [] for channel in channels: x_len = len(channel)//shrink y_len = len(channel[0])//shrink for chunk_x in range(x_len): for chunk_y in range(y_len): pix_sum = 0 for x_in_chunk in range(shrink): for y_in_chunk in range(shrink): pix_sum += channel[chunk_x*shrink+x_in_chunk,chunk_y*shrink+y_in_chunk] channel[chunk_x,chunk_y] = pix_sum // 100 small_channels.append(channel[:x_len,:y_len]) channels = np.array(small_channels) grayscale = np.round((channels[0]*0.3+ channels[1]*0.6+ channels[2]*0.1)).astype('uint8') pixels = np.stack([grayscale, grayscale, grayscale], axis = 2) return Img.fromarray(pixels) @timer def resize_2(image_path, shrink): img = Img.open(image_path, 'r') r, g, b = img.split() channels = np.array([np.array(r), np.array(g), np.array(b)]) small_channels = [] for channel in channels: x_len = len(channel)//shrink y_len = len(channel[0])//shrink for chunk_x in range(x_len): for chunk_y in range(y_len): # slice all pixels within 10*10 box and sum them pix_sum = channel[chunk_x*shrink:shrink*(chunk_x+1), chunk_y*shrink:shrink*(chunk_y+1)].sum() channel[chunk_x, chunk_y] = pix_sum // 100 small_channels.append(channel[:x_len,:y_len]) channels = np.array(small_channels) grayscale = np.round((channels[0]*0.3+ channels[1]*0.6+ channels[2]*0.1)).astype('uint8') pixels = np.stack([grayscale, grayscale, grayscale], axis = 2) return Img.fromarray(pixels) @timer def resize_3(image_path, shrink): image = cv2.imread(image_path) size = image.shape[:-1] new_size = tuple(int(item / shrink) for item in size)[::-1] resized = cv2.resize(image, tuple(new_size)) gray = cv2.cvtColor(resized, cv2.COLOR_BGR2GRAY) return gray if __name__ == '__main__': img = 'sample_image.png' shrink_by = 10 image1, image2, image3 = [item(img, shrink_by) for item in [resize_1, resize_2, resize_3]] image1.show() image2.show() cv2.imshow('resize_3', image3) cv2.waitKey(0) cv2.destroyAllWindows()
밖:
resize_1 time: 1.980221013 seconds resize_2 time: 0.3170622839999999 seconds resize_3 time: 0.01659756599999973 seconds
관련 자료
- 파이썬에서 전체 numpy 배열을 사용자 정의 함수에 인수로 전달하는 방법은 무엇입니까?
- 3D numpy 배열을 2 그룹으로 나누기 python
- python 3.x - numpy - 2d 배열 행렬의 크기?
- Numpy를 사용하여 Python에서 열의 로그를 어떻게 가져올 수 있습니까?
- numpy의`full ()`메서드와 파이썬 목록을 사용하여 numpy 배열을 만들 수 없습니다
- python - numpy 배열을 단일 정수로 병합
- 파이썬은 텍스트 파일을 단어 배열로 읽습니다
- python - numpy 배열의 데이터 쌍을 이루는 알고리즘을 개발하는 방법
- python - Pyspark 데이터 프레임에 Numpy 배열 추가
- python - numpy 배열의 올바른 색인 얻기
- python - 문자열로 채워진 numpy 배열 (모양 (n, m))에서 모든 값의 첫 번째 문자를 얻는 방법
- 파이썬에서 0으로 채우는 배열
- multiprocessing - Python 신호 처리, 여러 프로세스 종료
- pandas 및 numpy로 Python에서 행렬 만들기
- Python의 if 문에서 값 배열 만들기
- string - 파이썬 목록을 bash 배열로 변환
- Python 목록 이해가 새 배열에 할당되지 않았습니다
- python - 인덱스를 매개 변수로 사용하는 객체로 2D numpy 배열 채우기
- python - numpy 배열을 데이터 프레임으로 변환
- python - 데이터 빈도에 따라 numpy 배열에 쌍을 만드는 방법
이미지의 모든 픽셀을 반복하는 대신 사용할 수 있습니다.
numpy
배열 슬라이싱과 몇 가지 방법으로 속도를 높일 수 있습니다. 내부 루프를 제거하고 슬라이싱을 사용했습니다..sum()
의 방법numpy
배열 :이 알고리즘은 테스트를 통해 3-4 배 더 빠릅니다. 이게 도움이 되길 바란다. 확실히 봐
numpy
배열-이미지에 특히 유용하며 많은 경우 계산이 더 빠릅니다.