文章目录
- OpenCv基础之绘图及几何变换实例
- 创建背景图
- 线段绘制
- 矩形绘制
- 圆绘制
- 椭圆绘制
- 绘制多边形
- 添加文字
- 几何变换
- 图像平移
- 图像缩放
- 图像旋转
- 仿射变换
- 透视变化
OpenCv基础之绘图及几何变换实例
绘图在图像处理中,主要是在处理完图像后,将图像中的目标进行标注,以便于检验处理效果。
创建背景图
# 创建一张黑色的背景图
img = np.zeros((512,512,3),np.uint8)
线段绘制
cv.line(img, pt1, pt2, color, thickness=None, lineType=None, shift=None)
- img:要绘制线条的图像,可以是灰度图像或彩色图像。
- pt1:线条的起点坐标,为二元组(x1, y1)。
- pt2:线条的终点坐标,为二元组(x2, y2)。
- color:线条的颜色,可为标量、元组或列表。如果为标量,则表示使用灰度值(0255)进行绘制;如果为元组或列表,则表示使用BGR值(Blue, Green, Red,0255)进行绘制。
- thickness:线条的宽度,为正整数。如果不指定,则默认为1。(-1为填充)
- lineType:线条的类型,有8连通、4连通、抗锯齿等类型可选。如果不指定,则默认为8连通。
- shift:坐标点小数位的位数。如果不指定,则默认为0,即坐标点为整数。
# 绘制一条,从图像坐标中[100,100]到[200,200]颜色为蓝色,限宽为5个像素的线段
res = cv2.line(img,(100,100),(200,200),(255,0,0),5)
cv2.imshow('res',res)
cv2.waitKey(0)
矩形绘制
cv.rectangle(img, pt1, pt2, color, thickness=None, lineType=None, shift=None)
- pt1:矩形的左上角坐标,为二元组(x1, y1)。
- pt2:矩形的右下角坐标,为二元组(x2, y2)。
其他参数,参考线段函数说明即可。
# 画一个长为200,宽为100的绿色边框的矩形
res = cv2.rectangle(img,(150,100),(250,300),(0,255,0),3)
cv2.imshow('res',res)
cv2.waitKey(0)
圆绘制
cv.circle(img, prets, radius, color, thickness=None, lineType=None, shift=None)
- prets:圆心坐标
- radius:半径
其他参数,参考线段函数说明即可。
# 画一个半径为100像素且填充红色的圆
res = cv2.circle(img,(200,200),100,(0,0,255),-1)
cv2.imshow('res',res)
cv2.waitKey(0)
椭圆绘制
cv.ellipse(img, center, axes, angle, startAngle, endAngle, color, thickness=None, lineType=None, shift=None)
- center:椭圆形的中心点坐标
- axes:椭圆形两条轴的长度
- angle:椭圆形相对于水平方向的旋转角度(逆时针)
- startAngle:起始角度(单位为度)
- endAngle:结束角度(单位为度)
其他参数,参考线段函数说明即可。
# 在图中心画一个长轴为100,短轴半长为50且用蓝色填充的半椭圆,起始角度为0,结束角度为180
res = cv2.ellipse(img,(200,200),(100,50),0,0,180,(255,0,0),-1)
cv2.imshow('res',res)
cv2.waitKey(0)
绘制多边形
cv.polylines(img, pts, isClosed, color, thickness=None, lineType=None, shift=None)
- pts:多边形的顶点坐标,需要以数组形式传入,如 np.array([[x1, y1], [x2, y2], [x3, y3], …], dtype=np.int32)。
- isClosed:是否闭合多边形。如果为 True,则闭合多边形;如果为 False,则不闭合多边形。
# 定义三角形的顶点坐标
pts = np.array([[100, 300], [300, 300], [200, 100]], np.int32)
# 绘制一个蓝色的三角形
res = cv2.polylines(img, [pts], True, (255, 0, 0), 2)
cv2.imshow('res',res)
cv2.waitKey(0)
添加文字
cv2.putText(img, text, org, fontFace, fontScale, color, thickness=None, lineType=None, bottomLeftOrigin=None)
- text:要绘制的文本内容。
- org:文本框左下角的坐标。
- fontFace:字体类型,如 cv2.FONT_HERSHEY_SIMPLEX、cv2.FONT_HERSHEY_PLAIN、cv2.FONT_HERSHEY_DUPLEX 等。
- fontScale:字体缩放比例。
- bottomLeftOrigin:如果为 True,则文本框的原点为左下角;如果为 False,则文本框的原点为左上角。默认为 False。
font = cv2.FONT_HERSHEY_SIMPLEX# 字体类型
cv2.putText(img_zeros,'Hello OpenCv',(10,200),font,1,(255,255,255),2,cv2.LINE_AA)
cv2.imshow('res',img)
cv2.waitKey(0)
除此之外,读者也可以通过改变其中的数据,改变其线条类型、粗细以及其他性质,对其有更好的理解。
几何变换
图像平移
即将图像中所有的点按照指定的平移量水平或者垂直移动。
dst = cv2.warpAffine(src, M, dsize[], dst[], flags,borderMode, borderValue)
- 参数src表示输入的源图像
- 参数M表示仿射变换矩阵
- 参数dsize表示输出图像的大小,可以使用src.shape[1], src.shape[0]表示输出图像的大小为输入图像的大小。
- 参数dst表示输出的目标图像,如果没有指定,则函数会自动创建一个与输入图像大小相同的图像。
- 参数flags表示插值算法的类型,可以指定为cv2.INTER_LINEAR(线性插值)、cv2.INTER_NEAREST(最近邻插值)、cv2.INTER_CUBIC(三次样条插值)、cv2.INTER_AREA(区域插值)、cv2.INTER_LANCZOS4(lanczos插值)等。
- 参数borderMode表示边界模式的类型,可以指定为cv2.BORDER_CONSTANT、cv2.BORDER_REPLICATE、cv2.BORDER_REFLECT、cv2.BORDER_WRAP等。
- 参数borderValue表示当使用cv2.BORDER_CONSTANT边界模式时,指定的填充值。
# 读取图像信息
img = cv2.imread('img/orange.png')
# 构造移动矩阵,在x轴方向移动50个像素距离,在y移动25个像素距离
M = np.float32([[1,0,50],[0,1,25]])
rows,cols = img.shape[:2]# 获得图像的行列像素
# 对图像进行仿射变换(线性变换),它可以用于对图像进行平移、旋转、缩放、翻转等操作
res = cv2.warpAffine(img,M,(cols+50,rows+50),borderMode=cv2.INTER_LANCZOS4)# 注意,这里rows和cols需要反置,即先列后行
cv2.imshow('origin-picture',img)
cv2.imshow('new-picture',res)
cv2.waitKey(0)
cv2.destroyAllWindows()
图像缩放
按照指定的比例进行放大或缩小,下采样:缩小,上采样:放大
cv.resize(src,dsize=None,fx,fy,interpolation),dsize输出图像尺寸,fx沿水平轴的比例因子,fy沿垂直轴的比例因子,interpolation插值方法
插值方法:默认cv2.INTER_NEAREST最近邻插值,INTER_LINEAR线性插值,INTER_CUBIC三次样条插值(44像素邻域),INTER_LANCZOS4(lanczos插值,88像素邻域),INTER_AREA区域插值
# 方式1:通过设置缩放比例,来对图像进行放大或缩小(放大2倍)
resl = cv2.resize(img,None,fx=2,fy =2,interpolation=cv2.INTER_LINEAR)
# 缩小
height ,width = img.shape[:2]
# 方式2:直接设置图像的大小,不需要缩放因子
res2 = cv2.resize(img,(int(0.8*width),int(0.8*height)),interpolation=cv2.INTER_AREA)
cv2.imshow('origin_picture',img)
cv2.imshow('res1',resl)
cv2.imshow('res2',res2)
cv2.waitKey(0)
cv2.destroyAllWindows()
由于缩放图像需要通过cv进行展示,通过matplotlib展示不能够观察到缩放的效果。
图像旋转
即以图像的中心为原点,旋转一定的角度,即就是将图像上的所有像素都旋转一个相同的角度。
问题:旋转后图像的大小一般会改变,即可以把转出显示区域的图像截去,或者扩大图像范围来显示所有的图像。
解决方法:①旋转前通过坐标平移,避免信息的丢失,②图像旋转后进行填充处理
# 参数1:旋转中心,参数2:旋转角度,参数3:缩放因子(正为逆时针,负为正时针)
M = cv2.getRotationMatrix2D((cols/2,rows/2),45,0.5)
dst = cv2.warpAffine(img,M,(cols,rows),borderValue=(255,255,255))
cv2.imshow('origin-picture',img)
cv2.imshow('rotation',dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
仿射变换
通过对图片进行旋转,平移,缩放,剪切,反射等操作已达到数据增强的效果。
cv.getAffineTransform(pos1,pos2)
pos1变换前位置,pos2变换后位置,用于获取从三个点的原始坐标到三个点的目标坐标的仿射变换矩阵。它接受三个源点和三个目标点,并返回一个2x3的仿射变换矩阵。
rows,cols = img.shape[:2]
pos1 = np.float32([[50,50],[200,50],[50,200]])
pos2 = np.float32([[10,100],[200,50],[100,250]])
M = cv2.getAffineTransform(pos1,pos2)
result = cv2.warpAffine(img,M,(cols,rows))
cv2.imshow('origin-picture',img)
cv2.imshow('affine',result)
cv2.waitKey(0)
cv2.destroyAllWindows()
透视变化
对图像进行投影变换、透视变换、视角变换等操作
- cv2.getPerspectiveTransform(src, dst)函数,可以根据输入图像和输出图像中的四个点计算出透视变换矩阵;参数src表示输入图像中的四个顶点的坐标,参数dst表示输出图像中的四个顶点的坐标。函数会返回一个透视变换矩阵M。
- cv2.warpPerspective(src, M, dsize[], dst, flags, borderMode, borderValue)根据透视变换矩阵对图像进行变换。
参数src表示输入的源图像,参数M表示透视变换矩阵,参数dsize表示输出图像的大小,可以使用src.shape[1], src.shape[0]表示输出图像的大小为输入图像的大小。
参数dst表示输出的目标图像,如果没有指定,则函数会自动创建一个与输入图像大小相同的图像。 - 参数flags表示插值算法的类型,可以指定为cv2.INTER_LINEAR、cv2.INTER_NEAREST、cv2.INTER_CUBIC、cv2.INTER_AREA、cv2.INTER_LANCZOS4等。
- 参数borderMode表示边界模式的类型,可以指定为cv2.BORDER_CONSTANT、cv2.BORDER_REPLICATE、cv2.BORDER_REFLECT、cv2.BORDER_WRAP等。
参数borderValue表示当使用cv2.BORDER_CONSTANT边界模式时,指定的填充值。
rows,cols = img.shape[:2]
# 定义输入图像中的四个顶点
src_points = np.float32([[0, 0], [cols - 1, 0], [cols - 1, rows - 1], [0, rows - 1]])
# 定义输出图像中的四个顶点
dst_points = np.float32([[0, 0], [cols - 1, 0], [int(0.6 * cols), rows - 1], [int(0.4 * cols), rows - 1]])
# 根据输入图像和输出图像中的四个点计算出透视变换矩阵
M = cv2.getPerspectiveTransform(src_points,dst_points)
# 根据透视变换矩阵对图像进行变换
result = cv2.warpPerspective(img,M,(cols-1,rows-1),flags=cv2.INTER_LINEAR,borderMode=cv2.BORDER_CONSTANT,borderValue=(255,255,0))
cv2.imshow('origin-picture',img)
cv2.imshow('perspective',result)
cv2.waitKey(0)
cv2.destroyAllWindows()
以上只是罗列了一些基本属性,实际应用中,还需要我们进一步查询API或者资料,进行深入学习,以上实例仅供学习。