python之cv2动态绘制图形

本文部分参考了以下链接内容:https://blog.csdn.net/Vertira/article/details/123631185

代码如下:

说明:按下'c'键实现绘制圆功能;按下'r'键实现绘制矩形功能;按下'l'键实现绘制直线功能;按下‘p’键实现绘制多边形功能,在绘制圆和矩形时需按住左键不放,绘制直线和多边形时按中键结束。

左键实现删除上一个已绘制图形。

import cv2
import numpy as np
import copy

class Graphical(object):

    def __init__(self):

        self.start = (0,0)

        self.end = (0,0) #点start和end 用于绘制直接或四边形

        self.r = 0 #用于绘制圆

        self.points = [] #用于绘制多边形


class DrawGraphical(object):

    def __init__(self,img,color=(0,255,0),thickness=2):

        self.img = img

        self.img_for_show = self.img.copy()

        self.color = color

        self.thickness = thickness

        self.current_graphical = Graphical()

        self.lines = []

        self.polys = []

        self.circles = []

        self.rects = []

        self.graphicals = []

        self.left_button_down = False

    @staticmethod
    def __clip(value,low,high):

       output = max(value,low)

       output = min(output,high)

       return output

    def shrink_point(self,x,y):

        height,width = self.img_for_show.shape[0:2]

        x_shrink = self.__clip(x,0,width)

        y_shrink = self.__clip(y,0,height)

        return (x_shrink,y_shrink)

    def reset_image(self):

        self.img_for_show = self.img.copy()


    def add(self):

        print('多边形控制!:',control_for_poly)

        if draw_line_now or draw_poly_now:

            if control_for_poly == True:

                print(draw_line_now)

                print(draw_poly_now)

                if draw_poly_now:

                    print('现在开始添加多边形的边!')

                    self.graphicals.append(['l_p',copy.deepcopy(self.current_graphical)])

                else:

                    self.graphicals.append(['l',copy.deepcopy(self.current_graphical)])

            if draw_poly_now and control_for_poly ==False:

                print('现在开始添加多边形!')

                self.graphicals.append(['p',self.current_graphical])

        if draw_circle_now:

            print('添加圆成功!')

            self.graphicals.append(['c',self.current_graphical])

        if draw_rect_now:

            self.graphicals.append(['r',self.current_graphical])

    def draw(self):

        for grap in self.graphicals:

            if grap[0] == 'p':

                cv2.polylines(self.img_for_show,np.array([grap[1].points],np.int32),True,
                              color = self.color,thickness = self.thickness)

            elif grap[0] == 'l' or grap[0] == 'l_p':

                cv2.line(self.img_for_show,grap[1].start,grap[1].end,
                         color = self.color,thickness = self.thickness)

            elif grap[0] == 'c':

                cv2.circle(self.img_for_show,grap[1].start,grap[1].r,
                           color = self.color,thickness = self.thickness)

            elif grap[0] == 'r':

                cv2.rectangle(self.img_for_show,grap[1].start,grap[1].end,
                              color = self.color,thickness = self.thickness)

    def cal_R(self):

        self.current_graphical.r = int((abs(self.current_graphical.start[0] - self.current_graphical.end[0])**2 + abs(self.current_graphical.start[1] - self.current_graphical.end[1])**2)**0.5)

        return self.current_graphical.r

    def draw_current_rect(self):

        cv2.rectangle(self.img_for_show,self.current_graphical.start,self.current_graphical.end,
                     color = self.color,thickness = self.thickness)

    def draw_current_line(self):

        cv2.line(self.img_for_show,self.current_graphical.start,self.current_graphical.end,
                 color = self.color,thickness = self.thickness)

    def draw_current_poly(self):

        cv2.polylines(self.img_for_show,np.array([self.current_graphical.points],np.int32),True,
                      color = self.color,thickness = self.thickness)

    def draw_current_circle(self):

        self.current_graphical.r = self.cal_R()

        cv2.circle(self.img_for_show,self.current_graphical.start,self.current_graphical.r,
                   color = self.color,thickness = self.thickness)

    def pop(self):

        graphical = Graphical()

        self.graphicals = [i for i in self.graphicals if i[0] != 'l_p']

        if self.graphicals:

            graphical = self.graphicals.pop()

            return graphical


def onmouse_draw_graphical(event,x,y,flags,draw_graphical):

    global control_for_poly

    control_for_poly = True

    if draw_line_now or draw_poly_now or draw_rect_now or draw_circle_now:

        if event == cv2.EVENT_LBUTTONDOWN:

            if draw_graphical.left_button_down == False:

                draw_graphical.left_button_down = True

                draw_graphical.current_graphical.start = (x,y)

                if draw_poly_now:

                    draw_graphical.current_graphical.points.append([x,y])

            else:

                draw_graphical.current_graphical.end = draw_graphical.shrink_point(x,y)

                draw_graphical.reset_image()

                draw_graphical.draw()

                if draw_line_now:

                    draw_graphical.draw_current_line()

                elif draw_poly_now:

                    draw_graphical.draw_current_line()

                    draw_graphical.current_graphical.points.append([x,y])

                elif draw_circle_now:

                    print('进入绘圆状态!')

                    draw_graphical.draw_current_circle()

                elif draw_rect_now:

                    #print('绘制矩形!')

                    draw_graphical.draw_current_rect()

                draw_graphical.add()

                if draw_line_now or draw_poly_now:

                    draw_graphical.current_graphical.start = (x,y)

        if draw_graphical.left_button_down and event == cv2.EVENT_MOUSEMOVE:

            #print('鼠标移动!')

            draw_graphical.current_graphical.end = draw_graphical.shrink_point(x,y)

            draw_graphical.reset_image()

            draw_graphical.draw()

            if draw_line_now:

                draw_graphical.draw_current_line()

            elif draw_poly_now:

                draw_graphical.draw_current_line()

            elif draw_circle_now:

                draw_graphical.draw_current_circle()

            elif draw_rect_now:

                draw_graphical.draw_current_rect()

        if draw_circle_now or draw_rect_now:

            if event == cv2.EVENT_LBUTTONUP:

                draw_graphical.left_button_down = False

                draw_graphical.current_graphical.end = draw_graphical.shrink_point(x,y)

                draw_graphical.add()

                draw_graphical.current_graphical = Graphical()

        elif draw_line_now or draw_poly_now:

            if event == cv2.EVENT_MBUTTONDOWN:

                draw_graphical.reset_image()

                draw_graphical.draw()

                draw_graphical.draw_current_poly()

                print(draw_graphical.current_graphical.points)

                control_for_poly = False

                draw_graphical.add()

                draw_graphical.left_button_down = False

                draw_graphical.current_poly_points = []

                draw_graphical.current_graphical = Graphical()

        if event == cv2.EVENT_RBUTTONDOWN:

            draw_graphical.pop()

            draw_graphical.reset_image()

            draw_graphical.draw()




draw_line_now = False

draw_circle_now = False

draw_poly_now = False

draw_rect_now = False
        
img = np.zeros((512,512,3),np.uint8)

cv2.namedWindow('image')

draw_graphicals = DrawGraphical(img,(0,255,0),3)

cv2.setMouseCallback('image',onmouse_draw_graphical,draw_graphicals)

while True:

    cv2.imshow('image',draw_graphicals.img_for_show)

    key = cv2.waitKey(20)

    if key == ord('l'):

        print('现在开始绘制直线!')

        draw_line_now = not draw_line_now

        if draw_circle_now == True:

            draw_circle_now = False

        elif draw_poly_now == True:

            draw_poly_now = False

        elif draw_rect_now == True:

            draw_rect_now = False

    elif key == ord('c'):

        print('现在开始绘制圆!')

        draw_circle_now = not draw_circle_now

        if draw_line_now == True:

            draw_line_now = False

        elif draw_poly_now == True:

            draw_poly_now = False

        elif draw_rect_now == True:

            draw_rect_now = False

    elif key == ord('p'):

        print('现在开始绘制多边形!')

        draw_poly_now = not draw_poly_now

        if draw_circle_now == True:

            draw_circle_now = False

        elif draw_line_now == True:

            draw_line_now = False

        elif draw_rect_now == True:

            draw_rect_now = False

    elif key == ord('r'):

        print('现在开始绘制矩形!')

        draw_rect_now = not draw_rect_now

        if draw_circle_now == True:

            draw_circle_now = False

        elif draw_poly_now == True:

            draw_poly_now = False

        elif draw_line_now == True:

            draw_rect_now = False

    if key == 27:

        break

cv2.destroyAllWindows()

自觉python新手一名,如有建议或意见请联系。

本文部分代码参考于网络,如涉及侵权请联系管理员删除。

你可能感兴趣的:(python,几何学,开发语言)