要求opencv版本4.1.2.30(4.x >=版本),我的版本4.5.3
介绍Opencv4中用于绘制基础图形和生成文字的函数
img = cv.circle(img,cencter,radius,color,thickness,lineType,shift)
img:需要在其上绘制圆的图像
center:圆心的坐标
radius:圆的半径,单位为像素
color:圆的颜色
thickness:轮廓的宽度(默认为1,如果为负值则绘制一个实心圆)
lineType:线条的类型(可选值为cv.FILLED,cv.LINE_4,cv.LINE_8,cv.LINE_AA,默认为cv.LINE_8)
shift:center和radius的小素位数(默认为0)
img=cv.line(img,pt1,pt2,color,thickness,lineType,shift)
img:绘制的线段所在的图像
pt1:线段起点在图像中的坐标
pt2:线段终点在图像中的坐标
color:线条的颜色,用三通道表示
thickness:线条的粗细,默认值为1
lineType:线条的类型,默认为cv.LINE_8
shift:点坐标中的小数位数,默认值为0
img=cv.ellipse(img,center,axes,angle,startAngle,endAngle,color,thickness,lineType,shift)
img:绘制的椭圆所在的图像
center:椭圆的中心
axes:椭圆的长半轴的长度
angle:椭圆旋转的角度,单位为度
startAngle:椭圆弧起始的角度,单位度
endAngle:椭圆弧终止的角度,单位为度
color:线条的颜色,用三通道表示
thickness:线条的粗细,默认为1
lineType:线条的类型,默认为cv.LINE_8
shift:点坐标中小数位数,默认为0
Opencv还提供了函数cv.ellipse2Poly()用于输出近似椭圆边界的像素坐标,便于后续处理,但是他不会在图像中绘制椭圆:
pts = cv.ellipse2Poly(center,axes,angle,startAngle,endAngle,delta)
center:椭圆的中心
axes:椭圆的长半轴的长度
angle:椭圆旋转的角度,单位为度
startAngle:椭圆弧起始的角度,单位度
endAngle:椭圆弧终止的角度,单位为度
delta:后续折线顶点之间的角度,相当于定义了近似精度
pts:近似的椭圆边界的像素坐标集合
先介绍绘制矩阵的函数:
img = cv.rectangle(img,pt1,pt2,color,thickness,lineType,shift)
img = cv.rectangle(img,rec,color,thickness,lineType,shift)
img:绘制的矩阵所在的图像
pt1:矩阵的一个顶点;
pt2:与pt1相对的顶点
color:线条的颜色,用三通道表示
thickness:线条的粗细,默认为1
lineType:线条的类型,默认为cv.LINE_8
shift:点坐标中小数位数,默认为0
rec:矩阵左上角的顶点,以及矩阵的长和宽
接下来是多变形:
img=cv.fillPoly(img,pts,color,lineType,shift,offset)
img:绘制的多边形所在的图像
pts:多边形顶点数组(int32,顺时针或逆时针依次给出)
color:线条的颜色,用三通道表示
lineType:线条的类型,默认为cv.LINE_8
shift:点坐标中小数位数,默认为0
offset:所有顶点的可选偏移量
img = cv.putText(img,text,org,fontFace,fontScale,color,thickness,lineType,bottomLeftOrigin)
img:显示文字的图像
text:输出到图像的文字,目前只支持英文
org:图像中文字字符的左下角像素坐标
fontFace:字体类型的选择标志
fontScale:字体的大小
color:字体的颜色
thickness:线条的粗细,默认为1
lineType:线条的类型,默认为cv.LINE_8
bottomLeftOrigin:图像数据原点的位置,默认左上角。
import cv2 as cv
import numpy as np
import sys
if __name__ =='__main__':
#生成一幅黑色的图像,用于在其中绘制图像
img=np.zeros((512,512,3),dtype='uint8')
#绘制圆形
#绘制实心圆
img = cv.circle(img,(50,50),25,(255,255,255),-1)
#绘制空心圆
img=cv.circle(img,(100,50),20,(255,255,255),4)
#绘制直线
img = cv.line(img,(100,100),(200,100),(255,255,255),2,cv.LINE_4,0)
#绘制椭圆
img = cv.ellipse(img,(300,255),(100,70),0,0,270,(255.255,255),-1)
#用一些点近似一个椭圆
points=cv.ellipse2Poly((200,400),(100,7),0,0,360,2)
#使用直线将上述点显示出来
for i in range(len(points)-1):
img=cv.line(img,(points[i][0],points[i][1]),(points[i+1][0],points[i+1][1]),(255,0,0),2,cv.LINE_4,0)
img = cv.line(img,(points[-1][0],points[-1][1]),(points[0][0],points[0][1]),(255,0,0),2,cv.LINE_4,0)
#绘制矩形
img = cv.rectangle(img,(50,400),(100,450),(0,255,0),-1)
img = cv.rectangle(img,(400,450,60,50),(0,0,255),2)
#绘制多边形
pts = np.array([[350,83],[463,90],[500,171],[421,194],[338,141]],dtype='int32')
img = cv.fillPoly(img,[pts],(255,0,0),8)
#添加文字
img = cv.putText(img,'Learn Opencv',(150,70),2,1,(0,255,0))
cv.imshow('Image',img)
cv.waitKey(0)
cv.destroyAllWindows()
有时我们只对一张图像中的部分区域感兴趣,而原图像又比较大,如果带着非感兴趣区域一起处理会占用大量的内存,因此我们希望从原图像中截取部分图像再进行处理。这个区域称为感兴趣区域(Region Of Interest ,ROI)
介绍numpy中获得ROI的方式
ROI=img[x1:x2,y1,y2]
ROI:提取的感兴趣区域的结果
img:待提取的感兴趣区域所在的图像
x1,y1:感兴趣区域左上角坐标
x2,y2:感兴趣区域右下角坐标
通过 "="符号进行赋值的方式都是浅拷贝,在程序中要慎重使用以避免改变原始数据。深拷贝在创建变量的同时会在内存中分配新的地址,用于存储数据,因此不会改变原始数据。深拷贝可以通过copy()函数实现
a=b.copy()
a:拷贝结果
b:原拷贝区域
import cv2 as cv
import numpy as np
import sys
if __name__=='__main__':
img = cv.imread('./chapter_3/lena.jpg')
flower=cv.imread('./chapter_3/flower.jpg')
mask = cv.resize(flower,(200,200))
#深拷贝
img1 = img.copy()
#浅拷贝
img2 = img
#截取图像的ROI
ROI = img[206:406,206:406]
#深拷贝
ROI_copy=ROI.copy()
#浅拷贝
ROI1=ROI
img[206:406,206:406]=mask
#展示结果
cv.imshow('img+flower1',img1)
cv.imshow('img + flower2',img2)
cv.imshow('ROI copy1',ROI_copy)
cv.imshow('ROI copy2',ROI1)
#在图像中绘制圆形
img = cv.circle(img,(300,300),20,(0,0,255),-1)
cv.imshow('img + circle1',img1)
cv.imshow('img + circle2',img2)
cv.imshow('ROI circle1',ROI_copy)
cv.imshow('ROI circle2',ROI1)
cv.waitKey(0)
cv.destroyAllWindows()