You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在OpenCV.js(浏览器CDN)中实现cv2.pencilSketch()功能?

在JavaScript中实现铅笔素描效果(替代OpenCV.js缺失的pencilSketch方法)

OpenCV.js并未提供与Python版cv2.pencilSketch()对应的封装方法,但可以通过OpenCV.js的基础API手动复刻该功能。以下是具体实现思路和代码:

核心实现步骤

Python版cv2.pencilSketch()的本质是通过边缘检测+色调纹理融合模拟素描效果,可拆解为以下步骤:

  • 将彩色图像转换为灰度图
  • 保留边缘的平滑处理(避免噪点干扰边缘提取)
  • 提取边缘并反转(让边缘呈现白色线条,契合素描视觉)
  • 生成带有铅笔质感的色调层
  • 融合边缘层与色调层得到最终素描效果

完整代码实现

function pencilSketch(src) {
    // 初始化临时Mat对象
    const gray = new cv.Mat();
    const filtered = new cv.Mat();
    const edges = new cv.Mat();
    const shade = new cv.Mat();
    const sketch = new cv.Mat();

    try {
        // 1. 转为灰度图
        cv.cvtColor(src, gray, cv.COLOR_RGBA2GRAY);
        
        // 2. 双边滤波:保留边缘同时平滑区域
        cv.bilateralFilter(gray, filtered, 9, 75, 75, cv.BORDER_DEFAULT);
        
        // 3. Canny边缘检测 + 反转(边缘为白色,背景为黑色)
        cv.Canny(filtered, edges, 30, 150);
        cv.bitwise_not(edges, edges);
        
        // 4. 生成铅笔色调层:模糊+反转+融合灰度图模拟质感
        cv.GaussianBlur(gray, shade, new cv.Size(0, 0), 3);
        cv.divide(255, shade, shade, 1, cv.CV_8U);
        cv.multiply(gray, shade, shade, 1, cv.CV_8U);
        
        // 5. 融合边缘与色调层
        cv.multiply(shade, edges, sketch, 1/255, cv.CV_8U);
        
        return sketch;
    } finally {
        // 释放临时内存,避免浏览器内存泄漏
        gray.delete();
        filtered.delete();
        edges.delete();
        shade.delete();
    }
}

// 使用示例(需确保已加载OpenCV.js并获取到输入图像Mat)
// const src = cv.imread('inputImageElement');
// const result = pencilSketch(src);
// cv.imshow('outputCanvas', result);
// src.delete();
// result.delete();

参数调整建议

  • 双边滤波参数9,75,75:增大数值会让边缘更柔和,减小则保留更多细节
  • Canny阈值30,150:提高阈值会减少边缘数量,降低则保留更多细微线条
  • 高斯模糊参数new cv.Size(0,0),3:增大模糊程度会让色调层更柔和,素描质感更强

内容的提问来源于stack exchange,提问作者AgentNirmites

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 10:05:24