>

이미지 작업을 시작했으며 현재 이미지 크기를 조정하고 그레이 스케일하려고합니다 (크기 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

    이미지의 모든 픽셀을 반복하는 대신 사용할 수 있습니다. numpy 배열 슬라이싱과 몇 가지 방법으로 속도를 높일 수 있습니다. 내부 루프를 제거하고 슬라이싱을 사용했습니다. .sum() 의 방법 numpy 배열 :

    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):
                # slice all pixels within 10*10 box and sum them
                pix_sum = channel[chunk_x*10:10*(chunk_x+1),chunk_y*10:10*(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)
    new_img = Img.fromarray(pixels)
    new_img.show()
    
    

    이 알고리즘은 테스트를 통해 3-4 배 더 빠릅니다. 이게 도움이 되길 바란다. 확실히 봐 numpy 배열-이미지에 특히 유용하며 많은 경우 계산이 더 빠릅니다.

  • 답변 # 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
    
    

  • 이전 tensorflow - Lenet5와 유사한 아키텍처를 사용하여 '101 개 오브젝트 범주'데이터를 분류 할 때 예상보다 높은 정확도 확보
  • 다음 테라 폼을 사용하여 Azure App Service를 응용 프로그램 통찰력 리소스 (신규 또는 기존)와 연결하는 방법은 무엇입니까?