Skip to content
Advertisement

1 px thick line cv2

I need to draw a line in an image where no pixel is thicker than 1 pixel in the horizontal dimension.

Despite I use thickness=1 in poly lines,

cv2.polylines(img, np.int32([points]), isClosed=False, color=(255, 255, 255), thickness=1)

in the resulting plot there may be 2 pixels horizontally adjacent set to 255, like in this pic:

enter image description here

How can I prevent to have adjacent pixels set to 255? Or equivalently: what is an efficient way to set to 0 one of the 2?

I thought to Erosion but then, in those lines where there is only 1 255 pixel, such a pixel would be set to 0 as well.

Advertisement

Answer

It looks like we need to use for loops.

Removing one pixel out of two horizontally adjacent pixels is an iterative operation.
I can’t see a way to vectorize it, or use filtering or morphological operations.
There could be something I am missing, but I think we need to use a loop.

In case the image large, you may use Numba (or Cython) for accelerating the execution time.

import cv2
import numpy as np
from numba import jit

@jit(nopython=True)  # Use Numba JIT for accelerating the code execution time  
def horiz_skip_pix(im):
    for y in range(im.shape[0]):
        for x in range(1, im.shape[1]):
            # Use logical operation instead of using "if statement".
            # We could have used an if statement, like if im[y, x]==255 and im[y, x-1]==255: im[y, x] = 0 ...
            im[y, x] = im[y, x] & (255-im[y, x-1])


# Build sample input image
src_img = np.zeros((10, 14), np.uint8)
points = np.array([[2,2], [5,8], [12,5], [12,2], [3, 2]], np.int32)
cv2.polylines(src_img, [points], isClosed=False, color=(255, 255, 255), thickness=1)

dst_img = src_img.copy()

# Remove horizontally adjacent pixels.
horiz_skip_pix(dst_img)

# Show result
cv2.imshow('src_img', cv2.resize(src_img, (14*20, 10*20), interpolation=cv2.INTER_NEAREST))
cv2.imshow('dst_img', cv2.resize(dst_img, (14*20, 10*20), interpolation=cv2.INTER_NEAREST))
cv2.waitKey()
cv2.destroyAllWindows()

src_img:
src_img

dst_img:
dst_img

I wouldn’t call the result a “1 px thick line”, but it meats the condition of “prevent to having adjacent pixels”.

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement