Search code examples
pythonimageimage-processingedge-detectionsobel

Applying Horizontal Sobel Mask rotates the image by 180 degrees


In one of my personal projects, I tried to apply the following horizontal edge mask on a grayscale image. By applying the horizontal edge mask, I am trying to detect horizontal edges in the image.

[1 2 1
 0 0 0 
-1 -2 -1]

When I tried to convolve my image matrix with the mask given above, the output image is rotated by 180 degrees. I am not sure whether it is expected behavior or if I am doing something wrong?

Here is code snippet of convolution.

def convolution(self):
    result = np.zeros((self.mat_width, self.mat_height))
    print(self.mat_width)
    print(self.mat_height)

    for i in range(0, self.mat_width-self.window_width):
        for j in range(0, self.mat_height-self.window_height):
            # deflate both mat and mask 
            # if j+self.window_height >= self.mat_height:
            #   row_index = j+self.window_height + 1
            # else:

            row_index = j+self.window_height                
            col_index = i+self.window_width 

            mat_masked = self.mat[j:row_index, i:col_index]
            # pixel position 
            index_i = i + int(self.window_width / 2) 
            index_j = j + int(self.window_height / 2) 


            prod = np.sum(mat_masked*self.mask)


            if prod >= 255:
                result[index_i, index_j] = 255
            else:
                result[index_i, index_j] = 0

    return result

The original grayscale input image is here - enter image description here

Here is the output that is getting generated.

enter image description here


Solution

  • The indices when writing to the output are reversed. You are flipping the horizontal and vertical coordinates which would actually be transposing your image output and the output that you see is a result of transposing an image.

    In addition, you aren't declaring the output size of your image correctly. The first dimension spans the rows or the height while the second dimension spans the columns or the width. The first change you must make is swapping the input dimensions of the output image:

    result = np.zeros((self.mat_height, self.mat_width))
    

    Secondly, the variable index_i is traversing horizontally while the variable index_j is traversing vertically. You just have to flip the order so that you are writing the results correctly:

            if prod >= 255:
                result[index_j, index_i] = 255
            else:
                result[index_j, index_i] = 0
    

    If for some reason you don't want to change the order, then leave your code the way it is, including how you declared the output dimensions of your image and simply return the result transposed:

    return result.T