1. 程式人生 > >【OpenCV學習筆記】2.3影象的腐蝕、膨脹、模糊、邊緣檢測

【OpenCV學習筆記】2.3影象的腐蝕、膨脹、模糊、邊緣檢測

一、腐蝕和膨脹:

膨脹演算法使影象擴大一圈
腐蝕演算法使二值影象減小一圈

1、演算法:

從影象處理角度看,二值影象的腐蝕和膨脹就是將一個小型二值圖(結構元素,一般為3*3大小)在一個大的二值圖上逐點移動並進行比較,根據比較的結果作出相應處理而已。

  • 膨脹演算法:用結構元素,掃描二值影象的每一個畫素,用結構元素與其覆蓋的二值影象做“與”運算,如果都為0,結構影象的該畫素為0,否則為1.結果:使二值影象擴大一圈。
  • 腐蝕演算法:用結構元素,掃描二值影象的每一個畫素,用結構元素與其覆蓋的二值影象做“與”運算,如果都為1,結構影象的該畫素為1,否則為0.結果:使二值影象減小一圈。

2、函式

dilate 膨脹

void cv::dilate( const CvArr* src, CvArr* dst, IplConvKernel* element=NULL, int iterations=1 );  

src——輸入影象.
dst——輸出影象.
element——用於膨脹的結構元素。若為 NULL, 則使用 3×3 長方形的結構元素
iterations——膨脹的次數

對彩色影象,每個彩色通道單獨處理。

erode 腐蝕

void cv::erode( const CvArr* src, CvArr* dst, IplConvKernel* element=NULL
, int iterations=1 );

src——輸入影象.
dst——輸出影象.
element——用於腐蝕的結構元素。若為 NULL, 則使用 3×3 長方形的結構元素
iterations——腐蝕的次數

函式 Erode 對輸入影象使用指定的結構元素進行腐蝕,該結構元素決定每個具有最小值象素點的鄰域形狀

結構元素

我們一般使用函式 getStructuringElement配合膨脹或腐蝕演算法使用。
其中,getStructuringElement函式的第一個引數表示核心的形狀,我們可以選擇如下三種形狀之一:

  • 矩形: MORPH_RECT
  • 交叉形: MORPH_CROSS
  • 橢圓形: MORPH_ELLIPSE

而getStructuringElement函式的第二和第三個引數分別是核心的尺寸以及錨點的位置。

getStructuringElement函式會返回指定形狀和尺寸的結構元素(核心矩陣)。

Mat element = getStructuringElement(MORPH_RECT,
  Size(2*g_nStructElementSize+1,2*g_nStructElementSize+1),
  Point( g_nStructElementSize, g_nStructElementSize ));

3、例項

繼續用之前的那張圖片

<1>程式碼

int main(){
    system("color 5F");
    img = imread("yqsn.png",1);
    if (!img.data) { printf("Oh,no,讀取img圖片檔案錯誤~! \n"); return -1; }
    namedWindow("【1】原畫");
    imshow("【1】原畫", img);

    Mat element = getStructuringElement(MORPH_RECT, Size(5,5));//結構元素    
    Mat dstImage;

    erode(img, dstImage, element);//腐蝕
    namedWindow("【3】腐蝕");
    imshow("【3】腐蝕", dstImage);

    dilate(img, dstImage, element);//膨脹
    namedWindow("【4】膨脹");
    imshow("【4】膨脹", dstImage);

    waitKey(0);
    return 0;
}

<2>效果

這裡寫圖片描述

這裡寫圖片描述

<3>新增Toolbar滾動條的效果

#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include "opencv2/imgproc/imgproc.hpp"  

using namespace std;
using namespace cv;

Mat img;
int threshval;

static void on_trackbar(int, void*)
{
    if (threshval == 0)  { threshval=1; }
    Mat element = getStructuringElement(MORPH_RECT, Size(threshval, threshval));//結構元素    
    Mat dstImage;
    erode(img, dstImage, element);//腐蝕
    imshow("[2]滾動條改變腐蝕程度", dstImage);
}

int main()
{
    system("color 5F");
    //載入圖片  
    img = imread("C:/Users/Red/Documents/Visual Studio 2013/Projects/StudyOpenCV/yqsn.png");
    if (!img.data) { printf("Oh,no,讀取img圖片檔案錯誤~! \n"); return -1; }

    //顯示原圖  
    namedWindow("[1]原圖");
    imshow("[1]原圖", img);

    threshval = 25;
    //建立處理視窗  
    namedWindow("[2]滾動條改變腐蝕程度", 1);
    //建立軌跡條  
    createTrackbar("Threshold", "[2]滾動條改變腐蝕程度", &threshval, 50, on_trackbar);
    on_trackbar(threshval, 0);//軌跡條回撥函式  

    waitKey(0);
    return 0;
}

這裡寫圖片描述

二、模糊與Canny邊緣檢測

    Mat edge, grayImage;
    cvtColor(img, grayImage, CV_BGR2GRAY);//顏色模型轉換
    blur(grayImage, edge, Size(3, 3));
    namedWindow("【5】模糊-均值濾波");
    imshow("【5】模糊-均值濾波", edge);
    Canny(edge, edge, 3, 9, 3);
    namedWindow("【6】Canny邊緣檢測");
    imshow("【6】Canny邊緣檢測", edge);

這裡寫圖片描述

這裡寫圖片描述

臉麻麻的……