Opecv 图像处理之画图、鼠标事件、滑动调之变色画图

六、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 是画布窗口,是上面可切换形状的代码

滑动条的另一个作用就是当作开关使用

猜你喜欢

转载自blog.csdn.net/weixin_42973678/article/details/88619014