一、Canny算法步骤:
1.高斯模糊 — GaussianBlur
2.灰度转化 —CvtColor
3.计算梯度 — Sobel / Scharr
4.非最大信号抑制:边缘信号很强,但只能有一个信号(边缘只能是一条线,而不能是一个有宽度的面),对其他的非边缘信号进行压制(在梯度方向上,如果不是最大信号就剔除)。
5.高低阈值输出二值图像。
找到梯度强度和方向:
θ:在 0 ~ 180 之间,表示梯度方向 ,值表现了梯度在那个方向的变化率最大。
45 ,90 ,135 对应区域
1.黄色区域其值范围: 0 ~ 22.5 与 157.5 ~ 180
2.绿色区域取值范围:22.5 ~ 67.5
3.蓝色区域取值范围:67.5 ~ 112.5
4.棕色区域取值范围:112.5 ~ 157.5
有梯度得到变化趋势方向,在与变化趋势垂直的方向寻找相邻的左右两个像素,与中间值作比较。
private void button1_Click(object sender, EventArgs e)
{
Canny(@"C:\Users\shang\Desktop\OPENCVsharp\图像\ImageTest2\010161.jpg");
}
#region Canny算子 边缘提取
static Mat src = new Mat();
static Mat dst = new Mat();
static Mat gray = new Mat();
static Mat output = new Mat();
static int minVal = 50;
static int maxVal = 255;
const string outputName = "Canny Result";
private static void Canny(string path)
{
src = new Mat(path, ImreadModes.AnyColor | ImreadModes.AnyDepth);
dst = new Mat(src.Size(), src.Type());
new Window("SRC", WindowMode.AutoSize, src);
src.CopyTo(dst);
Cv2.CvtColor(dst, gray, ColorConversionCodes.RGB2GRAY); //转为灰度图(必须转)
new Window(outputName, WindowMode.AutoSize);
Cv2.Blur(gray, gray, new Size(3, 3), new Point(-1, -1), BorderTypes.Default);//模糊处理(降低噪点)
CvTrackbarCallback2 CannyDome = new CvTrackbarCallback2(CallBarck_CannyDome);
CvTrackbar cvt = new CvTrackbar("Bar :", outputName, minVal, maxVal, CallBarck_CannyDome, src);
//Cv2.Canny(gray, dst, 100, 255, 3,true);
//using (new Window("DST", WindowMode.AutoSize, dst))
//using (new Window("SRC", WindowMode.AutoSize, src))
//{
Cv2.WaitKey(0);
}
/// <summary>
/// 委托函数
/// </summary>
/// <param name="pos">变化的量</param>
/// <param name="userdata">传入的数据对象</param>
private static void CallBarck_CannyDome(int pos, object userdata)
{
Mat m = (Mat)userdata;
Cv2.Canny(m, output, pos, pos * 2, 3, true);
dst = new Mat(src.Size(), src.Type());
/*
* 拷贝数据
* 参数 Mat m :拷贝到
* Mat mask : 要拷贝的对象 (mask 的像素是非0的才拷贝,是0不拷贝)
*
*
*/
src.CopyTo(dst, output); //拷贝:
Cv2.ImShow(outputName, dst);
}
#endregion