石材网站模板wordpress自定义搜索页面
- 作者: 五速梦信息网
- 时间: 2026年03月21日 08:47
当前位置: 首页 > news >正文
石材网站模板,wordpress自定义搜索页面,除了阿里巴巴还有什么网站做外贸的,wordpress数据库表分析边缘检测一阶Roberts Cross 罗伯茨交叉算子Sobel 索贝尔算子Prewitt 普利维特算子Canny 算子Kirsch 算子 二阶Laplacian 拉普拉斯算子LoG 高斯拉普拉斯算子DoG 高斯函数差分 边缘检测 目的#xff1a;找到图像中亮度变化剧烈的像素点构成的集合#xff0c;即表现出来往往是图… 边缘检测一阶Roberts Cross 罗伯茨交叉算子Sobel 索贝尔算子Prewitt 普利维特算子Canny 算子Kirsch 算子 二阶Laplacian 拉普拉斯算子LoG 高斯拉普拉斯算子DoG 高斯函数差分 边缘检测 目的找到图像中亮度变化剧烈的像素点构成的集合即表现出来往往是图像的轮廓即边缘。 传统边缘检测的步骤①滤波去除噪声②增强边缘的特征③提取边缘完成检测。 类别常见算子一阶Roberts Cross算子Prewitt算子Sobel算子Canny算子罗盘算子krisch算子二阶Laplacian算子LoGDoGMarr-Hildreth在梯度方向的二阶导数过零点。 一阶 Roberts Cross 罗伯茨交叉算子 Roberts算子是一种斜向偏差分的梯度计算方法梯度的大小代表边缘的强度梯度的方向与边缘的走向垂直。它是2X2算子模板。2个卷积核形成了Roberts算子。图象中的每一个点都用这2个核做卷积。更详细计算过程查看 博主苏源流 优点计算简单边缘定位较准但对噪声极敏感。适用于边缘明显且噪声较少的图像分割。 Reboerts算子是一种利用局部差分来寻找边缘采用对角方向相邻两像素值之差算子计算形式如下 G x f ( i , j ) − f ( i − 1 , j − 1 ) G y f ( i − 1 , j ) − f ( i , j − 1 ) Gx f(i,j) - f(i-1,j-1) Gy f(i-1,j) - f(i,j-1) Gxf(i,j)−f(i−1,j−1)Gyf(i−1,j)−f(i,j−1) ∣ G ( x , y ) ∣ s p r t ( G x 2 − G y 2 ) |G(x,y)| sprt(Gx^2-Gy^2) ∣G(x,y)∣sprt(Gx2−Gy2) 即 G ( x , y ) a b s ( f ( x , y ) − f ( x 1 , y 1 ) ) a b s ( f ( x , y 1 ) − f ( x 1 , y ) ) 即 G(x,y)abs(f(x,y)-f(x1,y1))abs(f(x,y1)-f(x1,y)) 即G(x,y)abs(f(x,y)−f(x1,y1))abs(f(x,y1)−f(x1,y))
python
边缘检测 Robertes cross算子[[-1,-1],[1,1]] 图像增强锐化
一种斜向偏差分的梯度计算梯度的大小代表边缘的强度梯度的方向与边缘的走向垂直
Zivid 2021/8/16
import cv2 import numpy as np from skimage import filters# 方法一自定义 def Robert01(pic):pic_f np.copy(pic)pic_f pic_f.astype(float)Roberts np.zeros((row, column))for x in range(row - 1):for y in range(column - 1):gx abs(pic_f[x 1, y 1] - pic_f[x, y])gy abs(pic_f[x 1, y] - pic_f[x, y 1])Roberts[x, y] gx gysharp pic_f Robertssharp np.where(sharp 0, 0, np.where(sharp 0, 0, np.where(sharp 255, 255, sharp))sharp sharp.astype(uint8)return sharp# 方法二自定义 这个比较好 ↓ def Robert02(pic):ro [[-1, -1], [1, 1]]for i in range(row):for j in range(column):if(j2column) and (i2row):process_img pic[i:i2, j:j2]list_robert ro * process_imgpic[i,j] abs(list_robert.sum())return pic# 方法三自定义 def Robert03(pic):x_kernel np.array([[-1,0],[0,1]], dtypeint)y_kernel np.array([[0,-1],[1,0]], dtypeint)x cv2.filter2D(pic, cv2.CV_16S, x_kernel)y cv2.filter2D(pic, cv2.CV_16S, y_kernel)absX cv2.convertScaleAbs(x)absY cv2.convertScaleAbs(y)Prewitt cv2.addWeighted(absX, 0.5, absY, 0.5, 0)return Prewitt# 方法四 直接调用 skimage库内的函数 def sys_robret(pic):edge_pic filters.roberts(pic)return edge_pic):edge_pic filters.roberts(pic)return edge_picif name main:pic cv2.imread(H:\Zivid\pho\e.jpg, 0)row, column pic.shapecv2.imshow(original, pic)img01 Robert01(pic)cv2.imshow(Robertd-01, img01)img02 Robert02(pic)cv2.imshow(Roborts-02, img02)img03 Robert03(pic)cv2.imshow(Roborts-03, img03)img04 sys_robret(pic)cv2.imshow(Roborts-04, img04)cv2.waitKey(0) Sobel 索贝尔算子 Sobel算子根据像素点上下、左右邻点灰度加权差在边缘处达到极值这一现象检测边缘。它结合高斯平滑和微分求导用来计算图像灰度函数的近似梯度。在图像的任何一点使用此算子将会产生对应的梯度矢量或是其法矢量。 它对噪声具有平滑作用提供较为精确的边缘方向信息边缘定位精度不够高。当对精度要求不是很高时是一种较为常用的边缘检测方法。 Sobel算子实现水平边缘检测、垂直边缘检测45度、135度角边缘检测。 算法步骤 该算子包含两组3x3的矩阵分别为横向及纵向将之与图像作平面卷积即可分别得出横向及纵向的亮度差分近似值。如果以A代表原始图像Gx及Gy分别代表经横向及纵向边缘检测的图像灰度值其公式如下 图像的每一个像素的横向及纵向灰度值通过以下公式结合来计算该点灰度的大小 通常为了提高效率 使用不开平方的近似值 如果梯度G大于某一阀值 则认为该点(x,y)为边缘点。然后可用以下公式计算梯度方向 Sobel算子根据像素点上下、左右邻点灰度加权差在边缘处达到极值这一现象检测边缘。对噪声具有平滑作用提供较为精确的边缘方向信息边缘定位精度不够高。当对精度要求不是很高时是一种较为常用的边缘检测方法。 # python
边缘检测 Sober索贝尔算子
对噪声具有平滑作用提供较为精确的边缘方向信息边缘定位精度不够高。
Zivid 2021/8/16import cv2
import numpy as np from skimage import filters# 方法一 自定义 def def_sober(gray_img):# 算子x_sobel np.array([[-1, 0, 1],[-2, 0, 2],[-1, 0, 1]])y_sobel np.array([[-1, -2, -1],[0, 0, 0],[1, 2, 1]])h, w gray_img.shapeimg np.zeros([h 2, w 2], np.uint8)img[2:h 2, 2:w 2] gray_img[0:h, 0:w]x_edge_img cv2.filter2D(img, -1, x_sobel)y_edge_img cv2.filter2D(img, -1, y_sobel)edge_img np.zeros([h, w])for i in range(h):for j in range(w):edge_img[i][j] np.sqrt(x_edge_img[i][j] ** 2 y_edge_img[i][j] ** 2) / (np.sqrt(2))return edge_img# 方法二 系统自带opencv def cv2_sober(img):# 算子gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 灰度化sobel_x cv2.Sobel(gray, cv2.CV_8U, 1, 0) # 通过控制dx,dy的值来控制梯度的方向这里是求x方向的梯度sobel_y cv2.Sobel(gray, cv2.CV_8U, 0, 1) # 这里是求y方向的梯度sobel cv2.Sobel(gray, cv2.CV_8U, 1, 1) # 这里是求x,y方向综合的梯度return [sobel_x, sobel_y, sobel]# 方法三 直接调用系统自带 skimage库内的函数 def skimage_sobel(img):edge_pic filters.sobel(img)return edge_picif name main:# 读取图像img cv2.imread(H:\Zivid\pho\gray1.jpg, cv2.COLOR_BGR2GRAY)rgb_img cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 先转化成RGB# 灰度化处理图像grayImage cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)cv2.imshow(original, grayImage)pic1 def_sober(grayImage)cv2.imshow(def_sober, pic1)pic2 skimage_sobel(grayImage)cv2.imshow(skimage_sobel, pic2)sobel_x,sobel_y,sobel cv2_sober(img)cv2.imshow(cv2_Sobel_x, sobel_x)cv2.imshow(cv2_Sobel_y, sobel_y)cv2.imshow(cv2_Sobel, sobel)cv2.waitKey(0)Prewitt 普利维特算子 Prewitt算子的计算步骤如sober算子将方向的差分运算和局部平均相结合的方法也是取水平和垂直两个卷积核来分别对图像中各个像素点做卷积运算所不同的是Sobel 算子是先做加权平均然后再微分Prewitt 算子是先平均后求微分。 Prewitt 算子通过对图像上的每个像素点的八方向邻域的灰度加权差之和来进行检测边缘对噪声有一定抑制作用抗噪性较好但由于采用了局部灰度平均容易检测出伪边缘且边缘定位精度较低。 # python
边缘检测 Prewitt普利维特算子
利用像素点上下、左右邻点灰度差在边缘处达到极值检测边缘。对噪声具有平滑作用
Zivid 2021/8/16
import cv2 import numpy as np from skimage import filters# 方法一 自定义 def prewitt01(pic):# 算子x_kernel np.array([[1, 1, 1], [0, 0, 0], [-1, -1, -1]], dtypeint)y_kernel np.array([[-1, 0, 1], [-1, 0, 1], [-1, 0, 1]], dtypeint)x cv2.filter2D(pic, cv2.CV_16S, x_kernel)y cv2.filter2D(pic, cv2.CV_16S, y_kernel)absX cv2.convertScaleAbs(x)absY cv2.convertScaleAbs(y)Prewitt1 cv2.addWeighted(absX, 0.5, absY, 0.5, 0)return Prewitt1# 方法二 直接调用系统自带 skimage库内的函数 def sys_prewitt(pic):edge_img filters.prewitt(pic)return edge_imgif name main:# 读取图像img cv2.imread(H:\Zivid\pho\gray1.jpg, cv2.COLOR_BGR2GRAY)rgb_img cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 先转化成RGB# 灰度化处理图像grayImage cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)cv2.imshow(original, grayImage)pic1 prewitt01(grayImage)cv2.imshow(Prewitt01, pic1)pic2 sys_prewitt(grayImage)cv2.imshow(Prewitt02, pic2)cv2.waitKey(0) Canny 算子 Canny 边缘检测算法是被业界公认的性能最为优良的边缘检测算法之一。 优点结合了高斯平滑和微分求导用来计算图像灰度函数的近似梯度 缺点: 1为了得到较好的边缘检测结果它通常需要使用较大的滤波尺度这样容易丢失一些细节 2Canny算子的双阈值要人为的选取不能够自适应 算法步骤图片来自作者 拾牙慧者更详细可见作者 有点方 # python
边缘检测 Canny算法
步骤
1灰度化(通常灰度化采用的公式是:Gray0.299R0.587G0.114B;)
2高斯滤波
3计算图像的梯度和梯度方向(本文使用Sobel算子)
4非极大值抑制(上一步得到的边缘较粗这里会细化边缘)
5双阈值筛选边缘(二值化显示)
Zivid 2021/8/18import cv2
import numpy as np
from skimage import filters# 方法一 自定义
def def_canny(img, top1, buttom1, left1, right1):# prewitt算子。可采用不同的算子如soberprewittm1 np.array([[-1, 0, 1], [-1, 0, 1], [-1, 0, 1]])m2 np.array([[-1, -1, -1], [0, 0, 0], [1, 1, 1]])# 第一步 完成高斯平滑img cv2.GaussianBlur(img, (3, 3), 2) # 高斯滤波# 第二步 一阶差分极端没一点的梯度幅值和方向img1 np.zeros(img.shape, dtypeuint8) # 与原图大小相同的图片用于存放梯度值theta np.zeros(img.shape, dtypefloat) # 方向矩阵与原图像大小相同存放梯度方向img cv2.copyMakeBorder(img, top, buttom, left, right, borderTypecv2.BORDER_CONSTANT, value0)# ↑ 表示增加的像素值类似补零操作这里的上下左右都增加了一行补充方式问问诶cv2.BORDER_REPLICATErows, cols img.shape# 卷积操作以核与图像的卷积代替核之间对应的那个值for i in range(1, rows - 1):for j in range(1, cols - 1):# Gy, Gx相乘再相加Gy (np.dot(np.array([1, 1, 1]), (m1 * img[i - 1:i 2, j - 1:j 2]))).dot(np.array([[1], [1], [1]]))Gx (np.dot(np.array([1, 1, 1]), (m2 * img[i - 1:i 2, j - 1:j 2]))).dot(np.array([[1], [1], [1]]))# 将所有的角度转换到-180到180之间if Gx[0] 0:theta[i - 1, j - 1] 90continueelse:# 求梯度方向temp (np.arctan(Gy[0] / Gx[0])) * 180 / np.piif Gx[0] * Gy[0] 0:if Gx[0] 0:theta[i - 1, j - 1] np.abs(temp)else:thetai - 1, j - 1if Gx[0] * Gy[0] 0:if Gx[0] 0:theta[i - 1, j - 1] -1 * np.abs(temp)else:thetai - 1, j - 1img1i - 1, j - 1# 对梯度方向进行划分将梯度全部划分为0 90 45 -45四个方向for i in range(1, rows - 2):for j in range(1, cols - 2):if (((theta[i, j] -22.5) and (theta[i, j] 22.5)) or((theta[i, j] 157.5) and (theta[i, j] 180)) or((theta[i, j] -157.5) and (theta[i, j] -180))):theta[i, j] 0.0elif (((theta[i, j] 22.5) and (theta[i, j] 67.5)) or((theta[i, j] -112.5) and (theta[i, j] -157.5))):theta[i, j] 45.0elif (((theta[i, j] 67.5) and (theta[i, j] 112.5)) or((theta[i, j] -67.5) and (theta[i, j] -112.5))):theta[i, j] 90.0elif (((theta[i, j] 122.5) and (theta[i, j] 157.5)) or((theta[i, j] -22.5) and (theta[i, j] -67.5))):theta[i, j] -45.0# 第三步 进行非极大值抑制计算# 寻找极值点像素点的值是与该像素点的方向垂直方向上相邻三个像素最大的则该像素点定义为机制即边缘像素img2 np.zeros(img1.shape)for i in range(1, img2.shape[0] - 1):for j in range(1, img2.shape[1] - 1):if (theta[i, j] 0.0) and (img1[i, j] np.max([img1[i, j], img1[i 1, j], img1[i - 1, j]])):img2[i, j] img1[i, j]if (theta[i, j] -45.0) and (img1[i, j] np.max([img1[i, j], img1[i - 1, j - 1], img1[i 1, j 1]])):img2[i, j] img1[i, j]if (theta[i, j] 90.0) and (img1[i, j] np.max([img1[i, j], img1[i, j 1], img1[i, j - 1]])):img2[i, j] img1[i, j]if (theta[i, j] 45.0) and (img1[i, j] np.max([img1[i, j], img1[i - 1, j 1], img1[i 1, j - 1]])):img2[i, j] img1[i, j]# 第四步 双阈值检测和边缘链接img3 np.zeros(img2.shape) # 定义双阈值图像TL 50TH 100# 小于低阈值的设为0大于高阈值的设为255for i in range(1, img3.shape[0] - 1):for j in range(1, img3.shape[1] - 1):# 将明确的灰度值的像素点绘制if img2[i, j] TL:img3[i, j] 0elif img2[i, j] TH:img3[i, j] 255# 如果一个像素点的值在二者之间且这个像素的临近八个像素点有一个像素值是小于高阈值则为255# 将剩余像素点都设置为255实现边缘链接elif ((img2[i 1, j] TH) or (img2[i - 1, j] TH) or (img2[i, j 1] TH) or(img2[i, j - 1] TH) or (img2[i - 1, j - 1] TH) or (img2[i - 1, j 1] TH) or(img2[i 1, j 1] TH) or (img2[i 1, j - 1] TH)):img3[i, j] 255return [img1, img2, img3, theta]# 方法2 opencv自带函数 def cv_canny(img):img cv2.GaussianBlur(img, (3, 3), 2)edge_img cv2.Canny(img, 50, 100)return edge_imgif name main:img cv2.imread(H:\Zivid\pho\ground.jpg, 0) # 彩色变成灰白img1, img2, img3, theta def_canny(img)img_cv cv_canny(img)cv2.imshow(original, img)cv2.imshow(img1, img1)cv2.imshow(img2, img2)cv2.imshow(img3, img3)cv2.imshow(theta, theta)cv2.imshow(opencv, img_cv)cv2.waitKey(0)Kirsch 算子 Kirsch 算子是一种 3×3 的非线性方向算子。其基本思想是希望改进取平均值的过程从而尽量使边缘两侧的像素各自与自己同类的像素取平均值然后再求平均值之差来减小由于取平均值所造成的边缘细节丢失。通常采用八方向 Kirsch 模板的方法进行检测取其中最大的值作为边缘强度而将与之对应的方向作为边缘方向。常用的八方向 Kirsch 模板如下所示详细可见博主 飘云之下 对每个像素点都用 这8个模板进行进行卷积注意每个卷积值都应取绝对值在利用 max{ temp0,temp1,temp2,temp3,temp4,temp5,temp6,temp7} 求出该点的最大卷积值。
转自 博主 [飘云之下]
import cv2 import numpy as np from matplotlib import pyplot as plt #计算Kirsch 边沿检测算子#定义Kirsch 卷积模板 m1 np.array([[5, 5, 5],[-3, 0, -3],[-3, -3, -3]]) m2 np.array([[-3, 5, 5],[-3, 0, 5],[-3, -3, -3]]) m3 np.array([[-3, -3, 5],[-3, 0, 5],[-3, -3, 5]]) m4 np.array([[-3, -3, -3],[-3, 0, 5],[-3, 5, 5]]) m5 np.array([[-3, -3, -3],[-3, 0, -3],[5, 5, 5]]) m6 np.array([[-3, -3, -3],[5, 0, -3],[5, 5, -3]]) m7 np.array([[5, -3, -3],[5, 0, -3],[5, -3, -3]]) m8 np.array([[5, 5, -3],[5, 0, -3],[-3, -3, -3]]) img cv2.imread(H:\Zivid\pho\gray1.jpg,0)
img cv2.GaussianBlur(img,(3,3),5)
#周围填充一圈 #卷积时必须在原图周围填充一个像素 img cv2.copyMakeBorder(img,1,1,1,1,borderTypecv2.BORDER_REPLICATE temp list(range(8)) img1 np.zeros(img.shape) #复制空间 此处必须的重新复制一块和原图像矩阵一样大小的矩阵以保存计算后的结果 for i in range(1,img.shape[0]-1):for j in range(1,img.shape[1]-1):temp[0] np.abs( ( np.dot( np.array([1,1,1]) , ( m1*img[i-1:i2,j-1:j2]) ) ).dot(np.array([[1],[1],[1]])) )#利用矩阵的二次型表达可以计算出矩阵的各个元素之和temp[1] np.abs((np.dot(np.array([1, 1, 1]), (m2 * img[i - 1:i 2, j - 1:j 2]))).dot(np.array([[1],[1],[1]])) )temp[2] np.abs( ( np.dot( np.array([1,1,1]) , ( m1*img[i-1:i2,j-1:j2]) ) ).dot(np.array([[1],[1],[1]])) )temp[3] np.abs((np.dot(np.array([1, 1, 1]), (m3 * img[i - 1:i 2, j - 1:j 2]))).dot(np.array([[1],[1],[1]])) )temp[4] np.abs((np.dot(np.array([1, 1, 1]), (m4 * img[i - 1:i 2, j - 1:j 2]))).dot(np.array([[1],[1],[1]])) )temp[5] np.abs((np.dot(np.array([1, 1, 1]), (m5 * img[i - 1:i 2, j - 1:j 2]))).dot(np.array([[1],[1],[1]])) )temp[6] np.abs((np.dot(np.array([1, 1, 1]), (m6 * img[i - 1:i 2, j - 1:j 2]))).dot(np.array([[1],[1],[1]])) )temp[7] np.abs((np.dot(np.array([1, 1, 1]), (m7 * img[i - 1:i 2, j - 1:j 2]))).dot(np.array([[1],[1],[1]])) )img1[i,j] np.max(temp)if img1[i, j] 255: #此处的阈值一般写255根据实际情况选择0~255之间的值img1[i, j] 255else:img1[i, j] 0 cv2.imshow(1,img1) print(img.shape) cv2.waitKey(0)二阶 Laplacian 拉普拉斯算子 拉普拉斯算子是 n 维欧几里德空间中的一个二阶微分算子常用于图像增强领域和边缘提取。它通过灰度差分计算邻域内的像素查看中间值与周围像素值的差别如果相差大则判断为边界。 它不依赖于边缘方向的二阶微分算子对图像中的阶跃型边缘点定位准确该算子对噪声非常敏感它使噪声成分得到加强这两个特性使得该算子容易丢失一部分边缘的方向信息造成一些不连续的检测边缘同时抗噪声能力比较差由于其算法可能会出现双像素边界常用来判断边缘像素位于图像的明区或暗区。算法详细可见博主 yanghan742915081
边缘检测 二阶微分算子 laplacian算法
它通过灰度差分计算邻域内的像素。
1判断图像中心像素灰度值与它周围其他像素的灰度值如果中心像素的灰度更高
则提升中心像素的灰度反之降低中心像素的灰度从而实现图像锐化操作
2在算法实现过程中Laplacian算子通过对邻域中心像素的四方向或八方向求梯度
再将梯度相加起来判断中心像素灰度与邻域内其他像素灰度的关系
3最后通过梯度运算的结果对像素灰度进行调整。
Zivid 2021/8/18
import cv2 import numpy as np# 方法1 自定义函数 def def_laplacian(img):rows, cols img.shapeimage1 np.zeros(img.shape, dtypeuint8)image2 image1lap4_filter np.array([[0,-1,0],[-1,4,-1],[0,-1,0]])for i in range(rows -2):for j in range(cols -2):image1[i 1, j 1] abs(np.sum(img[i:i 3, j:j 3] * lap4_filter))if image1[i,j] 0:lap8_filter np.array([[-1, -1, -1],[-1, 8, -1],[-1, -1, -1]])for i in range(rows -2):for j in range(cols -2):image2[i 1, j 1] abs(np.sum(img[i:i 3, j:j 3] * lap8_filter))if image2[i,j] 0:image2[i,j] 0image1 cv2.convertScaleAbs(image1)image2 cv2.convertScaleAbs(image2)return image1, image2# 方法2 opencv系统函数 def cv_laplacian(img):lap cv2.Laplacian(img, cv2.CV_16S, ksize3) # 算子的大小必须为1、3、5、7laplacian cv2.convertScaleAbs(lap) # 转回uint8return laplacianif name main:img cv2.imread(H:\Zivid\pho\gray1.jpg,0) # 彩色变成灰白img1, img2 def_laplacian(img)lap cv_laplacian(img)cv2.imshow(original, img)cv2.imshow(4阶, img1)cv2.imshow(8阶, img2)cv2.imshow(laplacian, lap)cv2.waitKey(0) 当Laplace算子输出出现过零点时就表明有边缘存在其中忽略无意义的过零点(均匀零区)。原则上过零点的位置精度可以通过线性内插方法精确到子像素分辨率。 而拉普拉斯算子在图像边缘检测中并不常用主要原因有 任何包含有二阶导数的算子比只包含有一阶导数的算子更易受噪声的影响一阶导数很小的局部峰值也能导致二阶导数过零点所以Laplace算子对噪声具有无法接受的敏感性Laplace算子的幅值产生双边元这是复杂的分割不希望有结果;Laplace算子不能检测边缘的方向。为了避免噪声的影响必须采用特别有效的滤波方法。 所以人们提出了改进的LOG算子来处理Laplace不能处理的离散点和噪声。 LoG 高斯拉普拉斯算子 高斯拉普拉斯算子Lapacian of gaussian先对图像进行高斯平滑滤波处理然后再与Laplacian算子进行卷积。其处理过程灰度-高斯-拉普拉斯-负值为0。 更详细的计算过程请查看博主 ingy 或 dreamguard 【很详细】 滤波器的选择要考虑以下两个因素其一是滤波器在空间上要求平稳即要求空间位置误差 Δ x要小其二是平滑滤波器本身要求是带通滤波器并且在有限的带通内是平稳的即要求频域误差 Δω 要小。 根据信号处理中的测不准原理 Δx 和 Δ ω是相互矛盾的而达到测不准下限的滤波器就是高斯滤波器。Marr 和 Hildreth 提出的这种差分算子是各向同性的拉普拉斯二阶差分算子。 算法步骤 Laplace算子通过对图像求取二阶导数的零交叉点(zero-cross)来进行边缘检测其计算公式如下 ∇ 2 f ( x , y ) ∂ 2 f ∂ x 2 ∂ 2 f ∂ y 2 ∇^2f(x,y) \frac{∂^2f}{∂x^2}\frac{∂^2f}{∂y^2} ∇2f(x,y)∂x2∂2f∂y2∂2f 由于微分运算对噪声比较敏感可以先对图像进行高斯平滑滤波再使用Laplace算子进行边缘检测以降低噪声的影响。由此便形成了用于极值点检测的LoG算子。常用的二维高斯函数如下 G σ ( x , y ) 1 2 π σ 2 e x p ( − x 2 y 2 2 σ 2 ) G_σ(x,y)\frac{1}{\sqrt{2πσ^2}}exp(−\frac{x^2y^2}{2σ^2}) Gσ(x,y)2πσ2 1exp(−2σ2x2y2) 原图像与高斯核函数卷积后再做laplace运算 Δ [ G σ ( x , y ) ∗ f ( x , y ) ] [ Δ G σ ( x , y ) ] ∗ f ( x , y ) Δ[Gσ(x,y)∗f(x,y)][ΔGσ(x,y)]∗f(x,y) Δ[Gσ(x,y)∗f(x,y)][ΔGσ(x,y)]∗f(x,y) L o G Δ G σ ( x , y ) ∂ 2 G σ ( x , y ) ∂ x 2 ∂ 2 G σ ( x , y ) ∂ y 2 x 2 y 2 − 2 σ 2 σ 4 e − ( x 2 y 2 ) / 2 σ 2 LoGΔGσ(x,y)\frac{∂^2Gσ(x,y)}{∂x^2}\frac{∂^2Gσ(x,y)}{∂y^2}\frac{x^2y^2−2σ^2}{σ^4} e^{−(x^2y^2)/2σ^2} LoGΔGσ(x,y)∂x2∂2Gσ(x,y)∂y2∂2Gσ(x,y)σ4x2y2−2σ2e−(x2y2)/2σ2 该边缘检测器的基本特征是 1 所用的平滑滤波器是高斯滤波器 2 增强步骤采用的是二阶导数即二维拉普拉斯函数 3 边缘检测的判据是二阶导数过零点并且对应一阶导数的极大值 该方法的特点是先用高斯滤波器与图像进行卷积既平滑了图像又降低了噪声使孤立的噪声点和较小的结构组织被滤除。然而由于对图像的平滑会导致边缘的延展因此只考虑那些具有局部梯度极大值的点作为边缘点这可以用二阶导数的零交叉来实现。
python
边缘检测 二阶微分算子 LoG算法
先对图像进行高斯平滑处理然后再与Laplacian算子进行卷积
Zivid 2021/8/18
import cv2 import numpy as npdef def_log(img):rows, cols img.shape# 第一步高斯滤波gau_filter np.array([[0, 0, 1, 0, 0],[0, 1, 2, 1, 0],[1, 2, -16, 2, 1],[0, 1, 2, 1, 0],[0, 0, 1, 0, 0]])# gau_filter np.array([[1,2,1],# [2,4,2],# [1,2,1]])ex_pad1 np.pad(img, ((2, 2), (2, 2)), constant) # 扩展操作# 逐个像素进行高斯滤波操作for i in range(rows - 4):for j in range(cols - 4):ex_pad1[i, j] np.sum(ex_pad1[i:i 5, j:j 5] * gau_filter)# 第二步计算laplacian的二阶导数# 四邻域lap4_filter np.array([[0, -1, 0],[-1, 4, -1],[0, -1, 0]])lap4_pad np.pad(ex_pad1, ((1, 1), (1, 1)), constant)image1 np.zeros(img.shape, dtypeuint8)for i in range(rows - 2):for j in range(cols - 2):image1[i, j] np.sum(lap4_pad[i:i 3, j:j 3] * lap4_filter)if image1[i, j] 0:image1[i, j] 0# 八邻域lap8_filter np.array([[-1, -1, -1],[-1, 8, -1],[-1, -1, -1]])lap8_pad np.pad(ex_pad1, ((1, 1), (1, 1)), constant)image2 np.zeros(img.shape, dtypeuint8)for i in range(1, rows - 1):for j in range(1, cols - 1):image2[i, j] np.sum(lap8_pad[i - 1:i 2, j - 1:j 2] * lap8_filter)if image2[i, j] 0:image2[i, j] 0return ex_pad1, image1, image2def sys_log(img):# 以核为3*3方差为0的高斯函数进行高斯滤波image1 cv2.GaussianBlur(img, (3, 3), sigmaX0)sys_img cv2.Laplacian(image1, cv2.CV_16S, ksize3)sys_img cv2.convertScaleAbs(sys_img)return sys_imgif name main:img cv2.imread(H:\Zivid\pho\gray1.jpg, 0) # 彩色变成灰白gau, img1, img2 def_log(img)lap syslog(img)cv2.imshow(original, img)cv2.imshow(gause, gau)cv2.imshow(4阶, img1)cv2.imshow(8阶, img2)cv2.imshow(laplacian of gaussian, lap)cv2.waitKey(0) DoG 高斯函数差分 Difference of Gaussian(DOG)是高斯函数的差分。它是可以通过将图像与高斯函数进行卷积得到一幅图像的低通滤波结果即去噪过程这里的Gaussian和高斯低通滤波器的高斯一样是一个函数即为正态分布函数。同时它对高斯拉普拉斯LoG的近似在某一尺度上的特征检测可以通过对两个相邻高斯尺度空间的图像相减得到DoG的响应值图像。 常见的二维高斯函数公式为 G σ 1 ( x , y ) 1 2 π σ 1 2 e x p ( − x 2 y 2 2 σ 1 2 ) G{σ1}(x,y)\frac{1}{\sqrt{2πσ_1^2}}exp(−\frac{x^2y^2}{2σ_1^2}) Gσ1(x,y)2πσ12 1exp(−2σ12x2y2) 其次两幅图像的高斯滤波表示为 Δ g 1 ( x , y ) G σ 1 ( x , y ) ∗ f ( x , y ) Δ g 2 ( x , y ) G σ 2 ( x , y ) ∗ f ( x , y ) Δg_1(x,y)Gσ_1(x,y)∗f(x,y) Δg_2(x,y)Gσ_2(x,y)∗f(x,y) Δg1(x,y)Gσ1(x,y)∗f(x,y)Δg2(x,y)Gσ2(x,y)∗f(x,y) 最后将滤波得到的两幅图g1和g2相减得到 Δ g 1 ( x , y ) − Δ g 2 ( x , y ) G σ 1 ( x , y ) ∗ f ( x , y ) − G σ 2 ( x , y ) ∗ f ( x , y ) ( G σ 1 − G σ 2 ) ∗ f ( x , y ) D o G ∗ f ( x , y ) Δg_1(x,y)-Δg_2(x,y)Gσ_1(x,y)∗f(x,y)-Gσ_2(x,y)∗f(x,y)(Gσ_1-Gσ2)*f(x,y)DoG*f(x,y) Δg1(x,y)−Δg2(x,y)Gσ1(x,y)∗f(x,y)−Gσ2(x,y)∗f(x,y)(Gσ1−Gσ2)∗f(x,y)DoG∗f(x,y) 则由上式得到 D o G G σ 1 − G σ 2 1 2 π ( 1 σ 1 e − ( x 2 y 2 ) / 2 σ 1 2 − 1 σ 2 e − ( x 2 y 2 ) / 2 σ 2 2 ) DoG G{σ1}-G_{σ2}\frac{1}{\sqrt{2π}}(\frac{1}{σ_1}e^{-(x^2y^2)/2σ_1^2}-\frac{1}{σ_2}e^{-(x^2y^2)/2σ_2^2}) DoGGσ1−Gσ22π 1(σ11e−(x2y2)/2σ12−σ21e−(x2y2)/2σ22) DoG和LoG对比
python
边缘检测 二阶微分算子 dog算法
确定σ值来对一幅图像进行滤波所得零交叉边缘图与仅为全部图形保留的公共边缘相结合
Zivid 2021/8/18from skimage import filters
import cv2 import matplotlib.pyplot as plt# 方法:采用cv或skimage库自带高斯函数 def sys_dog(img):## 先对图像进行两次高斯滤波运算# 1.采用skimage进行高斯滤波gimg1 filters.gaussian(img, sigma6)gimg2 filters.gaussian(img, sigma3)# 2.采用cv进行高斯滤波# gimg1 cv2.GaussianBlur(img, (3, 3), sigmaX6)# gimg2 cv2.GaussianBlur(img, (3, 3), sigmaX3)# 两个高斯运算的差分dimg gimg1 - gimg2return gimg1, gimg2, dimgif name main:gray_img cv2.imread(H:\Zivid\pho\gray1.jpg, 0)gimg1, gimg2, dimg sys_dog(gray_img)cv2.imshow(ori, gray_img)cv2.imshow(gaus1, gimg1)cv2.imshow(gaus2, gimg2)cv2.imshow(gaus1-2, dimg)cv2.waitKey(0) 感谢以下博主都是大佬 菜菜粥 brycezou 有情怀的机械男 zhulu_20 TechArtisan6 疯狂的Little_Bee Senit_Co 等等等
- 上一篇: 十堰做网站网站底部流程
- 下一篇: 石河子市建设局网站营销型网站
