标签:推荐 max function 检测 ssi 大小 它的 好的 group
canny的目标有3个
canny分几步
前面2步我们应该很熟悉了,不熟悉的参考https://www.cnblogs.com/sdu20112013/p/11608469.html 和 https://www.cnblogs.com/sdu20112013/p/11600436.html
在求解梯度这一步,我们可以得到梯度的模长和方向
这一步为我们下面做nms(非极大值抑制)打下了基础,索贝尔算子处理后的图像得到的边缘可能是很粗糙的,反映到图像上也就是边缘比较宽,我们采用nms把非极大值的点的灰度都置为0,这样就可以滤掉很多非边缘的像素点.
如下图所示,C表示为当前非极大值抑制的点,g1-4为它的8连通邻域点,图中蓝色线段表示上一步计算得到的角度图像C点的值,即梯度方向,第一步先判断C灰度值在8值邻域内是否最大,如是则继续检查图中梯度方向交点dTmp1,dTmp2值是否大于C,如C点大于dTmp1,dTmp2点的灰度值,则认定C点为极大值点,置为1,因此最后生成的图像应为一副二值图像,边缘理想状态下都为单像素边缘.
这一步里有一点需要注意的就是dTmp1,dTmp2,这两个像素点是不存在的,是通过双线性插值法算出来的. 在John Canny提出的Canny算子的论文中,非最大值抑制就只是在0、90、45、135四个梯度方向上进行的,每个像素点梯度方向按照相近程度用这四个方向来代替.实际检测过程里,为了更准确地过滤出属于边缘的像素点,会做双线性插值得到dTmp1,dTmp2.再去做前面所说的nms过程去判断一个像素点是否属于边缘.
推荐2篇讲的比较好的:https://blog.csdn.net/kezunhai/article/details/11620357 https://www.cnblogs.com/techyan1990/p/7291771.html
关于如何得到梯度方向的像素点,如下图所示
这样的话就达到了将"粗大的边缘"过滤地更加细腻.
这一步之后,得到的边缘还包含很多由噪声及其他原因造成的假边缘.
经过nms以后,已经很接近真实边缘了.但还是有一些由于噪声或者别的一些原因造成的假的边缘.我们通过2个阈值来作进一步的过滤.
Hysteresis: The final step. Canny does use two thresholds (upper and lower): - If a pixel gradient is higher than the upper threshold, the pixel is accepted as an edge .If a pixel gradient value is below the lower threshold, then it is rejected.If the pixel gradient is between the two thresholds, then it will be accepted only if it is connected to a pixel that is above the upper threshold.
Canny recommended a upper:lower ratio between 2:1 and 3:1.
实际工程里,这两个参数要针对你自己的图像数据去调整,太低有可能造成假边缘太多,太高有可能造成想要保留的边缘也被滤掉了.
canny api
参数3,4表示低阈值和高阈值,L2gradient默认false,表示是否用开平方的方式计算梯度的大小.
from __future__ import print_function
import cv2 as cv
import argparse
max_lowThreshold = 100
window_name = 'Edge Map'
title_trackbar = 'Min Threshold:'
ratio = 3
kernel_size = 3
def CannyThreshold(val):
low_threshold = val
#img_blur = cv.blur(src_gray, (3,3))
detected_edges = cv.Canny(src_gray, low_threshold, low_threshold*ratio, kernel_size)
mask = detected_edges != 0
dst = src * (mask[:,:,None].astype(src.dtype))
cv.imshow(window_name, dst)
src = cv.imread("/home/sc/disk/keepgoing/opencv_test/sidetest.jpeg")
src = cv.GaussianBlur(src, (3, 3), 0)
src_gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
cv.namedWindow(window_name)
cv.createTrackbar(title_trackbar, window_name , 0, max_lowThreshold, CannyThreshold)
CannyThreshold(0)
cv.waitKey()
注意阈值的不同造成的影响,可以看到阈值很低的时候线条更多,当然"伪边缘"更多,当阈值很高的时候,"伪边缘"减少了,但也丢失了更多的细节.所以需要根据自己实际的图片数据去调参.
标签:推荐 max function 检测 ssi 大小 它的 好的 group
原文地址:https://www.cnblogs.com/sdu20112013/p/11614059.html