本文部分参考了以下链接内容: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新手一名,如有建议或意见请联系。
本文部分代码参考于网络,如涉及侵权请联系管理员删除。