边缘检测系列1:传统边缘检测算子
本文介绍了图像边缘检测的原理,指出边缘是灰度剧变处,检测基于方向导数掩码卷积。实现了通用边缘检测算子EdgeOP,集成Roberts、Prewitt等多种算子,提供四种边缘强度计算方式,并通过测试函数对比效果,展示了不同算子和计算方法的检测结果。

引入
图像的边缘指的是灰度值发生急剧变化的位置。
免费影视、动漫、音乐、游戏、小说资源长期稳定更新! 👉 点此立即查看 👈
在图像形成过程中,由于亮度、纹理、颜色、阴影等物理因素的不同而导致图像灰度值发生突变,从而形成边缘。
边缘是通过检查每个像素的邻域并对其灰度变化进行量化的,这种灰度变化的量化相当于微积分里连续函数中方向导数或者离散数列的差分。
算法原理
传统的边缘检测大多数是通过基于方向导数掩码(梯度方向导数)求卷积的方法。
计算灰度变化的卷积算子包含Roberts算子、Prewitt算子、Sobel算子、Scharr算子、Kirsch算子、Robinson算子、Laplacian算子。
大多数边缘检测算子是基于方向差分卷积核求卷积的方法,在使用由两个或者多个卷积核组成的边缘检测算子时假设有 n 个卷积核,记 Conv1,Conv2,...,Convn,为图像分别与个卷积核做卷积的结果,通常有四种方式来衡量最后输出的边缘强度。
取对应位置绝对值的和:∑i=1n∣convi∣
取对应位置平方和的开方:∑i=1nconvi2
取对应位置绝对值的最大值:max{∣conv1∣,∣conv2∣,...,∣convi∣}
插值法:∑i=1nai∣convi∣,其中 ai>=0,且 ∑i=1nai=1
代码实现
构建通用的边缘检测算子
因为上述的这些算子在本质上都是通过卷积计算实现的,只是所使用到的卷积核参数有所不同所以可以构建一个通用的计算算子,只需要传入对应的卷积核参数即可实现不同的边缘检测并且在后处理时集成了上述的四种计算最终边缘强度的方式In [1]import numpy as npimport paddleimport paddle.nn as nnclass EdgeOP(nn.Layer): def __init__(self, kernel): ''' kernel: shape(out_channels, in_channels, h, w) ''' super(EdgeOP, self).__init__() out_channels, in_channels, h, w = kernel.shape self.filter = nn.Conv2D(in_channels=in_channels, out_channels=out_channels, kernel_size=(h, w), padding='SAME', bias_attr=False) self.filter.weight.set_value(kernel.astype('float32')) @staticmethod def postprocess(outputs, mode=0, weight=None): ''' Input: NCHW Output: NHW(mode==1-3) or NCHW(mode==4) Params: mode: switch output mode(0-4) weight: weight when mode==3 ''' if mode==0: results = paddle.sum(paddle.abs(outputs), axis=1) elif mode==1: results = paddle.sqrt(paddle.sum(paddle.pow(outputs, 2), axis=1)) elif mode==2: results = paddle.max(paddle.abs(outputs), axis=1) elif mode==3: if weight is None: C = outputs.shape[1] weight = paddle.to_tensor([1/C] * C, dtype='float32') else: weight = paddle.to_tensor(weight, dtype='float32') results = paddle.einsum('nchw, c -> nhw', paddle.abs(outputs), weight) elif mode==4: results = paddle.abs(outputs) return paddle.clip(results, 0, 255).cast('uint8') @paddle.no_grad() def forward(self, images, mode=0, weight=None): outputs = self.filter(images) return self.postprocess(outputs, mode, weight)登录后复制图像边缘检测测试函数
为了方便测试就构建了如下的测试函数,测试同一张图片不同算子/不同边缘强度计算方法的边缘检测效果In [2]import osimport cv2from PIL import Imagedef test_edge_det(kernel, img_path='test.webp'): img = cv2.imread(img_path, 0) img_tensor = paddle.to_tensor(img, dtype='float32')[None, None, ...] op = EdgeOP(kernel) all_results = [] for mode in range(4): results = op(img_tensor, mode=mode) all_results.append(results.numpy()[0]) results = op(img_tensor, mode=4) for result in results.numpy()[0]: all_results.append(result) return all_results, np.concatenate(all_results, 1)登录后复制
Roberts 算子

roberts_kernel = np.array([ [[ [1, 0], [0, -1] ]], [[ [0, -1], [1, 0] ]]])_, concat_res = test_edge_det(roberts_kernel)Image.fromarray(concat_res)登录后复制
登录后复制
Prewitt 算子

prewitt_kernel = np.array([ [[ [-1, -1, -1], [ 0, 0, 0], [ 1, 1, 1] ]], [[ [-1, 0, 1], [-1, 0, 1], [-1, 0, 1] ]], [[ [ 0, 1, 1], [-1, 0, 1], [-1, -1, 0] ]], [[ [ -1, -1, 0], [ -1, 0, 1], [ 0, 1, 1] ]]])_, concat_res = test_edge_det(prewitt_kernel)Image.fromarray(concat_res)登录后复制
登录后复制
Sobel 算子

sobel_kernel = np.array([ [[ [-1, -2, -1], [ 0, 0, 0], [ 1, 2, 1] ]], [[ [-1, 0, 1], [-2, 0, 2], [-1, 0, 1] ]], [[ [ 0, 1, 2], [-1, 0, 1], [-2, -1, 0] ]], [[ [ -2, -1, 0], [ -1, 0, 1], [ 0, 1, 2] ]]])_, concat_res = test_edge_det(sobel_kernel)Image.fromarray(concat_res)登录后复制
登录后复制
Scharr 算子

scharr_kernel = np.array([ [[ [-3, -10, -3], [ 0, 0, 0], [ 3, 10, 3] ]], [[ [-3, 0, 3], [-10, 0, 10], [-3, 0, 3] ]], [[ [ 0, 3, 10], [-3, 0, 3], [-10, -3, 0] ]], [[ [ -10, -3, 0], [ -3, 0, 3], [ 0, 3, 10] ]]])_, concat_res = test_edge_det(scharr_kernel)Image.fromarray(concat_res)登录后复制
登录后复制
Krisch 算子

Krisch_kernel = np.array([ [[ [5, 5, 5], [-3,0,-3], [-3,-3,-3] ]], [[ [-3, 5,5], [-3,0,5], [-3,-3,-3] ]], [[ [-3,-3,5], [-3,0,5], [-3,-3,5] ]], [[ [-3,-3,-3], [-3,0,5], [-3,5,5] ]], [[ [-3, -3, -3], [-3,0,-3], [5,5,5] ]], [[ [-3, -3, -3], [5,0,-3], [5,5,-3] ]], [[ [5, -3, -3], [5,0,-3], [5,-3,-3] ]], [[ [5, 5, -3], [5,0,-3], [-3,-3,-3] ]],])_, concat_res = test_edge_det(Krisch_kernel)Image.fromarray(concat_res)登录后复制
登录后复制
Robinson算子

robinson_kernel = np.array([ [[ [1, 2, 1], [0, 0, 0], [-1, -2, -1] ]], [[ [0, 1, 2], [-1, 0, 1], [-2, -1, 0] ]], [[ [-1, 0, 1], [-2, 0, 2], [-1, 0, 1] ]], [[ [-2, -1, 0], [-1, 0, 1], [0, 1, 2] ]], [[ [-1, -2, -1], [0, 0, 0], [1, 2, 1] ]], [[ [0, -1, -2], [1, 0, -1], [2, 1, 0] ]], [[ [1, 0, -1], [2, 0, -2], [1, 0, -1] ]], [[ [2, 1, 0], [1, 0, -1], [0, -1, -2] ]],])_, concat_res = test_edge_det(robinson_kernel)Image.fromarray(concat_res)登录后复制
登录后复制
Laplacian 算子

laplacian_kernel = np.array([ [[ [1, 1, 1], [1, -8, 1], [1, 1, 1] ]], [[ [0, 1, 0], [1, -4, 1], [0, 1, 0] ]]])_, concat_res = test_edge_det(laplacian_kernel)Image.fromarray(concat_res)登录后复制
登录后复制
总结
简单介绍并实现了几种常用的传统边缘检测算子相关攻略
1 故障现象:OpenClaw无法联网搜索的典型报错 许多开发者在配置OpenClaw AI助手的搜索功能时,常常会遭遇一个典型故障:日常对话交互完全正常,但一旦触发需要联网查询信息的指令,界面便会立刻弹出“抱歉,我目前无法使用网络搜索功能(需要配置 API 密钥)”或“HTTP 401: Inv
1 4 万亿词元!阿里 Qwen3 6-Plus 刷新全球最大 AI 聚合平台 OpenRouter 日调用量纪录 这事儿挺震撼的。就在4月4日,全球最大的AI模型聚合平台OpenRouter在其官方账号上公布了一个爆炸性数字:阿里刚刚发布的千问新模型Qwen3 6-Plus,上线仅仅一天,日调用量
Solidus AI 是什么 在AI与Web3加速融合的当下,一个名为Solidus AI的项目提出了自己的解决方案。它将自己定位为“Web3原生的AI HPC基础设施”,其蓝图相当清晰:以位于欧洲的环保高性能计算(HPC)数据中心为基石,向上构建一个计算与AI工具市场,并最终通过AITECH代币完
Cardano (ADA) 2026年价格预测:AI深度解析与增长路径 在瞬息万变的加密市场,人工智能分析正成为洞察未来趋势的关键工具。近期,由Grok AI模型发布的Cardano(ADA)2026年价格预测引发了广泛关注,其大胆展望ADA或有望触及两位数美元价格。这不仅彰显了AI数据分析的潜力,
京东“全民养虾计划”:开启AI助手体验新纪元 科技领域近期迎来一场别开生面的创新活动:京东正式推出“全民养虾计划”。表面看,它与美食相关,实际上是一场针对AI智能体技术普及的宏大实验。该计划通过“购买AI硬件、赠送专业安装服务与趣味小龙虾”的组合策略,为当前热门的开源AI智能体——OpenClaw,
热门专题
热门推荐
末日生存手游推荐:前往九游开启你的废土冒险之旅 近年来,末日生存题材手游以其独特的沉浸感与生存挑战,持续吸引着大量玩家。在废墟世界中探索资源、应对危机、重建秩序的核心玩法,带来了紧张而富有成就感的游戏体验。如果你正在寻找一款高品质的末日生存手游,九游平台无疑是理想的起点。这里汇集了多款深受好评的末日
《纪念碑谷3》第二关“小镇”超详细图文攻略 《纪念碑谷》系列凭借其独特的视觉艺术与空间谜题设计广受赞誉。最新发布的《纪念碑谷3》在第二章节“小镇”中,将这一美学风格与机关逻辑提升到了新的层次。本章节不仅延续了标志性的极简主义美学,其空间层次感与交互严谨性也更具挑战性。本攻略将为你完整解析《纪念碑谷3
《生存33天》:“沙漠之王”高效通关攻略 在热门生存手游《生存33天》中,玩家面临的挑战远不止于无尽的丧尸潮。游戏深度结合了生存资源管理与高难度首领战策略,其中“沙漠之王”堪称游戏中期最具考验的BOSS。它不仅是实力分水岭,击败后更能获得稀有材料、限定头衔及海量经验金币,大幅推动队伍成长。本文将深入
《生存33天》“四只手”首领完全通关攻略 你是否在“四只手”首领关卡止步不前?不必焦虑,这个Boss在《生存33天》中素有“新秀杀手”之称。初次遭遇时,其独特的机制与高额伤害往往让玩家措手不及,不少冒险者在此耗费了数日时光。然而,只要掌握了它的核心规律,你就会发现这个敌人不过是外强中干。以下这份详尽
《剑与远征:启程》前排坦克英雄赫普深度解析:双形态切换机制与实战搭配指南 在《剑与远征:启程》这款策略放置手游中,组建一支攻守兼备的队伍至关重要,而前排坦克英雄的选择往往是决定胜败的关键。今天,我们将聚焦于蛮血部族的一位特色英雄——赫普。作为一名超稀有品质的坦克,赫普不仅具备坚实的防御力,更凭借独特





