[PYTHON] Image processing 100 knocks Q9, Q10 (filter) speedup

Recently I started knocking 100 images. https://qiita.com/yoyoyo_/items/2ef53f47f87dcf5d1e14

Recently, I was a little interested in image processing and wanted to use numpy well, so I am very grateful for this collection of problems, but I am dissatisfied with the answer examples of Q.9. Gaussian filter and Q.10. Median filter. There was (I don't want to use the for statement in python!), So I wrote a process that uses numpy as much as possible and compared the speed.

The code I wrote this time:

def gaussian_filter(_img, filter_matrix):
    # assume that fY and fX is odd number
    (fY, fX) = filter_matrix.shape
    mY = (fY - 1) // 2
    mX = (fX - 1) // 2

    (Y, X, C) = _img.shape
    img = np.zeros((Y + mY*2, X + mX*2, C))
    img[mY:Y+mY, mX:X+mX, :] = _img

    out_img = np.zeros_like(_img, np.float32)
    for dy in range (fY):
        for dx in range(fX):
            out_img += filter_matrix[dy][dx] * img[dy:Y+dy, dx:X+dx, :]
    return out_img.astype(np.uint8)

By turning y, x of filter_matrix with for instead of y, x of the image, the addition in the image can use for of numpy. Speed comparison We called gaussian_filter 100 times and compared how many seconds it took. Since the time command is used, the time for one image load is included, but I don't think it will affect many people.

Method time
This code 0.72
Model answer 50.60

Isn't it overwhelming? Our army is ~ ~ ~ Q10. Regarding the median filter, I think that it can be speeded up by creating an image (?) Of H * W * (filter_size) and then doing np.median (axis = 2) on that image. .. ~~ It's done.

def median_filter(_img, filter_size):
    # assume that filter_size is odd
    half_size = (filter_size - 1) // 2
    (Y, X, C) = _img.shape
    img = np.zeros((Y + half_size*2, X + half_size*2, C))
    img[half_size:Y+half_size, half_size:X+half_size, :] = _img

    out_img = np.zeros_like(_img)
    for c in range(C):
        big_ch_img = np.zeros((Y, X, filter_size**2))
        for fy in range(filter_size):
            for fx in range(filter_size):
                ch = fy * filter_size + fx
                big_ch_img[:,:,ch] = img[fy:fy+Y, fx:fx+X,c]
        out_img[:,:,c] = np.median(big_ch_img, axis=2)
    return out_img

The measurement time was 1.71 seconds vs 302.98 seconds.

By the way, I haven't come up with a way to avoid using the for statement for Pooling, so please let me know if anyone knows.

Recommended Posts

Image processing 100 knocks Q9, Q10 (filter) speedup
Image processing 100 knocks ①
Image processing with Python 100 knocks # 9 Gaussian filter
100 image processing knocks !! (011 --020) Early game
100 image processing knocks !! (001 --010) Carefully and carefully
Image processing with Python 100 knocks # 3 Binarization
Image processing with Python 100 knocks # 2 Grayscale
Image processing with Python 100 knock # 10 median filter
Image processing with Python 100 knocks # 8 Max pooling
Image processing with Python 100 knock # 12 motion filter
Image processing with Python 100 knocks # 7 Average pooling
Image processing 100 knock Q.6. Color reduction processing explanation
100 language processing knocks 03 ~ 05
[Image processing] Posterization
100 language processing knocks (2020): 40
100 language processing knocks (2020): 32
100 language processing knocks (2020): 35
python image processing
100 language processing knocks (2020): 47
100 language processing knocks (2020): 39
100 language processing knocks (2020): 22
100 language processing knocks (2020): 26
100 language processing knocks (2020): 34
100 language processing knocks (2020): 29
100 language processing knocks (2020): 49
100 language processing knocks 06 ~ 09
100 language processing knocks (2020): 43
100 language processing knocks (2020): 24
100 language processing knocks (2020): 45
100 language processing knocks (2020): 10-19
100 language processing knocks (2020): 30
100 language processing knocks (2020): 00-09
100 language processing knocks (2020): 31
100 language processing knocks (2020): 48
100 language processing knocks (2020): 44
100 language processing knocks (2020): 41
100 language processing knocks (2020): 37
100 language processing knocks (2020): 25
100 language processing knocks (2020): 23
100 language processing knocks (2020): 33
100 language processing knocks (2020): 20
100 language processing knocks (2020): 27
100 language processing knocks (2020): 46
100 language processing knocks (2020): 21
100 language processing knocks (2020): 36
(Image processing) Petit Thinning --Filter that performs loose thinning processing
Image processing by Python 100 knock # 11 smoothing filter (average filter)
100 amateur language processing knocks: 41
100 amateur language processing knocks: 71
100 amateur language processing knocks: 56
100 amateur language processing knocks: 24
100 amateur language processing knocks: 50
100 amateur language processing knocks: 59
100 amateur language processing knocks: 70
Image processing with MyHDL
100 amateur language processing knocks: 62
100 amateur language processing knocks: 60
100 amateur language processing knocks: 92
100 image processing knocks !! (021-030) I want to take a break ...
100 amateur language processing knocks: 30
100 amateur language processing knocks: 84