Kernel Convolution in Python 2.7 The code I wrote performs a mean blur on an image (I hardcoded it as zebra.jpg for testing purposes).
My problem is that for an image of 39KB image it take minutes to perform, is there any way of making this code more efficient?
Preferably using built in python modules.
Also is there any way of improving my code in other ways?

from PIL import Image
img = Image.open('zebra.jpg')

img_w = img.size[0]
img_h = img.size[1]

# The bigger the kernel size, the more intense the blur
kernel = [[1]*10]*10

outputIm = Image.new("RGB", (img_w, img_h))
d = []
for y in range(0, int(img_h)):
    for x in range(0, int(img_w)):
        r, g, b, count = 0, 0, 0, 0
        index_y = int((len(kernel[0]) - 1) / 2.0) * -1

        for kernel_offset_y in kernel:
            index_x = int((len(kernel_offset_y) - 1) / 2.0) * -1

            for kernel_val in kernel_offset_y:

                if img_w &gt; x + index_x+1 &gt; 0 and img_h &gt; y + index_y+1 &gt; 0:
                    temp_r, temp_g, temp_b = img.getpixel((int(x + index_x), int(y + index_y)))
                    r += temp_r * kernel_val
                    g += temp_g * kernel_val
                    b += temp_b * kernel_val
                    count += 1
                    index_x += 1
            index_y += 1

        if (r &gt; 0):
            r = r / count
        if (g &gt; 0):
            g = g / count
        if (b &gt; 0):
            b = b / count

        d.append((r,g,b))

outputIm.putdata([tuple(pixel) for pixel in d])
outputIm.save('blurred.jpg')
Unnecessary type conversions

There are a couple of unnecessary type conversions, for example:


index_y = int((len(kernel[0]) - 1) / 2.0) * -1



Casting to int truncates, but so does integer division.
So you can simplify the above with:

index_y = -(len(kernel_offset_y) - 1) // 2


In Python 2 integer division truncates by default,
so ... / 2 would work too.
But not in Python 3, where the behavior was changed.
Using // works in Python 2.7 and Python 3 consistently.

I also replaced the * -1 with a simpler - prefix.



On this line, x, index_x, y and index_y are all integers,
so no need to convert them to int:


temp_r, temp_g, temp_b = img.getpixel((int(x + index_x), int(y + index_y)))





This is also unnecessary:


outputIm.putdata([tuple(pixel) for pixel in d])



Since d is already a list of tuples, you could write simply:

outputIm.putdata(d)


Simplify

The default start value of range is 0, so instead of range(0, k) you could write range(k).

Instead of x = x / y you could write x /= y.

The parentheses are unnecessary in if (expr):.

Formatting

Instead of this:


kernel = [[1]*10]*10



PEP8 recommends this writing style:

kernel = [[1] * 10] * 10