I'm working with binary masks in openCV in Python and have created one with fillConvexPoly. First result can be seen in figure 1. As you can see the edge is not smooth, but rather looks like stairs.
So I use the anti-aliasing flag in fillconvexpoly, which is cv2.LINE_AA. The result looks promising, as you can see in figure 2. Problem is that using this mask in bitwise operations results in errors. Why?
Well, upon closer inspection and looking at the actual pixel values, I can see that the line is represented by a decrease in pixel values rather than pixel(x,y)=255, pixel(x+1,y)=0 and pixel(x+1,y+1)=255. In figure 3 (large image) you can see the decrease of value in pixels in one row. In figure 4 you can see what I would like as a result. I do understand that that is not realistically possible since the line doesn't have that angle, but there should be a better representation that in has in figure 1 right?. The reason I need it like that is because I'm replacing part of an image with another image, and the mask represents the replaced area. I use bitwise operations to get my result. Using bitwise operations with values other than 0 or 255 result in errors and different colors etc. So I need it to be 0 or 255. Result for now in figure 5, where the blue area is replaced (used to be red). As you can see, the result is not very attractive. If that would be a 'straight' line the result would look way better. (applying blur on straight edges afterwards makes it look good btw, but the stairwise motion is still visible after the blur).
What I have tried:
If you have another suggestion for this problem, I would love to hear it. Thanks in advance.
EDIT: Using a blur on the final result works well for lines with a lot of steps in it, f.e. every 2 or 3 pixels. From: original. Applied blur on the edge: result But applying this technique on a very long line with few steps: original: see figure 5, and result. As you can see, the result is not bad, but still contains this stepwise pattern. Really trying to get rid of it. (The glow coming from underneath is something I'm handling in the future)
You can solve this with an equivalent of the addWeighted function for array-based weights. Assuming you have 8-bit arrays image
, overlay
, and mask
, and since your mask seems to apply to the overlay rather than the base image, you could do something like
import cv2
import numpy as np
... # get/read image and overlay, create mask
alpha = mask / 255 # convert to 0-1 range, could also use cv2.normalize
combined = np.uint8(overlay * alpha + image * (1 - alpha))