6永興は、画像勾配とOpenCVのエッジ検出ノート

ここに画像を挿入説明

まず、画像勾配は何ですか。

勾配画像がグレー画像の変化を説明するために、計算は、関数の変化率を計算することである、すなわち、数(勾配)がターンオンされます。隣接する2つの画素間の差に対応する勾配画像。
二次元画像は、離散関数であるように、画像勾配を見ることができ、画像の勾配誘導体の実際に2次元離散関数である:
x方向に、ある画素を選択するために、画素値が100であると仮定され、x方向の隣接画素であります90,90,90、これは上記のx方向勾配10,0,0それぞれ計算されます。ここでしか変化率の絶対値は、変化の大きさを示します。
ここに画像を挿入説明
100と9010との間の輝度差の階調値が、非常に明確ではないが、90の大きなグループに連続階調値、プロファイルがぼやけされなければなりません。我々は、次に、ゼロ勾配、隣接する画素のグレーの値が変化しない場合、隣接する画素のグレースケール値は、その後、勾配の値は、存在する場合に変化があることに注意してください。画素加算に対応我々勾配値は、グレー値が変化しない場合、画素値は、勾配値は、階調値が大きくなるが、画像のエッジがより顕著で、不変です。
ここに画像を挿入説明

二つ、勾配画像(エッジ検出)のOpenCVのアプリケーション:

OpenCVの勾配フィルタ又はハイパスフィルタの3種類の、ソーベル、Scharr及びラプラシアンを提供する。
ハイパスフィルタ(英語:ハイパスフィルタ)高周波信号を可能にすることであるが、減衰(または減少)低い周波数信号のカットオフ周波数よりフィルターを通しました。異なる目的のためにフィルタ、各信号の周波数に対して弱めの程度が異なります。それは時々低周波カットフィルタと呼ばれ、
基本的な数学的しらふ:
ここに画像を挿入説明
1、Soberのオペレータ。
Soberのオペレータが近似階調勾配画像を計算するために使用される離散微分演算子(離散微分演算子)です。
cv2.Sobel(SRC、ddepth、DX、 DY、DST =なし、ksize =なし、スケール=なし、デルタ=なし、borderType =なし)

  • SRC:元画像
  • ddepth : 目标图像的深度,填写 -1 则保存与原图像的深度一致;
    图像深度是单个像素点的色彩详细度,往往把像素深度说成是图像深度。表示一个像素的位数越多,它能表达的颜色数目就越多,而它的深度就越深。
    src.depth() 为原图像的深度,则一般对应的ddepth为:
sec.depth() ddepth
CV_8U -1/CV_16S/CV_32F/CV_64F
CV_16U/CV_16S -1/CV_32F/CV_64F
CV_32F -1/CV_32F/CV_64F
CV_64F -1/CV_64F
  • dx:表示在x方向上求导的阶数
  • dy:表示在y方向上求导的阶数
    如果是0则表示在该方向上不求导(不能2个方向都是0)
    一阶导数可以用来描述原函数的增减性。
    二阶导数可以用来判断函数在一段区间上的凹凸性,f’’(x)>0,则是凹的,f’’(x)<0则是凸的。
  • dst : 表示输出图像
  • ksize : 内核大小
    如果不填写或者ksize<0,那么使用scharr内核过滤因子。scharr的内核过滤因子大小为3。
    xorder = dx ,xorder = dy
    ここに画像を挿入説明
  • scale : scale是缩放导数的比例常数,默认情况下没有伸缩系数;
  • delta :在将目标图像存储进多维数组前,可以将每个像素值增加delta,默认为0;
  • borderType :是判断图像边界的模式。这个参数默认值为cv2.BORDER_DEFAULT。
    ここに画像を挿入説明
import cv2
img = cv2.imread("first.jpg")
GRAYImg = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
SoberImg = cv2.Sobel(GRAYImg,-1,0,1)
cv2.imshow("img",img)
cv2.imshow("GRAYimg",GRAYImg)
cv2.imshow("Sober",SoberImg)
cv2.waitKey()
cv2.destroyAllWindows()

ここに画像を挿入説明
Sobel算子算法的优点是计算简单,速度快。但是由于只采用了2个方向的模板,只能检测水平和垂直方向的边缘,因此这种算法对于纹理较为复杂的图像,其边缘检测效果就不是很理想。该算法认为:凡灰度新值大于或等于阈值的像素点时都是边缘点。这种判断有点欠合理,可能会造成边缘点的误判,因为许多噪声点的灰度值也很大。

2、Scharr 算子
cv2.Scharr(src, ddepth, dx, dy, dst=None, scale=None, delta=None, borderType=None)

  • dx 和 dy : dx >= 0 && dy >= 0 && dx+dy == 1
  • 会看到参数和Sobel算子一致,不过,该函数与Sobel的区别在于,Scharr仅作用于大小为3的内核。但结果更为精确
  • scharr算子与Sobel的不同点是在平滑部分,这里所用的平滑算子是1/16∗[3,10,3],相比于1/4∗[1,2,1],中心元素占的权重更重
    ここに画像を挿入説明
    大小一样,故计算量一样。
    scharr算子临近像素的权重更大,故精确度更高。
    对比两种算子的处理效果。发现scharr算子能计算出更小的梯度变化
    Scharr:
    ここに画像を挿入説明
import cv2
img = cv2.imread("first.jpg")
GRAYImg = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
Scharr = cv2.Scharr(GRAYImg,-1,0,1)
cv2.imshow("img",img)
cv2.imshow("GRAYimg",GRAYImg)
cv2.imshow("Scharr",Scharr)
cv2.waitKey()
cv2.destroyAllWindows()

3、Laplacian 算子

Laplacian算子属于二阶微分算子。
二阶微分的边缘定位能力更强,锐化效果更好
ここに画像を挿入説明
ここに画像を挿入説明
Laplacian算子进行边缘检测并没有像Sobel的平滑过程,所以它会对噪声产生较大的响应,并且无法分别得到水平方向、垂直方向或者其他固定方向的的边缘。但是它只有一个卷积核,所以计算成本会更低。
ここに画像を挿入説明
从模板形式容易看出,如果在图像中一个较暗的区域中出现了一个亮点,那么用拉普拉斯运算就会使这个亮点变得更亮。因为图像中的边缘就是那些灰度发生跳变的区域,所以拉普拉斯锐化模板在边缘检测中很有用。一般增强技术对于陡峭的边缘和缓慢变化的边缘很难确定其边缘线的位置。但此算子却可用二次微分正峰和负峰之间的过零点来确定,对孤立点或端点更为敏感,因此特别适用于以突出图像中的孤立点、孤立线或线端点为目的的场合。同梯度算子一样,拉普拉斯算子(Laplacian)也会增强图像中的噪声,有时用拉普拉斯算子进行边缘检测时,可将图像先进行平滑处理。
图像锐化处理的作用是使灰度反差增强,从而使模糊图像变得更加清晰。 图像模糊的实质就是图像受到平均运算或积分运算 。 因此可以对图像进行逆运算,如微分运算能够突出图像细节,使图像变得更为清晰。由于拉普拉斯是一种微分算子,它的应用可增强图像中灰度突变的区域,减弱灰度的缓慢变化区域。

cv2.Laplacian(src, ddepth, dst=None, ksize=None, scale=None, delta=None, borderType=None)

  • src :原图像
  • ddepth:输出图像深度,-1则为保持原图像一致
    src.depth() 为原图像的深度,则一般对应的ddepth为:
深度 取值范围
CV_8U 0–255
CV_8S -128–127
CV_16U 0–65535
CV_16S -32768–32767
CV_32S 0–65535
CV_32F(单精度浮点数) 0.0–1.0
CV_64F(双精度浮点数 ) 0.0–1.0
src.depth() ddepth
CV_8U -1/CV_16S/CV_32F/CV_64F
CV_16S -1/CV_32F/CV_64F
CV_32F -1/CV_32F/CV_64F
CV_64F -1/CV_64F

转换深度后的图像可能需要归一化;

  • dst:处理后的图像
  • ksize:内核大小(大小必须为正奇数)(一般为1、3、5、7。默认为1)
  • scale是缩放导数的比例常数,默认情况下没有伸缩系数;
  • delta是一个可选的增量,将会加到最终的dst中,同样,默认情况下没有额外的值加到dst中;
  • borderType是判断图像边界的模式。这个参数默认值为cv2.BORDER_DEFAULT。
    ここに画像を挿入説明
import cv2
img = cv2.imread("first.jpg",0) #灰度模式读取图像
LaplacianImg = cv2.Laplacian(img,-1)
cv2.imshow("img",img)
cv2.imshow("Laplacian",LaplacianImg)
cv2.waitKey()
cv2.destroyAllWindows()

ここに画像を挿入説明

三、边缘检测:

边缘检测是图像处理和计算机视觉中的基本问题,边缘检测的目的是标识数字图像中亮度变化明显的点。图像属性中的显著变化通常反映了属性的重要事件和变化。 这些包括(i)深度上的不连续、(ii)表面方向不连续、(iii)物质属性变化和(iv)场景照明变化。 边缘检测是图像处理和计算机视觉中,尤其是特征提取中的一个研究领域。
图像边缘检测大幅度地减少了数据量,并且剔除了可以认为不相关的信息,保留了图像重要的结构属性。 有许多方法用于边缘检测,它们的绝大部分可以划分为两类:基于查找一类和基于零穿越的一类。基于查找的方法通过寻找图像一阶导数中的最大和最小值来检测边界,通常是将边界定位在梯度最大的方向。基于零穿越的方法通过寻找图像二阶导数零穿越来寻找边界,通常是Laplacian过零点或者非线性差分表示的过零点。
边缘检测的一般步骤:

  • 滤波:边缘检测的算法主要是基于图像强度的一阶和二阶导数,但导数通常对噪声很敏感,因此必须采用滤波器来改善与噪声有关的边缘检测器的性能。常见的滤波方法主要有高斯滤波,即采用离散化的高斯函数产生一组归一化的高斯核(具体见“高斯滤波原理及其编程离散化实现方法”一文),然后基于高斯核函数对图像灰度矩阵的每一点进行加权求和(具体程序实现见下文)。
  • 增强:增强边缘的基础是确定图像各点邻域强度的变化值。增强算法可以将图像灰度点邻域强度值有显著变化的点凸显出来。在具体编程实现时,可通过计算梯度幅值来确定。
  • 检测:经过增强的图像,往往邻域中有很多点的梯度值比较大,而在特定的应用中,这些点并不是我们要找的边缘点,所以应该采用某种方法来对这些点进行取舍。实际工程中,常用的方法是通过阈值化方法来检测。

Canny 边缘检测 :
原理:

  • 去噪:先经过高斯平滑

  • 增强:寻找图像强度梯度

  • 非极大抑制:
    这一步的目的是将模糊(blurred)的边界变得清晰(sharp)。通俗的讲,就是保留了每个像素点上梯度强度的极大值,而删掉其他的值。对于每个像素点,进行如下操作:
    将其梯度方向近似为以下值中的一个(0,45,90,135,180,225,270,315)(即上下左右和45度方向)
    ここに画像を挿入説明
    比较该像素点,和其梯度方向正负方向的像素点的梯度强度
    如果该像素点梯度强度最大则保留,否则抑制(删除,即置为0)
    ここに画像を挿入説明

  • 双阈值
    经过非极大抑制后图像中仍然有很多噪声点。Canny算法中应用了一种叫双阈值的技术。即设定一个阈值上界和阈值下界(opencv中通常由人为指定的),图像中的像素点如果大于阈值上界则认为必然是边界(称为强边界,strong edge),小于阈值下界则认为必然不是边界,两者之间的则认为是候选项(称为弱边界,weak edge)。

  • 利用滞后的边界跟踪
    思想:和强边界相连的弱边界认为是边界,其他的弱边界则被抑制
    滞后阈值:
    现在需要确定哪些边界是真正的边界,需要两个阈值,minVal和maxVal。图像灰度梯度 高于maxVal被认为是真正的边界,低于minVal的舍弃。两者之间的值要判断是否与真正的边界相连,相连就保留,不相连舍弃。

    • Ⅰ.如果某一像素位置的幅值超过 高 阈值, 该像素被保留为边缘像素。

    • Ⅱ.如果某一像素位置的幅值小于 低 阈值, 该像素被排除。

    • Ⅲ.如果某一像素位置的幅值在两个阈值之间,该像素仅仅在连接到一个高于 高 阈值的像素时被保留。
      ここに画像を挿入説明

cv2.Canny(image, threshold1, threshold2, edges=None, apertureSize=None, L2gradient=None)

  • image : 原图像
  • threshold1:阈值1
  • threshold2:阈值2
    • 低于阈值1的像素点会被认为不是边缘;
    • 高于阈值2的像素点会被认为是边缘;
    • 在阈值1和阈值2之间的像素点,若与处理后得到的边缘像素点相邻,则被认为是边缘,否则被认为不是边缘。
    • 对于Canny函数的使用,推荐的高低阈值比在2:1到3:1之间。
  • edges:输出边缘映射; 默认:单通道8位图像,与图像大小相同。
  • apertureSize:Sobel算子内核大小 (默认为3)
  • L2gredient:是否采用更精确的方式计算图像梯度(默认为 False)
import cv2
img = cv2.imread("first.jpg")
GRAYImg = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)  #转换为灰度图像
GauBurlGrayImg = cv2.GaussianBlur(GRAYImg,(3,3),1) #进行高斯滤波
imgCanny = cv2.Canny(GauBurlGrayImg,100,200) #边缘检测
cv2.imshow("img",img)
cv2.imshow("Canny",imgCanny)
cv2.waitKey()
cv2.destroyAllWindows()

ここに画像を挿入説明
Canny 的特点:

  • 1.低错误率: 标识出尽可能多的实际边缘,同时尽可能的减少噪声产生的误报。
  • 2.高定位性: 标识出的边缘要与图像中的实际边缘尽可能接近。
  • 3.最小响应: 图像中的边缘只能标识一次,并且可能存在的图像噪声不因标识为边缘。

练习题6:

同じ絵。Sobor、Scharr、ラプラス演算子とキャニーを、同時に5枚の画像を表示:画像をグレースケールに変換された後、使用しました。(調整パラメータの4種類のエッジ検出の最良の実施形態を達成するために必要)

あなたの答えをコメントアウトします。

公開された45元の記事 ウォン称賛28 ビュー10000 +

おすすめ

転載: blog.csdn.net/m0_43505377/article/details/103772566