I am working on a project that involves video frame manipulation, and one of the requirements is to add smooth rounded corners to the frames. I did some research on how to add rounded corners to images using PIL or any other image processing library, but all of them produce rough corners that look unprofessional. Here is the code I tried :-
def add_corners(im, rad):
circle = Image.new('L', (rad * 2, rad * 2), 0)
draw = ImageDraw.Draw(circle)
draw.ellipse((0, 0, rad * 2 - 1, rad * 2 - 1), fill=255)
alpha = Image.new('L', im.size, 255)
w, h = im.size
alpha.paste(circle.crop((0, 0, rad, rad)), (0, 0))
alpha.paste(circle.crop((0, rad, rad, rad * 2)), (0, h - rad))
alpha.paste(circle.crop((rad, 0, rad * 2, rad)), (w - rad, 0))
alpha.paste(circle.crop((rad, rad, rad * 2, rad * 2)), (w - rad, h - rad))
im.putalpha(alpha)
return im
im = Image.open('sand.png')
im = round_corner_jpg(im, 50)
im.save('sand_corner.png')
and here is the result it produces, as can be seen in the above image, the corners are rough and have this pixelated view on them, they are not smooth just like we can do in figma using IOS corner smoothing:-

I also saw this question that also had the same requirements, but they didn't show the code for how to implement it :- Any way to make nice antialiased round corners for images in python?
I want to make sure that there is no loss in the frame quality when adding the rounded corners and the corners should be smooth and better yet look like the corner smoothing in figma
EDIT:-
out = cv2.VideoWriter('assets/pathToSave.mp4', fourcc, fps, (1920, 1080))
def generate_frame():
while cap.isOpened():
code, frame = cap.read()
if code:
yield frame
else:
print("done")
break
for i, frame in enumerate(generate_frame()):
# Convert opencv frames into PIL Image
img = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
im_pil = Image.fromarray(img)
ss = 4
alpha = Image.new('L', (im.width*ss, im.height*ss))
# Draw rounded rectangle and unsupersample
d = ImageDraw.Draw(alpha)
d.rounded_rectangle([0,0,im.width*ss-1,im.height*ss-1],radius=120,fill='white')
alpha = alpha.resize((alpha.width//ss, alpha.height//ss),
resample=Image.Resampling.LANCZOS)
alpha.save('DEBUG-alpha.png')
# Push new alpha channel into original image and save
im_pil.putalpha(alpha)
im_np = np.array(im_pil.convert('RGB'))
open_cv_image = im_np[:, :, ::-1].copy()
outputVideo.write(open_cv_image)
I tried the above code in order to have rounded corners from an incoming video frames, but I still got rough corners :-
Please look at the white frame, the transparent rounded corners are a part of background on which this video is rendered upon



Maybe this is better: