cv2函数原型-几何形状(矩形/直线/圆/椭圆/多边形/线段/标记/文字)轮廓(外接框/旋转框/凸包)绘图(字体/渲染类型)

目录

矩形(rectangle)

直线

cv2.fitLine (4.5.3.56)

圆(circle)

cv2.HoughCircles

椭圆(ellipse)

cv2.fitEllipse(4.4.0.46)

多边形

cv2.fillPoly

轮廓(Contours)

cv2.findContours (4.4.0.46)

cv2.drawContours (4.5.5.64)

cv2.contourArea (4.4.0.46)

凸包 cv2.convexHull (4.5.5.64)

cv2.boundingRect (4.4.0.46)

cv2.minAreaRect (4.4.0.46 | 4.5.5.64)

cv2.boxPoints (4.5.3.56)

箭头线段

标记

cv2.drawMarker

文字


矩形(rectangle)

# pt:`(x, y)`, color:`BGR`, 该方法直接作用于img, 并返回img自身
cv2.rectangle(img_bgr, (w//4, h//4), (w//2, h//2), color=(0, 0, 255), thickness=2)

直线

cv2.fitLine (4.5.3.56)
输入:shape=(M,2)的点集,M为点数,注意与轮廓(M,1,2)的区别
输出:shape=(4,1),代表一条直线

提取直线,假设已知直线上的两个点,在图像中像素坐标分别为(100, 100)和(150, 50)

>>> cv2.fitLine(np.array([[100, 100], [150, 50]]), cv2.DIST_L1, 0, 1, 1)
array([[  0.70710677],
       [ -0.70710677],
       [125.        ],
       [ 75.        ]], dtype=float32)
array([[cos_Theta],
       [sin_Theta],
       [x0       ],
       [y0       ]], dtype=float32)

Theta是x轴旋转到与直线重合的角度(x轴水平与直线相交,按就近原则,x轴旋转到与直线重合,所经过的角度值;若逆时针更近则角度值为-89.9999~0,若顺时针更近则角度值为0~90,垂直为90)。

计算斜率:

k_inv = 0
if abs(line[1]) > 1e-10:
    k_inv = line[0] / line[1]  # 斜率k=x/y

圆(circle)

cv2.HoughCircles

todo…

椭圆(ellipse)

椭圆转多边形

cv2.fitEllipse(4.4.0.46)

todo…


多边形

fillConvexPoly,fillPoly,polylines

cv2.fillPoly

fillPoly(img, pts, color[, lineType[, shift[, offset]]]) -> img

用于一个或多个图形(不规则多边形)的填充。

多边形的列表,每个多边形可以是shape=(M,2)或(M,1,2)轮廓。

polygons = [np.array([[100,100], [200,230], [150,200], [100,220]], dtype = np.int32), ...]
cv2.fillPoly(img, polygons, color)

官方解释是一次填充多个多边形,但某次我使用过程中,一次无法填充多个多边形!还是逐个填充是比较保险的方法:

[cv2.fillPoly(img, [poly], color) for poly in polygons]

假设用轮廓,contours.shape=(N,M,1,2),下列两种方式,结果不同:

# 填充内部
cv2.fillPoly(img,[contours[1]],(255,0,0))

# 只染色边界,原因是把轮廓上的M个点当成M个多边形
cv2.fillPoly(img,contours[1],(255,0,0))

实例:

area1 = np.array([[250, 200], [300, 100], [750, 800], [100, 1000]])
area2 = np.array([[1000, 200], [1500, 200], [1500, 400], [1000, 400]])
img = np.zeros((1080, 1920, 3), np.uint8)
cv2.fillPoly(img, [area1, area2], color=(255, 255, 255))

轮廓(Contours

cv2.findContours (4.4.0.46)

findContours(image, mode, method[, contours[, hierarchy[, offset]]]) -> contours, hierarchy

找图中轮廓。

conts, hier = cv2.findContours(cls_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

输入

  • image:8-bit单通道,非0为1,视为二值化图像
  • mode:轮廓层级关系的模式
    • 0=cv2.RETR_EXTERNAL:仅检测外轮廓
    • 1=cv2.RETR_LIST:检测所有轮廓,但轮廓间没有给出层级关系
    • 2=cv2.RETR_CCOMP:仅给出两层包含关系,即某个轮廓包含其他轮廓,就算外轮廓
    • 3=cv2.RETR_TREE:检测所有轮廓,并给出完整的层级关系
    • 4=cv2.RETR_FLOODFILL:
  • method:轮廓点集存储的近似算法
    • 1=cv2.CHAIN_APPROX_NONE:连续点只相差一个像素,密集型
    • 2=cv2.CHAIN_APPROX_SIMPLE:横向/纵向/对角线段上的点只保存端点,例如矩形只存四个顶点
    • 3=cv2.CHAIN_APPROX_TC89_L1:
    • 4=cv2.CHAIN_APPROX_TC89_KCOS:

输出

  • contours:检测到的轮廓列表( __len__ =N=轮廓数),N个轮廓都是shape=(M,1,2)的ndarray(int32),M为每个轮廓的点数,shape为啥不是(M,2)?
  • hierarchy:轮廓之间的层级关系,shape=(1,N,4),依次标识N个轮廓的 同级后一个轮廓的序号 、 同级前一个轮廓的序号 、 第一个子轮廓的序号 和 父轮廓的序号 ,没有则为-1

参考:

https://blog.csdn.net/zb1165048017/article/details/109404373

https://docs.opencv.org/4.5.0/d9/d8b/tutorial_py_contours_hierarchy.html

cv2.drawContours (4.5.5.64)

drawContours(image, contours, contourIdx, color[, thickness[, lineType[, hierarchy[, maxLevel[, offset]]]]]) -> image

原地修改绘制多个轮廓。

  • contourIdx表示绘制轮廓的id,若为负则绘制所有轮廓
  • color绘制颜色值
  • thickness轮廓粗细,若为负则填充轮廓(closed)

cv2.contourArea (4.4.0.46)

contourArea(contour[, oriented]) -> area: float

凸包 cv2.convexHull (4.5.5.64)

convexHull(points[, hull[, clockwise[, returnPoints]]]) -> hull

根据点集/轮廓,计算凸包。

输入:shape=(M,2)/(M,1,2)/(1,M,2)的点集,M为点数
输出:shape=(N,1,2),代表一个凸包,N为凸包点数

cv2.boundingRect (4.4.0.46)

boundingRect(array) -> (x, y, w, h)

找包围了所有点/灰度图所有非0像素点的正外接矩形(直边界)。

输入:array.shape=(M,1,2)的二维点集或shape=(H,W)的灰度图

cv2.minAreaRect (4.4.0.46 | 4.5.5.64)

minAreaRect(points) -> ((cx, cy), (cw, ch), angle)

找包围了所有点的最小面积外接旋转矩形框。输入可以是二维点集/轮廓shape=(M,1,2)。

返回值都是float类型,分别表示旋转矩形的中心点坐标宽高角度

在OpenCV(4.5)之前:

角度为[-90, 0),由矩形最低点所在x轴 逆时针旋转到 第一次重合的边 所经过的角度值;首次重合的边即为新的x轴==w宽度(因此旋转矩形的宽度不一定是横向的那条边长,也可能是纵向的边长)

而(4.5.3.56)及之后 角度 改了, 宽w 的定义也有变化!!!

角度angle总是为(0, 90],为x轴(矩形最低点) 顺时针 旋转的角度,最先重合的边为w

x轴顺时针为正数,逆时针为负数。

角度在旋转图像中有用,角度为正==x轴顺时针旋转,角度为负==x轴逆时针旋转,图像整体则是反方向转

旋转矩形框rect就只分长边和短边。

算法上只需分两种情况:w是不是短边?

long_angle = w>h ? angle : angle-90,其中long_angle是长边方向角度,angle是旋转框角度

4.4.0.46及之前(逆时针旋转30°)

4.5.3.56及之后(顺时针旋转60°)—— w 和 h 互换,angle 由逆变顺

虽然不同版本cv2.minAreaRect计算得到的宽高、角度不同,但中心点和旋转结果图是一样的。

参考:https://zhuanlan.zhihu.com/p/491547614

cv2.boxPoints (4.5.3.56)

boxPoints(box[, points]) -> points

官方解释:Finds the four vertices of a rotated rect. Useful to draw the rotated rectangle.

计算旋转框的四个角点坐标,返回值为<class 'numpy.ndarray'>, array([ x, y ], dtype=float32), shape=(4, 2), 闭合多边形按逆时针顺序(但起始点和结束点不明确),如:

rotRect = cv2.minAreaRect(contour)
box_pts = cv2.boxPoints(rotRect)
box_pts =
    [[ 78.349365  69.19873 ]
     [121.650635  44.19873 ]
     [171.65063  130.80127 ]
     [128.34937  155.80127 ]]

可以cv2.polylines用来绘制:

cv2.polylines(img, [box_pts.astype(np.int32)], 1, 255)

箭头线段

arrowedLine

标记

cv2.drawMarker

文字

cv2字体大小计算

getFontScaleFromHeight

getTextSize

# 该方法直接作用于img, 返回img
cv2.putText(img_bgr, '~', (w//4, h//4),cv2.FONT_HERSHEY_SIMPLEX, 1.5, [255, 0, 255], 3, cv2.LINE_AA)

官网:https://docs.opencv.org/4.5.5/d6/d6e/group__imgproc__draw.html


持续更新中……

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值