OpenCV Python 绘图函数实战cv.line、cv.rectangle、cv.circle、cv.ellipse 与 cv.putText 全解【免费下载链接】opencvOpen Source Computer Vision Library项目地址: https://gitcode.com/GitHub_Trending/opencv31/opencv本篇基于 OpenCV 官方 Python 教程py_drawing_functions系统讲解如何使用 OpenCV 的绘制 API 在图像上画出直线、矩形、圆、椭圆、多边形并添加文字。读完本文你不仅能掌握cv.line()、cv.rectangle()、cv.circle()、cv.ellipse()、cv.polylines()、cv.putText()的完整用法与参数含义还能结合 modules/imgproc/src/drawing.cpp 中的源码实现理解 thickness 填充规则、LINE_AA 抗锯齿的降级逻辑以及多折线批量绘制的底层机制从而在实际项目中正确、高效地完成图像标注与结果可视化。一、绘图函数的公共参数OpenCV 中所有基础绘图函数直线、矩形、圆、椭圆、多边形、文字共享一组核心参数理解它们是掌握全部绘图 API 的前提来源官方教程参数说明img要在其上进行绘制的目标图像即绘图画布color形状颜色。BGR 三通道图像传元组例如蓝色为(255,0,0)灰度图像直接传标量值thickness线条/圆的粗细。对圆等封闭图形传-1时会填充整个形状。默认粗细为1lineType线的类型如 8 连通线、抗锯齿线等。默认为 8 连通。cv.LINE_AA提供抗锯齿效果画曲线时视觉效果好得多从源码结构看这组参数的行为有明确的实现约束抗锯齿只对 8 位图生效在 line() 实现 中可以看到if( line_type cv::LINE_AA img.depth() ! CV_8U ) line_type 8;——当图像不是CV_8U深度时LINE_AA会被自动降级回 8 连通线。圆、矩形、椭圆、多边形circle()、rectangle()、ellipse()、polylines()均有同样的降级逻辑因此抗锯齿主要服务于uint8图像。LINE_AA的取值在 modules/imgproc/include/opencv2/imgproc.hpp 中定义为LINE_AA 16与教程中默认为 8 连通的说法相互印证。thickness 的合法性检查line()中通过CV_Assert( 0 thickness thickness MAX_THICKNESS )断言约束线宽而thickness -1的填充语义由各图形函数分别处理例如rectangle()在thickness 0时走PolyLine描边、否则走FillConvexPoly填充见 rectangle() 实现。二、绘制直线cv.line()绘制直线需要传入起点和终点坐标。下面创建一张黑图并从左上角到右下角画一条蓝色对角线粗细 5 像素import numpy as np import cv2 as cv # 创建黑色图像 (512x512, 3通道) img np.zeros((512, 512, 3), np.uint8) # 绘制一条粗细为 5px 的蓝色对角线 cv.line(img, (0, 0), (511, 511), (255, 0, 0), 5)参数解读(0,0)与(511,511)是端点坐标(255,0,0)为 BGR 蓝色5是线宽。从 line() 源码 看cv.line()最终通过ThickLine()完成粗线光栅化其姊妹函数arrowedLine()L1845-L1864则通过两条额外的短线段构造箭头尖端可用于绘制带箭头的标注线。三、绘制矩形cv.rectangle()绘制矩形需要传入左上角与右下角两个坐标。这里在图像右上角画一个绿色矩形cv.rectangle(img, (384, 0), (510, 128), (0, 255, 0), 3)参数解读(384,0)和(510,128)是矩形的对角点(0,255,0)为绿色3是线宽。结合 rectangle() 源码 可知函数内部由两个对角点扩展出四个顶点pt[0..3]当thickness 0时按闭合折线描边传负值时则用FillConvexPoly填充整个矩形——即thickness -1得到实心矩形。此外还存在接受Rect对象的重载L1899-L1914会先把矩形裁剪到图像边界内再绘制因此画在图像外的目标检测框不会被忽略或报错。四、绘制圆cv.circle()绘制圆需要圆心坐标与半径。教程示例在上一节画的矩形内部绘制一个圆cv.circle(img, (447, 63), 63, (0, 0, 255), -1)参数解读(447,63)是圆心63是半径(0,0,255)为红色thickness -1表示填充因此画出一个实心红色圆。从 circle() 源码 可以看到一个有意思的实现细节cv.circle()本质上是特例化的椭圆绘制。当thickness 1、非 8 连通线或存在坐标偏移时函数内部将圆心与半径放大到XY_SHIFT精度后调用EllipseEx(img, center, (radius, radius), 0, 0, 360, ...)只有在最轻量的thickness 1 LINE_8场景下才走专门的Circle()快速路径。这也解释了为什么圆的thickness -1填充行为与椭圆一致。五、绘制椭圆cv.ellipse()椭圆是参数最多的绘制函数。需要依次提供中心坐标(x, y)两轴半轴长(semi-major axis, semi-minor axis)angle椭圆绕中心逆时针旋转的角度startAngle/endAngle椭圆弧的起止角从长轴方向开始顺时针测量0到360即完整椭圆。下面在图像中心画一个半椭圆白色、填充cv.ellipse(img, (256, 256), (100, 50), 0, 0, 180, 255, -1)参数解读中心(256,256)半轴(100,50)旋转角0从0°画到180°即半个椭圆颜色255白色-1填充。从 ellipse() 源码 看angle、startAngle、endAngle三个double入参会被cvRound取整为整数角度后传入EllipseEx()因此在 C 层面角度精度只到 1°axes会做非负断言CV_Assert( axes.width 0 axes.height 0 ... )。另有一个接受RotatedRect的重载L1979 起方便直接用检测器输出的旋转框画椭圆。注意cv.ellipse()中使用的角度并不是常见的标准圆角度其旋转方向与测量基准与其他 API 不同使用angle参数时务必以实际渲染结果为准、通过startAngle/endAngle组合调试。六、绘制多边形cv.polylines()绘制多边形的第一步是准备顶点坐标数组形状为ROWS x 1 x 2其中ROWS为顶点数且数据类型必须是int32。下面画一个黄色四顶点小多边形pts np.array([[10,5],[20,30],[70,20],[50,10]], np.int32) pts pts.reshape((-1, 1, 2)) cv.polylines(img, [pts], True, (0, 255, 255))参数解读[pts]是多边形列表外层列表表示可以一次画多个多边形True表示闭合(0,255,255)为 BGR 黄色。两点补充与教程 Note 一致若第三个参数isClosed为False得到的是依次连接所有点的折线而非闭合图形cv.polylines()支持一次传入多条折线把所有折线的点数组组成列表一次性传入即可每条折线独立绘制。相比对每条线单独调用cv.line()这是绘制一组线更快、更省的方式。从源码印证这两点polylines() 核心实现 通过for( int i 0; i ncontours; i )循环逐个轮廓调用PolyLine(..., isClosed, ...)正是逐条独立绘制的批量加速来源而 Python 绑定层 cv::polylines() 会识别vectorvectorPoint/vectorMat这类多轮廓输入manyContours分支自动拆分成指针数组传入底层这就是外层需要[pts]列表的原因。同时该层会校验每个点数组是 2 维CV_32S向量CV_Assert(p.checkVector(2, CV_32S) 0)与教程必须 int32的要求完全对应。七、在图像上添加文字cv.putText()在图像上写文字需要指定要写入的文本内容放置位置坐标即文字起始的左下角字体类型cv.FONT_HERSHEY_SIMPLEX等 Hershey 字体族;字体缩放比例fontScale决定文字大小以及颜色、thickness、lineType等常规参数。为了更好看推荐lineType cv.LINE_AA。下面在图像左下角用白色写出OpenCVfont cv.FONT_HERSHEY_SIMPLEX cv.putText(img, OpenCV, (10, 500), font, 4, (255, 255, 255), 2, cv.LINE_AA)参数解读(10,500)是文字基线左下角font为 Hershey 单线字体4是缩放倍数2是笔画粗细cv.LINE_AA让文字边缘平滑。从 modules/imgproc/src/drawing_text.cpp 的源码结构看putText()有两代实现传统的 Hershey 字体绘制入口putText() 接受fontface与ttsize以及较新的FontRenderEngine流水线putText_()后者支持 TrueType/OpenType 等 Unicode 字体渲染。Python 中cv.putText()对应的仍是 Hershey 字体接口支持的字体面即教程提到的cv.FONT_HERSHEY_*系列常量。八、完整示例与结果把以上代码段合并成一份可运行的完整脚本img逐段累积绘制顺序不可打乱import numpy as np import cv2 as cv # 创建黑色图像 img np.zeros((512, 512, 3), np.uint8) # 1. 粗细 5px 的蓝色对角线 cv.line(img, (0, 0), (511, 511), (255, 0, 0), 5) # 2. 右上角绿色矩形 cv.rectangle(img, (384, 0), (510, 128), (0, 255, 0), 3) # 3. 矩形内的实心红圆 cv.circle(img, (447, 63), 63, (0, 0, 255), -1) # 4. 图像中心的半椭圆白色填充 cv.ellipse(img, (256, 256), (100, 50), 0, 0, 180, 255, -1) # 5. 左上角黄色小多边形 pts np.array([[10, 5], [20, 30], [70, 20], [50, 10]], np.int32) pts pts.reshape((-1, 1, 2)) cv.polylines(img, [pts], True, (0, 255, 255)) # 6. 左下角白色文字 font cv.FONT_HERSHEY_SIMPLEX cv.putText(img, OpenCV, (10, 500), font, 4, (255, 255, 255), 2, cv.LINE_AA) # 显示结果 cv.imshow(Drawing Demo, img) cv.waitKey(0) cv.destroyAllWindows()运行后的效果即教程配图所示蓝色对角线、右上角绿色矩形内嵌实心红圆、中心白色半椭圆、左上角黄色多边形、左下角白色 OpenCV 文字见文首结果图 drawing_result.jpg。注意cv.imshow依赖 GUI 支持无头环境可改用cv.imwrite()保存图像再查看。九、练习与延伸阅读教程给出的实践题目尝试使用 OpenCV 的绘制函数绘制 OpenCV 的 Logo。建议组合使用cv.circle()-1 填充、cv.ellipse()startAngle/endAngle控制弧段与cv.polylines()能完整检验本文所有 API。进一步深入可查阅仓库中的这些位置全部形状绘制实现modules/imgproc/src/drawing.cpp含line、rectangle、circle、ellipse、polylines、fillConvexPoly、fillPoly、drawContours文字绘制实现modules/imgproc/src/drawing_text.cpp线型常量定义modules/imgproc/include/opencv2/imgproc.hppLINE_AA 16原始教程文档doc/py_tutorials/py_gui/py_drawing_functions/py_drawing_functions.markdown。最后提醒两条容易踩坑的适用前提cv.LINE_AA仅在CV_8U深度图像上真正生效否则自动降级为 8 连通见上文源码cv.polylines()的点数组必须是np.int32类型且形状符合N x 1 x 2的约定否则绑定层的checkVector(2, CV_32S)校验会直接报错。【免费下载链接】opencvOpen Source Computer Vision Library项目地址: https://gitcode.com/GitHub_Trending/opencv31/opencv创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考