Python图像处理丨认识图像锐化和边缘提取的4个算子
摘要:图像锐化和边缘提取技术可以消除图像中的噪声,提取图像信息中用来表征图像的一些变量,为图像识别提供基础。
本文分享自华为云社区《[Python图像处理] 十七.图像锐化与边缘检测之Roberts算子、Prewitt算子、Sobel算子和Laplacian算》,作者: eastmount 。
由于收集图像数据的器件或传输数图像的通道的存在一些质量缺陷,文物图像时间久远,或者受一些其他外界因素、动态不稳定抓取图像的影响,使得图像存在模糊和有噪声的情况,从而影响到图像识别工作的开展。这时需要开展图像锐化和边缘检测处理,加强原图像的高频部分,锐化突出图像的边缘细节,改善图像的对比度,使模糊的图像变得更清晰。
图像锐化和边缘提取技术可以消除图像中的噪声,提取图像信息中用来表征图像的一些变量,为图像识别提供基础。通常使用灰度差分法对图像的边缘、轮廓进行处理,将其凸显。本文分别采用Laplacian算子、Robert算子、Prewitt算子和Sobel算子进行图像锐化边缘处理实验。本文主要讲解灰度线性变换,基础性知识希望对您有所帮助。
该系列在github所有源代码:https://github.com/eastmountyxz/ImageProcessing-Python
一.Roberts算子
Roberts算子又称为交叉微分算法,它是基于交叉差分的梯度算法,通过局部差分计算检测边缘线条。常用来处理具有陡峭的低噪声图像,当图像边缘接近于正45度或负45度时,该算法处理效果更理想。其缺点是对边缘的定位不太准确,提取的边缘线条较粗。
Roberts算子的模板分为水平方向和垂直方向,如公式(11.7)所示,从其模板可以看出,Roberts算子能较好的增强正负45度的图像边缘。
详细计算公式如下所示:(PS-下图参考自己的书和论文)
在Python中,Roberts算子主要通过Numpy定义模板,再调用OpenCV的filter2D()函数实现边缘提取。该函数主要是利用内核实现对图像的卷积运算,其函数原型如下所示:
dst = filter2D(src, ddepth, kernel[, dst[, anchor[, delta[, borderType]]]])
- src表示输入图像
- dst表示输出的边缘图,其大小和通道数与输入图像相同
- ddepth表示目标图像所需的深度
- kernel表示卷积核,一个单通道浮点型矩阵
- anchor表示内核的基准点,其默认值为(-1,-1),位于中心位置
- delta表示在储存目标图像前可选的添加到像素的值,默认值为0
- borderType表示边框模式
Python实现代码如下所示:
# -*- coding: utf-8 -*- import cv2 import numpy as np import matplotlib.pyplot as plt #读取图像 img = cv2.imread("lena.png") lenna_img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB) #灰度化处理图像 grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #Roberts算子 kernelx = np.array([[-1,0],[0,1]], dtype=int) kernely = np.array([[0,-1],[1,0]], dtype=int) x = cv2.filter2D(grayImage, cv2.CV_16S, kernelx) y = cv2.filter2D(grayImage, cv2.CV_16S, kernely) #转uint8 absX = cv2.convertScaleAbs(x) absY = cv2.convertScaleAbs(y) Roberts = cv2.addWeighted(absX,0.5,absY,0.5,0) #用来正常显示中文标签 plt.rcParams["font.sans-serif"]=["SimHei"] #显示图形 titles = [u"原始图像", u"Roberts算子"] images = [lenna_img, Roberts] for i in xrange(2): plt.subplot(1,2,i+1), plt.imshow(images[i], "gray") plt.title(titles[i]) plt.xticks([]),plt.yticks([]) plt.show()