Andrew Fakhry
Andrew Fakhry

Reputation: 70

How to remove a polyline from an RGB image using numpy

I am not sure what would be the best way to remove a vertical polyline from an image. This line starts from the very top of an image to the bottom. The input is an image with three channels and array of y indices of the line. The output would be the same input image but without the polyline. For example, if the first image shape is (5, 10,3), then the final image shape should be (5, 9, 3) after removing the polyline.

Input example:

Image:

np.array([[[0, 20, 0, 0, 255, 0, 0, 0, 0, 0],
           [0, 20, 0, 0, 255, 0, 0, 0, 0, 0],
           [0, 56, 0, 0, 0, 255, 0, 0, 0, 0],
           [0, 58, 0, 0, 0, 255, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 255, 0, 0, 0]],
          [[0, 0, 0, 0, 255, 0, 0, 0, 30, 0],
           [0, 0, 0, 0, 255, 0, 0, 0, 31, 0],
           [0, 0, 0, 0, 0, 255, 0, 0, 32, 0],
           [0, 0, 0, 0, 0, 255, 0, 0, 31, 0],
           [0, 0, 0, 0, 0, 0, 255, 0, 0, 0]],
          [[1, 0, 0, 0, 255, 0, 0, 0, 0, 0],
           [1, 0, 0, 0, 255, 0, 0, 0, 0, 0],
           [1, 0, 0, 0, 0, 255, 0, 0, 0, 0],
           [1, 0, 0, 0, 0, 255, 0, 0, 0, 0],
           [1, 0, 0, 0, 0, 0, 255, 0, 0, 0]]])

Note: the size here is (3, 5, 10) for illustration. The image shape would be (5, 10, 3). We wanna remove the white polyline

Polyline:

np.array([4, 4, 5, 5, 6])

Output Example

np.array([[[0, 20, 0, 0, 0, 0, 0, 0, 0],
           [0, 20, 0, 0, 0, 0, 0, 0, 0],
           [0, 56, 0, 0, 0, 0, 0, 0, 0],
           [0, 58, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0]],
          [[0, 0, 0, 0, 0, 0, 0, 30, 0],
           [0, 0, 0, 0, 0, 0, 0, 31, 0],
           [0, 0, 0, 0, 0, 0, 0, 32, 0],
           [0, 0, 0, 0, 0, 0, 0, 31, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0]],
          [[1, 0, 0, 0, 0, 0, 0, 0, 0],
           [1, 0, 0, 0, 0, 0, 0, 0, 0],
           [1, 0, 0, 0, 0, 0, 0, 0, 0],
           [1, 0, 0, 0, 0, 0, 0, 0, 0],
           [1, 0, 0, 0, 0, 0, 0, 0, 0]]])

Note: the size now is (3, 5, 9)

My code

def remove_polyline(image, polyline):
    h, w = image.shape[:2]
    res_image = np.zeros((h, w - 1))

    for i in range(h):
        left_section = image[i, :polyline[i]]
        right_section = image[i, polyline[i]+1:]
        res_image[i, :] = np.dstack((left_section, right_section))

    return res_image

I know this would work for grayscale images but not sure about 3 channel images

Upvotes: 1

Views: 161

Answers (2)

Sumit Chaturvedi
Sumit Chaturvedi

Reputation: 348

You can try this.

def remove_polyline(image, polyline):
    h, w, c = image.shape
    res_image = np.zeros((h, w - 1, c))

    for i in range(h):
        left_section = image[i, :polyline[i], :]
        right_section = image[i, polyline[i]+1:, :]
        res_image[i, :, :] = np.vstack((left_section, right_section))

    return res_image

Upvotes: 1

Quang Hoang
Quang Hoang

Reputation: 150735

Note that your input has shape (3,5,10) instead of (5,10,3). This answer assumes the latter:

def remove_polyline(s, polyline):
    mask = np.arange(s.shape[1]) != polyline[ :, None]
    return s[mask,:].reshape(s[:,:-1].shape).copy()

r = remove_polyline(image, polyline)
plt.imshow(r)

Output:

enter image description here

Upvotes: 1

Related Questions