import cv2 import numpy as np # storing settings for semicircle class SemiCircle: def __init__( self, thickness=10, color=(255, 0, 0), radius=100, center=(250, 250), angle=0, start_angle=180, end_angle=360 ): self.thickness = thickness self.color = color self.radius = (radius, radius) self.center = center self.angle = angle self.start_angle = start_angle self.end_angle = end_angle class Line: def __init__(self, thickness=2, color=(0, 0, 0)): self.thickness = thickness self.color = color def generate_points(radius, length, center, num_points): # center points cx, cy = center # generating points on circle outer_circle_points = [(radius * np.cos(i), radius * np.sin(i)) for i in np.linspace(np.pi, 2*np.pi, num_points)] inner_radius = radius - length inner_circle_points = [(inner_radius * np.cos(i), inner_radius * np.sin(i)) for i in np.linspace(np.pi, 2*np.pi, num_points)] # genrating point for drawing line using cv2, start_points and end_points start_points = [(int(cx + i), int(cy + j)) for i, j in outer_circle_points] end_points = [(int(cx + i), int(cy + j)) for i, j in inner_circle_points] return zip(start_points, end_points) class Meter: def __init__(self, center, radius, circle_color): self.center = center self.radius = radius self.circle_color = circle_color def draw_meter(self, image, idx): # drawing semicircle circle = SemiCircle(center=self.center, radius=self.radius, color=self.circle_color) cv2.ellipse( image, circle.center, circle.radius, circle.angle, circle.start_angle, circle.end_angle, circle.color, circle.thickness ) # drawing smaller fine lines line = Line(thickness=circle.thickness//3) for start, end in generate_points(self.radius - 10, self.radius * 0.05, self.center, 50): cv2.line(image, start, end, line.color, line.thickness) # drawing bigger lines line2 = Line(thickness=circle.thickness//2, color=(238, 222, 23)) for start, end in generate_points(self.radius - 10, self.radius * 0.15, self.center, 10): cv2.line(image, start, end, line2.color, line2.thickness) # drawing needle anchor point cv2.circle(image, circle.center, 15, (0, 0, 0), -1) # emotion classes emotions = ['neutral', 'happy', 'surprise', 'sad', 'angry', "disgust", 'fear', 'contempt', 'unknown', 'NotFace'] # points where text will be written pts = generate_points(self.radius*1.55, self.radius * 0.15, self.center, 10) pts = list(pts) for i, emot in enumerate(emotions): x, y = pts[i][0] x -= 20 color = (98, 65, 255) if (i == idx) else (144,238,144) cv2.putText( image, emot, (x, y), cv2.FONT_HERSHEY_SIMPLEX, 1, color, 2, cv2.LINE_AA ) # needle 12, 178, 33 line3 = Line(thickness=circle.thickness//2, color=(0, 0, 255)) pts2 = generate_points(self.radius*0.7, self.radius*0.7, self.center, 10) pts2 = list(pts2) start, end = pts2[idx] cv2.line(image, start, end, line3.color, line3.thickness) if __name__ == '__main__': image = np.ones((500, 500, 3)) meter = Meter((250, 250), 150, (80, 127, 255)) meter.draw_meter(image, 4) cv2.imshow('image', image) if cv2.waitKey(0) & 0xFF == 27: pass cv2.destroyAllWindows()