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:
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()
I wouldn’t call the result a “1 px thick line”, but it meats the condition of “prevent to having adjacent pixels”.