I'm using OpenCV to do some image processing on Python. I'm trying to overlay an outline on an image where the outline was made from a mask. I'm using cv2.Canny() to get the outline of the mask, then changing that to a color using cv2.cvtColor() then finally converting that edge to cyan using outline[np.where((outline == [255,255,255]).all(axis=2))] = [180,105,255]. My issue now is that this is a one pixel thick line and can barely be seen on large images. This outline is all [0,0,0] except on the points I apply as a mask onto my color image using cv2.bitwise_or(img, outline.
I'm currently thickening this outline by brute forcing and checking every single pixel in the bitmap to check if any of its neighbors are [180,105,255] and if so, that pixel will also change. This is very slow. Is there any way using numpy or openCV to do this automatically? I was hoping for some conditional indexing with numpy, but can't find anything.
Here are two methods depending on the situation:
cv2.dilate() - enhance all white pixelscv2.drawContours() - enhance specific pixelsExample
Using this input image

import cv2
import numpy as np
# Create test image
mask = np.zeros((200,200,3), dtype=np.uint8)
cv2.line(mask, (50, 100), (150, 100), (255,255,255), 1)
Method #1
All pixels in the foreground (white) will have its area increased with cv2.dilate(). We create a structuring element and dilate. More iterations will generate a thicker line
iterations=1 (left), iterations=2 (middle), iterations=3 (right)

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
dilate = cv2.dilate(mask, kernel, iterations=1)
Method #2
When we want to only enhance a particular part of an image but leave other sections untouched, we can use cv2.drawContours(). We can specify the color and adjust the size using the thickness parameter. The result will be similar to cv2.dilate() with the added benefit of color selection

gray = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)
cnts = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
cv2.drawContours(mask, [c], -1, (255,255,255), thickness=15)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With