Drawing fancy rectangle around face

I did something naive. You can implement with further modifications using a function.

Steps:

  1. I manually marked a rectangle around the text and extracted the 4 points.

  2. Then I fixed a length for the line to be drawn from these 4 points.

Result:

enter image description here

Functions used:

  • cv2.line()
  • cv2.rectangle()

See THIS LINK for details about their usage.


You can achieve what you want by using the functions that draw lines and arcs.

The frame you want to draw consists of 4 similar parts (one per corner), each rotated (or mirrored).

Let's have a look at the top left corner:

Illustration

As you can see, we need to draw 2 line segments (of length d) and an arc (a quarter of a circle of radius r).

Let's say the coordinates of the top-left corner are (x1, y1).

That means that the arc will have a center at position (x1 + r, y1 + r).

One of the lines will go from (x1 + r, y1) to (x1 + r + d, y1).

The other line will go from (x1, y1 + r) to (x1, y1 + r + d).

Similar situation will happen with the other corners.


Sample code:

import cv2
import numpy as np

# ============================================================================

def draw_border(img, pt1, pt2, color, thickness, r, d):
    x1,y1 = pt1
    x2,y2 = pt2

    # Top left
    cv2.line(img, (x1 + r, y1), (x1 + r + d, y1), color, thickness)
    cv2.line(img, (x1, y1 + r), (x1, y1 + r + d), color, thickness)
    cv2.ellipse(img, (x1 + r, y1 + r), (r, r), 180, 0, 90, color, thickness)

    # Top right
    cv2.line(img, (x2 - r, y1), (x2 - r - d, y1), color, thickness)
    cv2.line(img, (x2, y1 + r), (x2, y1 + r + d), color, thickness)
    cv2.ellipse(img, (x2 - r, y1 + r), (r, r), 270, 0, 90, color, thickness)

    # Bottom left
    cv2.line(img, (x1 + r, y2), (x1 + r + d, y2), color, thickness)
    cv2.line(img, (x1, y2 - r), (x1, y2 - r - d), color, thickness)
    cv2.ellipse(img, (x1 + r, y2 - r), (r, r), 90, 0, 90, color, thickness)

    # Bottom right
    cv2.line(img, (x2 - r, y2), (x2 - r - d, y2), color, thickness)
    cv2.line(img, (x2, y2 - r), (x2, y2 - r - d), color, thickness)
    cv2.ellipse(img, (x2 - r, y2 - r), (r, r), 0, 0, 90, color, thickness)

# ============================================================================

img = np.zeros((256,256,3), dtype=np.uint8)

draw_border(img, (10,10), (100, 100), (127,255,255), 1, 10, 20)
draw_border(img, (128,128), (240, 160), (255,255,127), 1, 5, 5)

cv2.imwrite('round_rect.png', img)

Result:

Result