六、Opencv中的绘图函数
实例代码:
主要介绍:直线,矩形,圆,椭圆,多边形
# 画直线 矩形 圆 椭圆 多边形 添加文本
def paint():
#img = cv2.imread('confu2.jpg')
img = np.zeros((512,512,3),np.uint8)
cv2.namedWindow('littlejun')
# 画直线
# 画布 起点 末点 颜色bgr thickness 抗锯齿类型
cv2.line(img,(1,1),(512,512),(255,0,0),1,cv2.LINE_AA)
# 长方形
# 画布 左上角 右下角 颜色 线大 线的类型
cv2.rectangle(img,(412,0),(512,100),(0,255,0),2,cv2.LINE_AA)
# 圆
# 画布 圆心 半径 颜色 线大 线的类型
cv2.circle(img,(200,200),100,(0,0,255),3,cv2.LINE_AA)
# 椭圆
# 画布 椭圆中心 (长半轴,短半轴)x轴偏离水平方向的位置(正数顺时针,负数逆时针),颜色 线大(负数为填充模式)线的类型
cv2.ellipse(img,(100,462),(100,50),-45,0,180,(255,255,255),-1,cv2.LINE_AA)
pts = np.array([[0,0],[30,40],[100,200],[50,30]],np.int32)
#改变形状的原因是 将这些点设为一个形状为ROWSx1x2 的数组,其中ROWS是顶点的数目
pts = pts.reshape((-1,1,2)) # 变成4层 1行两列的三维矩阵 -1 代表由后面的维数算出确定
# 以列表的形式窜入 第三个参数为真是图是封闭的,否则只是把点连起来的折线
cv2.polylines(img,[pts],1,(0,255,255))
# 画多条直线 先创建直线数组,然后 传过去
line1 = np.array([[150,250],[350,450]],np.int32)
line2 = np.array([[10,20],[30,40]],np.int32)
line3 = np.array([[350,400],[345,480]],np.int32)
# 注意p3 设为假
cv2.polylines(img,[line1,line2,line3],0,(255,255,255))
#添加文本
# 画布 文字 左上角位置 字体 字体大小1比较合适 0.5也是可以的 颜色 线条粗细
cv2.putText(img,'littlejun size 1 hershey simplex',(5,300),cv2.FONT_HERSHEY_SIMPLEX,1,(255,255,255),1)
cv2.putText(img,'littlejun size 1 comlex',(5,330),cv2.FONT_HERSHEY_COMPLEX,1,(255,255,255),1)
cv2.putText(img,'littlejun size 2 plain',(5,360),cv2.FONT_HERSHEY_PLAIN,2,(255,255,255),1)
# 都没有
# cv2.putText(img,'littlejun size 1 duplex',(5,400),cv2.FONT_FONT_HERSHEY_DUPLEX,1,(255,255,255),1)
# cv2.putText(img,'littlejun size 1 triplex',(5,450),cv2.FONT_FONT_HERSHEY_TRIPLEX,1,(255,255,255),1)
cv2.imshow('littlejun',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# all event
# event = [i for i in dir(cv2) if 'EVENT' in i]
# for i in event:
# print(i)
# EVENT_FLAG_ALTKEY
# EVENT_FLAG_CTRLKEY
# EVENT_FLAG_LBUTTON
# EVENT_FLAG_MBUTTON
# EVENT_FLAG_RBUTTON
# EVENT_FLAG_SHIFTKEY
# EVENT_LBUTTONDBLCLK
# EVENT_LBUTTONDOWN
# EVENT_LBUTTONUP
# EVENT_MBUTTONDBLCLK
# EVENT_MBUTTONDOWN
# EVENT_MBUTTONUP
# EVENT_MOUSEHWHEEL
# EVENT_MOUSEMOVE
# EVENT_MOUSEWHEEL
# EVENT_RBUTTONDBLCLK
# EVENT_RBUTTONDOWN
# EVENT_RBUTTONUP
pimg = np.zeros((700,1200,3),np.uint8)
1、直线
Cv2.line(img,point1,point2,color,thickness,linetype)
Img: 画布
Point1: 起点,以元组的形式表示
Point2: 终点,同上
Color : 颜色,BGR 的格式
Thickness :线条宽度,默认值为1(1的宽度比较好看)
Linetype: 线的类型,一般用抗锯齿类型比较好,cv2.LINE_AA
2、矩形
Cv2.line(img,point1,point2,color,thickness,linetype)
Img: 画布
Point1: 左上角,以元组的形式表示
Point2: 右下角,同上
Color : 颜色,BGR 的格式
Thickness :线条宽度,默认值为1
Linetype: 线的类型,一般用抗锯齿类型比较好,cv2.LINE_AA
3、圆
Cv2.circle(img,centerpoint,radius,color,thickness,linetype)
Img: 画布
Centerpoint: 圆心
Ridius: 半径
Color : 颜色,BGR 的格式
Thickness :线条宽度,默认值为1
Linetype: 线的类型,一般用抗锯齿类型比较好,cv2.LINE_AA
4、椭圆
Cv2.ellipse(img,centerpoint,(halflong,halfshort),angle,startangle,endangle,color,
thickness,linetype)
Img: 画布
Centerpoint: 椭圆中心
Halflong: 长半轴
Halfshort: 短半轴
Angle: x轴偏离水平轴的角度,负数为逆时针,正数为顺时针
Startangle: 椭圆起始点偏离x轴的角度,方向同上
Endangle: 椭圆结束点偏离x轴的角度,方向同上
Color : 颜色,BGR 的格式
Thickness :线条宽度,默认值为1
Linetype: 线的类型,一般用抗锯齿类型比较好,cv2.LINE_AA
5、多边形
Cv2.polylines(img,[pts],isclosed,color,thickness,linetype)
Img:画布
Pts: 三维数组表示的点集合 numpoint x 1 x 2 的形式,其中numpoint为点数
Isclosed: 为真时,多边形是封闭的,否则,起点和终点不相连
Color : 颜色,BGR 的格式
Thickness :线条宽度,默认值为1
Linetype: 线的类型,一般用抗锯齿类型比较好,cv2.LINE_AA
画布的创建:
np.zeros((512,512,3),np.uint8)
函数原型:zeros(shape, dtype=float, order=‘C’)
参1 :形状 宽,高,通道数
参2 :数据类型默认为浮点型
参3 :C 代表行优先,F 代表列优先
函数会用0去初始化每一个值,所以最后画布是黑色的
np.zeros(5)
array([ 0., 0., 0., 0., 0.])
np.zeros((5,), dtype=np.int)
array([0, 0, 0, 0, 0])
np.zeros((2, 1))
array([[ 0.],
[ 0.]])
创建多边形点集
pts = np.array([[0,0],[30,40],[100,200],[50,30]],np.int32)
首先创建的是一个二维数组,一定要声明类型为有符号32位整型
修改成为三维数组 numpoint x 1 x 2
用函数:pts = pts.reshape((-1,1,2))
第一个值为-1 ,说明通过后面的维数来决定
举个例子:
z = np.array([[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16]])
z.reshape(-1, 2)
newshape等于-1,列数等于2,行数未知,reshape后的shape等于(8, 2)
z.reshape(-1, 2)
array([[ 1, 2],
[ 3, 4],
[ 5, 6],
[ 7, 8],
[ 9, 10],
[11, 12],
[13, 14],
[15, 16]])
关于polylines() 的另用:可以通过把要画的直线,放在一个列表里面,同时画完这个效率比用line()效率要高,如下图所示
6、添加文本
Cv2.putText(img,stirng,location,font,size,color,thickness,linetype)
Img:画布
String: 要显示的内容,注意不能有中文
Location: 文本左上角的坐标,以元组形式表示
Font : 字体,一般cv2.FONT_HERSHEY_SIMPLEX比较好
FONT_HERSHEY_PLAIN # plain平的,简单的 朴素的
FONT_HERSHEY_DUPLEX # duplex 二倍的,双重的
FONT_HERSHEY_COMPLEX # complex 复杂的
FONT_HERSHEY_TRIPLEX # triplex 三重的
Size:字体大小,1比较合适,可以0.5等
后面就不说了
七、鼠标当画笔
画矩形实例代码:
def drawrectangle(event,x,y,flags,param):
global ix,iy
if(event == cv2.EVENT_LBUTTONDOWN):
ix,iy = x,y
elif(event == cv2.EVENT_LBUTTONUP):
cv2.rectangle(pimg,(ix,iy),(x,y),(255,255,255),1)
首先是定义回调函数:
def drawrectangle(event,x,y,flags,param):
Event 就是上面的event事件,x,y 为事件发生时对应的坐标
flag 为对应的flag标志
Param 函数接收的参数,以列表的形式
然后设置鼠标响应函数
Cv2.setMouseCallback(winname,func)
Func 为回调函数
然后让函数一直运行就好
注意画长方形是要定义有全局变量保存好左上角坐标的,其他跟画图一样
可切换模式画图实例代码:
def changShape(event,x,y,flags,param):
global ix,iy,kinds
if(event == cv2.EVENT_LBUTTONDOWN):
ix,iy = x,y
elif(event == cv2.EVENT_LBUTTONUP):
if(kinds == 0): # 要互相独立
cv2.rectangle(pimg,(ix,iy),(x,y),color,1)
elif(kinds == ord('c')):
r = int(np.sqrt((ix-x)**2+(iy-y)**2))
cv2.circle(pimg,(ix,iy),r,color,1)
# putext 不能有中文
cv2.putText(pimg,'center of circle:'+str(ix)+' '+str(iy)+'radius:'+str(r),(ix-r,iy+r+20),cv2.FONT_HERSHEY_SIMPLEX,1,color,1)
# 鼠标的各种事件,结合画图操作
def mouseEvent():
global kinds
cv2.namedWindow('littlejun')
# 设置回调函数
cv2.setMouseCallback('littlejun',changShape)
while True:
cv2.imshow('littlejun',pimg)
k = cv2.waitKey(5)
if k&0xff == ord('q'):
break
if(k != -1):
kinds = k
if(k == ord('r')): # 切换回矩形
kinds = 0
cv2.destroyAllWindows()
八、滑动条调色板结合画图
# 调色板 结合画图
def colorPanel():
cv2.namedWindow('littlejun')
cv2.namedWindow('littlejun2')
cv2.createTrackbar('B','littlejun',0,255,nothing)
cv2.createTrackbar('G','littlejun',0,255,nothing)
cv2.createTrackbar('R','littlejun',0,255,nothing)
cv2.createTrackbar('Switch','littlejun',0,1,nothing)
global kinds,color
# 设置回调函数
cv2.setMouseCallback('littlejun2',changShape)
img = np.zeros((512,600,3),np.uint8)
while True:
cv2.imshow('littlejun',img)
cv2.imshow('littlejun2',pimg)
b = cv2.getTrackbarPos('B','littlejun')
g = cv2.getTrackbarPos('G','littlejun')
r = cv2.getTrackbarPos('R','littlejun')
s = cv2.getTrackbarPos('Switch','littlejun')
color = (b,g,r)
if(s == 0):
img[:] = 0
else:
img[:] = [b,g,r]
k = cv2.waitKey(5)
if k&0xff == ord('q'):
break
if(k != -1):
kinds = k
if(k == ord('r')): # 切换回矩形
kinds = 0
cv2.destroyAllWindows()
jx,jy = -1,-1
change = False
def getRectPos(event,x,y,flags,param):
global ix,iy,jx,jy,change
if event == cv2.EVENT_LBUTTONDOWN:
ix,iy = x, y
elif event == cv2.EVENT_LBUTTONUP:
jx,jy = x,y
cv2.rectangle(param,(ix,iy),(x,y),(0,0,255),1)
change =True
Cv2.creatTrackbar(label,winname,location,callfunc)
Label: 滑动条的名称
Winname:窗口名字
Location: 0 默认位置
Callfunc: 回调函数,此处不用做什么,写个nothing 函数就好
获取滑动条的值
Cv2.getTrackbarPos(label,winname)
Label: 滑动条的名称
Winname:窗口名字
此处开了连个窗口,littlejun 是调色板,littlejun2 是画布窗口,是上面可切换形状的代码
滑动条的另一个作用就是当作开关使用