-2

I'm trying to fix this function that tries to filter an image in python in parallel, but the function isn't working:

def parallel_filtering_image(r):
    # r: is the image row to filter
    # image is the global memory array
    # my_filter is the filter shape to apply to the image
    
    global image
    global my_filter
    
    #from the global variaable, gets the image shape
    (rows,cols,depth) = image.shape

    #fetch the r row from the original image
    srow=image[r,:,:]
    if ( r>0 ):
        prow=image[r-1,:,:]
    else:
        prow=image[r,:,:]
    
    if ( r == (rows-1)):
        nrow=image[r,:,:]
    else:
        nrow=image[r+1,:,:]
    
    #defines the result vector, and set the initial value to 0
    frow=np.zeros((cols,depth))
    frow=srow
    
    #return the filtered row
    return frow

here is the caller:

def filter_image(my_image):
    shape=my_image.shape
    rows=shape[0]
    v=range(rows)
    with mp.Pool(NUMCORES,initializer=my.init_globalimage,initargs=[image,filter_mask]) as p:
        result=p.map(my.parallel_filtering_image,v)
    return result

if I need to calculate the filtered pixel in the position (x,y), I will need to calculate the product of the pixels in the positions (x-1,y-1)+(x,y-1)+(x+1,y-1)+(x-1,y)+(x,y)+(x+1,y)+(x-1,y+1)+(x,y+1)+(x+1,y1+1), against the filter mask.

Things to take care:

  • The algorithm must be independent of the image size
  • The values will been between 0 an 255, and the results should be integer values between those values.
  • To calculate the borders, we uses the next available value. For example: if y is the row, for the upper border (where y=0) we will replace (x-1,y)+(x,y)+(x+1,y)+(x-1,y)+(x,y)+(x+1,y)+(x-1,y+1)+(x,y+1)+(x+1,y1+1).
  • The images have 3 layers depth, so, we need to apply to each one of the 3 layers the filter mask
  • You will have 2 matrices: Image and Filter. The first one will be a preloaded image, the second matrix is the filter mask.
Giackkk
  • 41
  • 6

1 Answers1

2

prow and nrow are unused so their assignment is useless. frow=np.zeros((cols,depth)) is also useless since frow is assigned just after that. Since srow=image[r,:,:] and frow=srow, then frow=image[r,:,:] too. This means your code is semantically equivalent to:

def parallel_filtering_image(r):
    global image
    return image[r,:,:]

This is why the output is the same: the computational part is missing.

Jérôme Richard
  • 41,678
  • 6
  • 29
  • 59
  • Well... by adding the missing filter computation. IDK what filter you want to use (not mentioned in the question). – Jérôme Richard Sep 26 '22 at 13:43
  • i have add it to the question :) – Giackkk Sep 26 '22 at 13:58
  • Ok what you want to implement is a stencil (or convolution). It is very famous and there are many way to do that in parallel efficiently. While you can do it with Numpy, it is not trivial and clearly not efficient. In fact, the resulting code would certainly be slower than a more efficient sequential stencil using Scipy (which should already be sub-optimal): see https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.convolve2d.html. You can parallelize this using ghost area (eg. overlapping rows). – Jérôme Richard Sep 26 '22 at 16:28
  • If you want to write an efficient stencil, then please do not use multiprocessing for that. Consider using Cython or Numba or even specialized libraries (eg. OpenCV) – Jérôme Richard Sep 26 '22 at 16:30