I have an image which consists of two arbitrarily placed black 1px “blobs” on a white canvas 100px by 200px. I’m trying to “blur these blobs by turning some of the neighbouring pixels (within a radius of 10px of each blob) black also. I’ve put together the following code, but am not quite sure of the next step..
import numpy as np
from PIL import Image
from scipy import ndimage
from matplotlib import pyplot
from matplotlib import cm
from scipy.misc import imsave
im = Image.open("test.png")
pix = np.asarray(im)
new_pix = np.copy(pix[:,:,0]) # need this otherwise can't write to the pix array.
pix_to_enlarge = np.where(new_pix != 255)
pixels_to_enlarge_by = 10
i=0
for each_pixel in pix_to_enlarge[0]: # this cycles through each non-white pixel
for y in range(len(new_pix)): # this looks across the length (down) the page
for x in new_pix[y]: # this looks across the x-axis for each y step
radius = pixels_to_enlarge_by**2
so essentially I’ve found the locations of the non-white pixels in the variable pixels_to_enlarge_by. What I’m trying (and so far failing to do) is to select the surrounding pixels (within 10px) and change them to black also. Any ideas?
In one way or the other you need to look at each pixel and then figure out how much of that content you want to distribute to each other pixel in your picture, for example by comparing the distance between the two.
Here’s how it’s done with numpy. If you want to do it manually then that may in any case help as a starting point. It’s called convolution.
2d convolution using python and numpy
Here’s a good starting point about gaussian blur:
http://en.wikipedia.org/wiki/Gaussian_blur
But if you just want to make a on/off blurring effect then the function to convolve with (convolution kernel) is just an if statement on the distance between the source point and any possible neighbor pixel. For sure there are optimizations for that case: your loops will not need to span all pixels for all pixels, only enough so that a circle of size R fits within the range considered.
Since you want first principles, here it is. It works only for rgb black and white
If you want a smoothing that is a function of the distance use something like
Obviously, you should operate on floats, not integers if you do stuff like this. And use numpy or some of the image manipulation modules.
Gaussian blur would be (within the function above). Now integer is a really bad idea btw: