OpenCV踩坑(一)为什么你的cv2.drawContours()绘制轮廓失败

活不多说,先上代码:(错的哈!!!)

import cv2

# 读入银行卡数字的模板图片 灰度图
template = cv2.imread('ocr_a_reference.png')
template = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)
# 对模板图片进行二值化
template_thresh = cv2.threshold(template, 10, 255, cv2.THRESH_BINARY_INV)[1]
cv2.imshow('template_thresh', template_thresh)
cv2.waitKey(0)
# 轮廓检测 cv2.RETR_EXTERNAL--检测外侧轮廓
contours, hierarchy = cv2.findContours(template_thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
print(contours)
# 轮廓绘制
res = cv2.drawContours(template_thresh.copy(), contours, -1, (0, 0, 255), 3) 
cv2.imshow('res', res)
cv2.waitKey(0)
cv2.destroyAllWindows()

搞定,没报错-->运行

图片预处理之后(嗯,没毛病...)

接下来,看到绘制轮廓的图我傻了...

what??? 这是啥?这咋还变瘦了呢?

<think> 我们正在讨论如何在绘制轮廓时调整线条粗细。根据OpenCV的文档,`cv2.drawContours`函数有个参数可以控制线条粗细。 在引用[1]中,我们看到调用方式为:`cv2.drawContours(image_c, contours, -1, (255), 1)` 这里的最后个参数`1`就是线条的粗细(以像素为单位)。如果我们想要更粗的线条,可以增加这个值。 函数原型(以Python为例): cv2.drawContours(image, contours, contourIdx, color[, thickness[, lineType[, hierarchy[, maxLevel[, offset]]]]]) 其中: thickness: 轮廓线条的粗细。如果为负值(例如-1),则表示填充轮廓内部。 因此,调整线条粗细的方法是改变`thickness`参数的值。 例如,想要绘制3个像素宽的轮廓线: `cv2.drawContours(image_c, contours, -1, (255), 3)` 注意:在引用[1]中,轮廓是在二值图像上绘制的,所以颜色是(255)(白色)。如果是彩色图像,颜色可以是三元组,如(0,255,0)表示绿色。 另外,在引用[2]中,我们看到绘制轮廓时使用了绿色和2像素粗细:`cv2.drawContours(img, refCnts, -1, (0, 255, 0), 2)` 因此,用户只需在调用`cv.drawContours`(在OpenCV.js中函数名相同)时,将`thickness`参数设置为所需的值即可。 在OpenCV.js中,该函数的参数顺序与Python类似,但需要注意JavaScript版本的参数传递方式。 示例(OpenCV.js): cv.drawContours(dstImage, contours, contourIndex, color, thickness, lineType, hierarchy, maxLevel, offset); 实际使用中,我们可以只传递必要的参数,比如: cv.drawContours(dstImage, contours, -1, new cv.Scalar(255, 255, 255), 2); 这里,`thickness`参数设置为2,表示2像素宽。 注意:在OpenCV.js中,颜色是cv.Scalar对象,如果是灰度图,则使用单个数值(如255)或Scalar.all(255);如果是彩色,则使用Scalar(B, G, R)(注意顺序是蓝、绿、红)。 所以,调整线条粗细的关键就是设置`thickness`参数。 下面给出个在OpenCV.js中绘制轮廓并调整线条粗细的完整示例: 步骤: 1. 读取图像并转换为灰度图 2. 二值化 3. 查找轮廓 4. 创建个空白图像(用于绘制轮廓) 5. 在空白图像上绘制轮廓,并指定线条粗细 代码示例(在Vue项目中,假设已经加载了OpenCV.js): </think> 在 OpenCV.js 中使用 `cv.drawContours()` 函数绘制轮廓图时,调整线条粗细的关键是正确设置函数的 **`thickness` 参数**。以下是详细方法和技术要点: ### 📏 线条粗细调整方法 ```javascript // 基本语法 cv.drawContours( image, // 目标图像(需要绘制的画布) contours, // 检测到的轮廓数组 contourIdx, // 要绘制轮廓索引(-1 表示所有轮廓) color, // 线条颜色(Scalar 对象) thickness, // 线条粗细(关键参数) lineType, // 线条类型(可选) hierarchy, // 轮廓层级信息(可选) maxLevel // 绘制的最大层级(可选) ); ``` #### 1. **核心参数说明** - **`thickness`**:控制线条宽度的整数值 - `>0`:表示线条像素宽度(如 `2` = 2像素宽) - `=0`:默认值,绘制1像素宽线条 - `=-1`:填充整个轮廓区域(实心图形) #### 2. **调整粗细的代码示例** ```javascript // 创建空白图像(用于绘制轮廓) const height = srcMat.rows; const width = srcMat.cols; const contourImage = new cv.Mat.zeros(height, width, cv.CV_8UC3); // 绘制轮廓(设置不同粗细) cv.drawContours(contourImage, contours, -1, new cv.Scalar(0, 255, 0), // 绿色线条 3); // 3像素宽线条 [^1] // 对比:绘制1像素细线条 cv.drawContours(contourImage, contours, -1, new cv.Scalar(255, 0, 0), // 蓝色线条 1); // 1像素宽 [^2] // 对比:填充轮廓(实心效果) cv.drawContours(contourImage, contours, -1, new cv.Scalar(0, 0, 255), // 红色填充 -1); // 填充模式 [^1] ``` ### ⚙️ 高级技巧 1. **颜色自定义** 颜色通过 `cv.Scalar(B, G, R)` 设置: ```javascript // 红色粗线条 (BGR格式) new cv.Scalar(0, 0, 255), // B=0, G=0, R=255 → 红色 thickness: 5 ``` 2. **线条类型优化** 添加 `lineType` 参数改善渲染质量: ```javascript cv.drawContours(contourImage, contours, -1, new cv.Scalar(255,255,255), 4, // 4像素宽 cv.LINE_AA); // 抗锯齿线条 [^2] ``` 3. **局部轮廓绘制** 选择性绘制特定轮廓: ```javascript // 只绘制轮廓(索引0) cv.drawContours(contourImage, contours, 0, new cv.Scalar(0,255,255), 2); ``` ### 📐 效果对比表 | `thickness` 值 | 效果 | 适用场景 | |----------------|------|----------| | **1** | 1像素细线 | 高精度边缘检测 | | **2-4** | 中等粗细 | 常规物体轮廓提取(推荐) | | **>5** | 粗线条 | 强调主要轮廓/可视化展示 | | **-1** | 区域填充 | 轮廓内部着色/掩模生成 | ### 💡 最佳实践建议 1. **移动端优化**:在移动设备上将线条宽度设为 **2-3像素**,平衡清晰度和渲染性能 2. **动态调整**:根据图像分辨率自动计算粗细比例 ```javascript const adaptiveThickness = Math.max(1, Math.round(width / 300)); cv.drawContours(..., adaptiveThickness); ``` 3. **内存管理**:绘图后及时释放资源 ```javascript contourImage.delete(); // 避免内存泄漏 ``` > **技术要点**:在引用[1][^1]和引用[2][^2]中的轮廓绘制代码中,通过修改`thickness`参数值即可直接控制线条粗细。例如将`1`改为`3`会使线条宽度增加到3像素。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值