{"id":16629999,"url":"https://github.com/jm12138/cannydetector","last_synced_at":"2025-03-16T22:30:58.928Z","repository":{"id":179618102,"uuid":"418187974","full_name":"jm12138/CannyDetector","owner":"jm12138","description":"A python implementation of  Canny Detector using numpy / scipy / torch / paddle package.","archived":false,"fork":false,"pushed_at":"2024-05-17T08:18:20.000Z","size":4138,"stargazers_count":24,"open_issues_count":0,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-10-13T04:44:35.311Z","etag":null,"topics":["canny-detector","numpy","opencv","paddle","paddlepaddle","pytorch","scipy","torch"],"latest_commit_sha":null,"homepage":"","language":"Jupyter Notebook","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jm12138.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-10-17T16:22:27.000Z","updated_at":"2024-09-13T07:39:36.000Z","dependencies_parsed_at":null,"dependency_job_id":"96625a5d-a25d-4e0f-9f08-18bb8d7bb882","html_url":"https://github.com/jm12138/CannyDetector","commit_stats":null,"previous_names":["jm12138/cannydetector"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jm12138%2FCannyDetector","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jm12138%2FCannyDetector/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jm12138%2FCannyDetector/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jm12138%2FCannyDetector/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jm12138","download_url":"https://codeload.github.com/jm12138/CannyDetector/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221668362,"owners_count":16860631,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["canny-detector","numpy","opencv","paddle","paddlepaddle","pytorch","scipy","torch"],"created_at":"2024-10-12T04:44:34.987Z","updated_at":"2024-10-27T11:26:25.642Z","avatar_url":"https://github.com/jm12138.png","language":"Jupyter Notebook","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 简介\n* 一个基于 Python 和 cv2 / numpy / scipy / torch / paddle 等模块实现的 Canny 边缘检测器\n\n* 本项目中包含如下三个版本的 Canny 边缘检测器：\n\n    * Python：使用 numpy 模块的原生 python 实现的简易版本 Canny 边缘检测器，效果一般\n\n    * Pytorch：基于 torch 深度学习框架实现的运用矩阵运算并行加速、GPU 计算加速的 Canny 边缘检测器，效果较好\n\n    * Paddle：基于 paddle 深度学习框架实现，功能与结果与 torch 版本保持一致\n\n* 项目总览：[Jupyter Notebook](./CannyDetector.ipynb)\n\n* 在线体验：[![](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/jm12138/CannyDetector/blob/main/CannyDetector.ipynb)   [![](https://img.shields.io/badge/AIStudio-Open%20in%20AIStudio-blue)](https://aistudio.baidu.com/aistudio/projectdetail/2490960)\n   \n# 更新\n* 【Bug Fix】修复大批量数据的边缘检测报错的问题 [@Beat-in-our-hearts](https://github.com/Beat-in-our-hearts) [#2](https://github.com/jm12138/CannyDetector/pull/2)\n\n# 目录结构\n* 本项目大致的文件目录结构及功能如下：\n\n    ```\n    │ requirements.txt # 依赖模块列表\n    │\n    │ CannyDetector.ipynb # Jupyter Notebook\n    │\n    ├─tools # 脚本工具\n    │  │ \n    │  ├─test_all.py # 总体测试脚本\n    │  │ \n    │  ├─test_opencv.py # OpenCV 测试脚本\n    │  │ \n    │  ├─test_paddle.py # Paddle 测试脚本\n    │  │ \n    │  ├─test_python.py # Python 测试脚本\n    │  │ \n    │  └─test_pytorch.py # Pytorch 测试脚本\n    │  \n    ├─cannydet # Canny 边缘检测器代码\n    │  │ \n    │  ├─paddle # Paddle 实现\n    │  │          \n    │  ├─python # Python 实现\n    │  │          \n    │  └─torch # Pytorch 实现\n    │          \n    ├─results # 输出结果\n    │  │ \n    │  ├─compare # 结果对比图像\n    │  │ \n    │  ├─cv2 # OpenCV 输出图像\n    │  │ \n    │  ├─paddle # Paddle 输出图像\n    │  │          \n    │  ├─python # Python 输出图像\n    │  │          \n    │  └─torch # Pytorch 输出图像\n    │      \n    └─test_imgs # 测试图像\n    ```\n\n# 算法原理\n* Canny 是一个经典的图像边缘检测算法，一般包含如下几个步骤：\n\n    * 使用高斯模糊对图像进行模糊降噪处理\n\n    * 基于图像梯度幅值进行图像边缘增强\n\n    * 非极大值抑制处理进行图像边缘细化\n\n    * 图像二值化和边缘连接得到最终的结果\n\n# 结果对比\n* 多种实现对比的实测效果图如下：\n\n    ![1-1.png](./results/compare/1-1.png)\n\n# 性能对比\n* 测试平台：\n\n    |CPU|显卡|内存|系统|\n    |:-:|:-:|:-:|:-:|\n    |AMD Ryzen 5 3600|Nvidia RTX 2060|8G|Windows10|\n\n* 使用上图作为测试图片测试多个实现的耗时长短：\n\n    |实现方式|耗时(s)|\n    |:-:|:-:|\n    |Python|11.51|\n    |Pytorch CPU|0.13|\n    |Pytorch GPU|0.04|\n    |Paddle CPU|0.40|\n    |Paddle GPU|0.06|\n    |OpenCV|0.02|\n\n# 快速使用\n* 安装依赖\n\n    ```bash\n    $ pip install -r requirements.txt\n    ```\n\n* 使用下面的命令运行测试脚本：\n\n    ```bash\n    # 运行所有实现的测试脚本\n    $ python tools/test_all.py\n\n    # 运行 OpenCV 实现的测试脚本\n    $ python tools/test_opencv.py\n\n    # 运行 Python 实现的测试脚本\n    $ python tools/test_python.py\n\n    # 运行 Pytorch 实现的测试脚本\n    $ python tools/test_pytorch.py\n\n    # 运行 Paddle 实现的测试脚本\n    $ python tools/test_paddle.py\n    ```\n\n* 使用脚本对自定义图片进行边缘检测：\n\n    * Python 实现：\n\n        ```python\n        import cv2\n        import numpy as np\n        \n        from cannydet.python import canny\n\n        lower = 0.1 # 最小阈值\n        upper = 0.3 # 最大阈值\n\n        img_path = 'test_imgs/1-1.jpg' # 指定测试图像路径\n        res_path = 'test.png' # 指定结果保存路径\n\n        gray = cv2.imread(img_path, 0) # 读取灰度图像\n        edge = canny(gray, lower, upper) # Canny 图像边缘检测\n        edge = (edge * 255).astype(np.uint8) # 反归一化\n\n        cv2.imshow('result', edge) # 结果预览\n        cv2.waitKey(0) # 等待响应\n        cv2.imwrite(res_path, edge) # 结果保存\n        ```\n\n    * Pytorch 实现：\n\n        ```python\n        import cv2\n        import torch\n        import numpy as np\n        \n        from cannydet.torch import CannyDetector\n\n        lower = 2.5  # 最小阈值\n        upper = 5  # 最大阈值\n\n        img_path = 'test_imgs/1-1.jpg'  # 指定测试图像路径\n        res_path = 'test.png'  # 指定结果保存路径\n\n        img = cv2.imread(img_path, 1)  # 读取彩色图像\n        img = np.transpose(img, [2, 1, 0]) / 255.0 # 转置 + 归一化\n        img_tensor = torch.from_numpy(img[None, ...]).float() # 转换为 Tensor\n\n        canny = CannyDetector(device='cpu') # 初始化 Canny 检测器，可设置其运行的设备\n\n        edge = canny(img_tensor, lower, upper)  # Canny 图像边缘检测\n        edge = np.squeeze(edge.cpu().numpy()) # 去除 Batch dim\n        edge = np.transpose(edge, [1, 0]) # 图像转置\n        edge = (edge * 255).astype(np.uint8)  # 反归一化\n\n        cv2.imshow('result', edge)  # 结果预览\n        cv2.waitKey(0)  # 等待响应\n        cv2.imwrite(res_path, edge)  # 结果保存\n        ```\n\n    * Paddle 实现：\n\n        ```python\n        import cv2\n        import paddle\n        import numpy as np\n        \n        from cannydet.paddle import CannyDetector\n\n        lower = 2.5  # 最小阈值\n        upper = 5  # 最大阈值\n\n        img_path = 'test_imgs/1-1.jpg'  # 指定测试图像路径\n        res_path = 'test.png'  # 指定结果保存路径\n\n        img = cv2.imread(img_path, 1)  # 读取彩色图像\n        img = np.transpose(img, [2, 1, 0]) / 255.0 # 转置 + 归一化\n        img_tensor = paddle.to_tensor(img[None, ...]).cast('float32') # 转换为 Tensor\n\n        paddle.set_device('cpu') # 设置其运行的设备\n        canny = CannyDetector() # 初始化 Canny 检测器\n\n        edge = canny(img_tensor, lower, upper)  # Canny 图像边缘检测\n        edge = np.squeeze(edge.numpy()) # 去除 Batch dim\n        edge = np.transpose(edge, [1, 0]) # 图像转置\n        edge = (edge * 255).astype(np.uint8)  # 反归一化\n\n        cv2.imshow('result', edge)  # 结果预览\n        cv2.waitKey(0)  # 等待响应\n        cv2.imwrite(res_path, edge)  # 结果保存\n        ```\n\n    * OpenCV 实现：\n\n        ```python\n        import cv2\n\n        lower = 30  # 最小阈值\n        upper = 70  # 最大阈值\n\n        img_path = 'test_imgs/1-1.jpg'  # 指定测试图像路径\n        res_path = 'test.png'  # 指定结果保存路径\n\n        gray = cv2.imread(img_path, 0)  # 读取灰度图像\n        edge = cv2.Canny(gray, lower, upper) # Canny 图像边缘检测\n\n        cv2.imshow('result', edge)  # 结果预览\n        cv2.waitKey(0)  # 等待响应\n        cv2.imwrite(res_path, edge)  # 结果保存\n        ```\n\n# 参考资料\n* 参考论文：\n\n    ```\n    @ARTICLE{4767851,\n    author={Canny, John},\n    journal={IEEE Transactions on Pattern Analysis and Machine Intelligence}, \n    title={A Computational Approach to Edge Detection}, \n    year={1986},\n    volume={PAMI-8},\n    number={6},\n    pages={679-698},\n    doi={10.1109/TPAMI.1986.4767851}}\n    ```\n\n* 参考项目：\n\n    * [DCurro/CannyEdgePytorch](https://github.com/DCurro/CannyEdgePytorch)\n\n* 参考文章：\n\n    * [Canny边缘检测 原理\u0026\u0026python代码](https://blog.csdn.net/xiachong27/article/details/88385123)\n\n    * [Canny 边缘检测算法-python实现](https://ai-chen.github.io/%E4%BC%A0%E7%BB%9F%E5%9B%BE%E5%83%8F%E5%A4%84%E7%90%86%E6%96%B9%E6%B3%95/2019/08/21/Canny-%E8%BE%B9%E7%BC%98%E6%A3%80%E6%B5%8B%E7%AE%97%E6%B3%95.html)\n\n    * [Python+Opencv实现无参数、全自动的Canny算法](https://blog.csdn.net/WZZ18191171661/article/details/89762062)\n    \n    * [使用Pytorch从头实现Canny边缘检测](https://blog.csdn.net/sophia_11/article/details/117004153)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjm12138%2Fcannydetector","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjm12138%2Fcannydetector","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjm12138%2Fcannydetector/lists"}