cany邊緣檢測算法(坎尼算法)

砍尼算法是最優的邊緣檢測器

預備知識:


圖像梯度:在一幅圖像f(x,y)位置處尋找的邊緣強度和方向,所選工具就是梯度。


求取圖像梯度的方法:用模板算子:如sobel算子等,算子有方向區別,x方向算子,y方向算子


通過模板可以得到Gx(x,y),Gy(x,y)兩張與原圖像尺寸一樣的梯度圖,Gx(x,y),Gy(x,y)分表表示x,y方向的梯度圖



cany邊緣求取算法


步驟;

用高斯濾波平滑圖像(去掉細節,使大邊緣在分割後效果更明顯);

計算梯度幅值圖像和角度賦值圖像:M(x,y)=|Gx|+|Gy|;,角度幅值圖像爲a(x,y)=arctan[Gy/Gx],(x,y)爲圖像的取值範圍爲圖像各像素點座標;

對梯度幅值圖像應用非最大抑制;

用雙魚之處理和鏈接分析來檢測並鏈接邊緣。


應用實例

#include "stdafx.h"





#include <opencv2/opencv.hpp>   
#include <opencv2/highgui.hpp>   
#include<iostream>    
#define PI 3.1415926    
#define R 150    

using namespace cv;
using namespace std;
Mat getHistImg(const MatND& hist);

int main()
{
    Mat result;//聲明一個表示圖像的變量;
    Mat gray;
    int height;
    int width;
    gray = imread("../13.jpg");
   


    Canny(gray, result, 20, 100, 3);//cany算法函數,gray爲輸入圖像,result爲輸出圖像,20爲第閾   值,100爲高閾值,3爲sobel算子尺寸
    
     

   
    imshow("1", result);
   

     waitKey(0);

}


int main()
{
    Mat image,image1, abs_image, abs_image1,result;//聲明一個表示圖像的變量;
    Mat gray;
 
    int height;
    int width;

    gray = imread("../13.jpg");
    cvtColor(gray, gray, CV_BGR2GRAY);
    medianBlur(gray, gray, 11);
    height = gray.rows;
    width = gray.cols* gray.channels();   // 列項要乘通道數  

    for (int i = 0; i< height; i++)
    {
        for (int j = 0; j< width; j++)
        {
            if (gray.at<uchar>(i, j) > 69)
                gray.at<uchar>(i, j) = 255; //- gray.at<uchar>(i, j);   // 每一個像素反轉  
            else
                gray.at<uchar>(i, j) = 0;
        }
    }
   
  
          /*用sobel算子提取邊緣*/
   
    Sobel(gray, image1, CV_8U, 0, 1, 3, 1, 0, BORDER_DEFAULT);//提取y方向的
    Sobel(gray, image, CV_8U, 1, 0, 3, 1, 0, BORDER_DEFAULT);//提取x方向的
    convertScaleAbs(image1, abs_image1);           //對提取到的梯度圖求絕對值
    convertScaleAbs(image, abs_image);
    addWeighted(abs_image1, 0.5, abs_image, 0.5, 0, result);   //求取梯度幅值圖像result
      
       
    imshow("1", result);

   
    waitKey(0);

}    








發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章