opencv入门:绘图及交互 您所在的位置:网站首页 opencv画图函数驱动机器手画圆 opencv入门:绘图及交互

opencv入门:绘图及交互

2024-07-14 14:47| 来源: 网络整理| 查看: 265

绘图及交互

opencv 提供了方便的绘图功能,可以方便的绘制直线,矩形,圆,椭圆等几何图形,还可以在指定位置添加文字说明

处理图像时,可能需要与当前正在处理的图像进行交互,提供了鼠标事件,使用户可以通过鼠标与图像交互,鼠标事件可以识别常用的鼠标操作,比如滑动,点击等

还有滚动条提供交互功能,用户可以拖动滚动条在某一个范围内设置特定的值,并将该值用于后续的图像处理中,而且如果设置为二值形式,滚动条还可以作为开关选择器。

绘画基础

我们见过了了绘制直线的函数 cv2.line()、绘制矩形的函数 cv2.rectangle()、绘制圆的函数 cv2.circle()、绘制椭圆的函数 cv2.ellipse()、绘制多边形的函数 cv2.polylines()、在图像内添加文字的函数 cv2.putText()等多种绘图函数。

这些绘图函数有一些共有参数,主要用于设置原图像,颜色,线条属性等。

img 在其上面绘制图像的载体图像(绘图的容器载体,也成为画布,画板)color 绘制颜色的形状,通常用BGR 模型表示,对于灰度图只能传入灰度值,注意颜色通道范围thickness 线条粗细,默认1,-1表示实心lineType 线条类型,默认 8连接类型 在这里插入图片描述shift 数据精度,用来控制数值(例如圆心坐标等)的精度,一般不用设置 绘制直线

img = cv2.line( img, pt1, pt2, color[, thickness[, lineType ]]) pt1 pt2 对应线段的起点,终点

在这里插入图片描述

绘制矩形

img = cv2.rectangle( img, pt1, pt2, color[, thickness[, lineType]] ) pt1, pt2 对应矩阵的顶点,和对角的顶点 在这里插入图片描述

绘制圆形

img = cv2.circle( img, center, radius, color[, thickness[, lineType]] ) 在这里插入图片描述 在这里插入图片描述

绘制椭圆

img=cv2.ellipse(img, center, axes, angle, startAngle, endAngle, color[, thickness[, lineType]])

center 椭圆圆心坐标axes 轴长angle偏转角,逆时针startAngle 圆弧起始角度,endAngle 圆弧终结角的角度。如果需要绘制部分曲线可以指定。 在这里插入图片描述 绘制多边形

img = cv2.polylines( img, pts, isClosed, color[, thickness[, lineType[, shift]]])

pts 多边形的各个顶点,构成一个数组,数据类型为 numpy.int32isClosed 闭合标记,True 最后一个点与第一个点连接,否则仅是构成一个曲线。 d = 400 img = np.ones((d,d,3),dtype="uint8")*255 pts=np.array([[200,50],[300,200],[200,350],[100,200]], np.int32) pts=pts.reshape((-1,1,2)) print(pts) # [[[200,50],[300,200],[200,350],[100,200]]] 就变成这样的。直接构造这样的也行就不用再reshape。 # 第 1 个参数为-1, 表明它未设置具体值,它所表示的维度值是通过其他参数值计算得到的 cv2.polylines(img,[pts],False,(0,255,0),8) cv2.imshow("demo19.6",img) cv2.waitKey(0) cv2.destroyAllWindows()

在这里插入图片描述

再图形上绘制文字

img=cv2.putText(img, text, org, fontFace, fontScale, color[, thickness[, lineType[, bottomLeftOrigin]]])

text 绘制的字体org 字体位置,以文字的左下角为起点fontFace 字体类型,fontScale 字体大小bottomLeftOrigin 用于控制文字的方向,默认False,为True时,文字是垂直镜像的效果。 在这里插入图片描述 在这里插入图片描述 鼠标交互

对触发的鼠标事件做出相应,我们通过创建相应函数 OnMouseAction(event , x, y ,flags, param)

event 触发的事件x, y 代表触发鼠标事件是,鼠标在窗口中的坐标flags 代表鼠标的拖拽事件,以及键鼠联合事件param 函数ID,表示所相应的事件函数,相当于自定义一个 OnMouseAction() 函数的ID。OnMouseAction 就是一个名称,可以自己定义 在这里插入图片描述 在这里插入图片描述 定义相应函数后,要将函数与一个特定的窗口建立联系(绑定),让该窗口内的鼠标触发事件,可以找到该响应函数并执行,cv2.setMouseCallback(winname,onMouse) 这个函数将函数和窗口绑定。 def Demo(event,x,y,flags,param): # 触发对应事件就发送对应标识 if event == cv2.EVENT_LBUTTONDOWN: print("单击了鼠标左键") elif event==cv2.EVENT_RBUTTONDOWN : print("单击了鼠标右键") elif flags==cv2.EVENT_FLAG_LBUTTON: print("按住左键拖动了鼠标") elif event==cv2.EVENT_MBUTTONDOWN : print("单击了中间键") img = np.ones((300,300,3),np.uint8)*255 cv2.namedWindow('Demo19.9') cv2.setMouseCallback('Demo19.9',Demo) # 实现绑定 cv2.imshow('Demo19.9',img) cv2.waitKey() cv2.destroyAllWindows() # 在出现的窗口中操作 单击了鼠标左键 按住左键拖动了鼠标 单击了鼠标右键 单击了鼠标左键 按住左键拖动了鼠标 按住左键拖动了鼠标 几个栗子 d = 400 def draw(event,x,y,flags,param): if event==cv2.EVENT_LBUTTONDBLCLK: # 双击左键绘制一个随机矩形 p1x=x p1y=y p2x=np.random.randint(1,d-50) # 随机对角点 p2y=np.random.randint(1,d-50) color = np.random.randint(0,high = 256,size = (3,)).tolist() cv2.rectangle(img,(p1x,p1y),(p2x,p2y),color,2) # 坐标是 (y,x)or(x,y)无所谓了 img = np.ones((d,d,3),dtype="uint8")*255 cv2.namedWindow('Demo19.10') cv2.setMouseCallback('Demo19.10',draw) while(1): cv2.imshow('Demo19.10',img) if cv2.waitKey(20)==27: # ESC键 break cv2.destroyAllWindows()

在这里插入图片描述

thickness=-1 mode=1 d=400 def draw_circle(event,x,y,flags,param): if event==cv2.EVENT_LBUTTONDOWN: # 按下左键 a=np.random.randint(1,d-50) r=np.random.randint(1,d/5) angle = np.random.randint(0,361) color = np.random.randint(0,high = 256,size = (3,)).tolist() if mode==1: cv2.rectangle(img,(x,y),(a,a),color,thickness) # 矩形 elif mode==2: cv2.circle(img,(x,y),r,color,thickness) # 圆 elif mode==3: cv2.line(img,(a,a),(x,y),color,3) # 线 elif mode==4: # 椭圆 cv2.ellipse(img, (x,y), (100,150), angle, 0, 360,color,thickness) elif mode==5: # 文字 cv2.putText(img,'OpenCV',(0,round(d/2)), cv2.FONT_HERSHEY_SIMPLEX, 2,color,5) img=np.ones((d,d,3),np.uint8)*255 cv2.namedWindow('image') cv2.setMouseCallback('image',draw_circle) while(1): cv2.imshow('image',img) k=cv2.waitKey(1) if k==ord('r'): # 按键检测 mode=1 elif k==ord('c'): mode=2 elif k==ord('l'): mode=3 elif k==ord('e'): mode=4 elif k==ord('t'): mode=5 elif k==ord('f'): # 挺好玩的,,, thickness=-1 elif k==ord('u'): thickness=3 elif k==27: break cv2.destroyAllWindows()

在这里插入图片描述

滚动条

依附于特定的窗口而存在,通过调节滚到条可以设置,获取指定范围内的特定值

cv2.createTrackbar(trackbarname, winname, value, count, onChange)

trackbarname 滚动条名称winname 依附窗口名称value 初始值,决定滚动条中滑块的位置count 滚动条的最大值,一般 最小值为0onChange 回调函数,将滚动条改变后实现的操作写在回调函数内。

retval=getTrackbarPos( trackbarname,winname ) 获取滚动条返回的值,参数是滚动条名和依附窗口名

使用滚动条实现调色板

通过RGB 各通道的值混合设计一个调色板,三个滚动条分别设置 RGB 的值。

def changeColor(x): r=cv2.getTrackbarPos('R','image') g=cv2.getTrackbarPos('G','image') b=cv2.getTrackbarPos('B','image') # 读取滚动条的值,修改img img[:]=[b,g,r] img=np.zeros((100,700,3),np.uint8) cv2.namedWindow('image') cv2.createTrackbar('R','image',0,255,changeColor) cv2.createTrackbar('G','image',0,255,changeColor) cv2.createTrackbar('B','image',0,255,changeColor) while(1): cv2.imshow('image',img) k=cv2.waitKey(1) if k==27: break cv2.destroyAllWindows()

在这里插入图片描述

用滚动条控制阈值处理参数 Type=0 # 阈值处理方式 Value=0 # 使用的阈值 # retval, dst=cv2.threshold(src, thresh, maxval, type) def onType(a): Type= cv2.getTrackbarPos(tType, windowName) Value= cv2.getTrackbarPos(tValue, windowName) ret, dst = cv2.threshold(o, Value,255, Type) cv2.imshow(windowName,dst) def onValue(a): Type= cv2.getTrackbarPos(tType, windowName) Value= cv2.getTrackbarPos(tValue, windowName) ret, dst = cv2.threshold(o, Value, 255, Type) cv2.imshow(windowName,dst) o = cv2.imread("5.jpg",0) windowName = "Demo19.13" #窗体名 cv2.namedWindow(windowName) cv2.imshow(windowName,o) tType = "Type" # 用来选取阈值处理方式的滚动条 tValue = "Value" # 用来选取阈值的滚动条 cv2.createTrackbar(tType, windowName, 0, 4, onType) cv2.createTrackbar(tValue, windowName,0, 255, onValue) print(1) if cv2.waitKey(0) == 27: # 这里应该是等待按键所以停在了 waitKey() 这。。 cv2.destroyAllWindows()

在这里插入图片描述

用滚动条作为开关

这是滚动条只有两种值,0和1,出来逻辑关系,0,1也可以标识任意两种不同的状态

d=400 global thickness # 好久没见过全局变量了。。。 thickness=-1 def fill(x): pass def draw(event,x,y,flags,param): if event==cv2.EVENT_LBUTTONDBLCLK: # 还是那个绘制矩形的 p1x=x p1y=y p2x=np.random.randint(1,d-50) p2y=np.random.randint(1,d-50) color = np.random.randint(0,high = 256,size = (3,)).tolist() cv2.rectangle(img,(p1x,p1y),(p2x,p2y),color,thickness) img=np.ones((d,d,3),np.uint8)*255 cv2.namedWindow('image') cv2.setMouseCallback('image',draw) cv2.createTrackbar('R','image',0,1,fill) while(1): cv2.imshow('image',img) k=cv2.waitKey(1) g=cv2.getTrackbarPos('R','image') # 用滚动条决定绘制实心还是虚心的 if g==0: thickness=-1 else: thickness=2 if k==27: break cv2.destroyAllWindows()

在这里插入图片描述 芜湖,有了滚动条就可以搞很多事情了。。。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有