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