欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

OpenCV圖像處理之實(shí)現(xiàn)圖像膨脹腐蝕操作

 更新時(shí)間:2022年09月08日 12:00:01   作者:肖愛Kun  
圖像形態(tài)學(xué)操作是指基于形狀的一系列圖像處理操作的合集,主要是基于集合論基礎(chǔ)上的形態(tài)學(xué)數(shù)學(xué)對(duì)圖像進(jìn)行處理。本文將為大家介紹一下如何利用OpenCV實(shí)現(xiàn)其中的腐蝕和膨脹操作,需要的可以參考一下

一.形態(tài)學(xué)操作概念

圖像形態(tài)學(xué)操作是指基于形狀的一系列圖像處理操作的合集,主要是基于集合論基礎(chǔ)上的形態(tài)學(xué)數(shù)學(xué)對(duì)圖像進(jìn)行處理。

形態(tài)學(xué)有四個(gè)基本操作:腐蝕、膨脹、開操作、閉操作,膨脹與腐蝕是圖像處理中最常用的形態(tài)學(xué)操作手段。

二.形態(tài)學(xué)操作-膨脹

跟卷積操作類似,假設(shè)有圖像A和結(jié)構(gòu)元素B,結(jié)構(gòu)元素B在圖像A上面移動(dòng),其中結(jié)構(gòu)元素B定義其中心為錨點(diǎn),計(jì)算B覆蓋下A的最大像素值用來替換錨點(diǎn)的像素,其中B作為結(jié)構(gòu)體可以是任意形狀。

膨脹的原理:

膨脹或者腐蝕操作就是將圖像(或圖像的一部分區(qū)域,我們稱之為圖像A)與結(jié)構(gòu)元素(我們稱之為卷積核B)進(jìn)行卷積。核可以是任何的形狀和大小,擁有一個(gè)單獨(dú)定義出來的參考點(diǎn),我們稱其為錨點(diǎn)(anchorpoin)。多數(shù)情況下,核是一個(gè)小的中間帶有參考點(diǎn)和實(shí)心正方形或者圓盤,可以把核視為模板或者掩碼。

膨脹就是求局部最大值的操作,核B與圖形卷積,即計(jì)算核B覆蓋的區(qū)域的像素點(diǎn)的最大值,并把這個(gè)最大值賦值給參考點(diǎn)指定的像素。這樣就會(huì)使圖像中的高亮區(qū)域逐漸增長。

膨脹和腐蝕操作的核心內(nèi)容是結(jié)構(gòu)元素。一般來說結(jié)構(gòu)元素是由元素為1或者0的矩陣組成。結(jié)構(gòu)元素為1的區(qū)域定義了圖像的領(lǐng)域,領(lǐng)域內(nèi)的像素在進(jìn)行膨脹和腐蝕等形態(tài)學(xué)操作時(shí)要進(jìn)行考慮。

膨脹函數(shù)API接口

dst=cv2.dilate(  
        InputArray src,  
        OutputArray dst,  
        InputArray kernel,  
        Point anchor=Point(-1,-1),  
        int iterations=1,  
        int borderType=BORDER_CONSTANT,  
        const Scalar& borderValue=morphologyDefaultBorderValue()   
    );  

參數(shù)詳解:

第一個(gè)參數(shù),InputArray類型的src,輸入圖像,即源圖像,填Mat類的對(duì)象即可。圖像通道的數(shù)量可以是任意的,但圖像深度應(yīng)為CV_8U,CV_16U,CV_16S,CV_32F或 CV_64F其中之一。
第二個(gè)參數(shù),OutputArray類型的dst,即目標(biāo)圖像,需要和源圖片有一樣的尺寸和類型。

第三個(gè)參數(shù),InputArray類型的kernel,膨脹操作的核。若為NULL時(shí),表示的是使用參考點(diǎn)位于中心3x3的核。

我們一般使用函數(shù) getStructuringElement配合這個(gè)參數(shù)的使用。getStructuringElement函數(shù)會(huì)返回指定形狀和尺寸的結(jié)構(gòu)元素(內(nèi)核矩陣)。

其中,getStructuringElement函數(shù)的第一個(gè)參數(shù)表示內(nèi)核的形狀,我們可以選擇如下三種形狀之一:

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

而getStructuringElement函數(shù)的第二和第三個(gè)參數(shù)分別是內(nèi)核的尺寸以及錨點(diǎn)的位置。

我們一般在調(diào)用erode以及dilate函數(shù)之前,先定義一個(gè)Mat類型的變量來獲得getStructuringElement函數(shù)的返回值。對(duì)于錨點(diǎn)的位置,有默認(rèn)值Point(-1,-1),表示錨點(diǎn)位于中心。且需要注意,十字形的element形狀唯一依賴于錨點(diǎn)的位置。而在其他情況下,錨點(diǎn)只是影響了形態(tài)學(xué)運(yùn)算結(jié)果的偏移。

getStructuringElement函數(shù)相關(guān)的調(diào)用示例代碼如下:

int g_nStructElementSize = 3; //結(jié)構(gòu)元素(內(nèi)核矩陣)的尺寸
 //獲取自定義核
Mat element = getStructuringElement(MORPH_RECT,
    Size(2*g_nStructElementSize+1,2*g_nStructElementSize+1),
    Point( g_nStructElementSize, g_nStructElementSize ));

第四個(gè)參數(shù),Point類型的anchor,錨的位置,其有默認(rèn)值(-1,-1),表示錨位于中心。

第五個(gè)參數(shù),int類型的iterations,迭代使用erode()函數(shù)的次數(shù),默認(rèn)值為1。

第六個(gè)參數(shù),int類型的borderType,用于推斷圖像外部像素的某種邊界模式。注意它有默認(rèn)值BORDER_DEFAULT。

第七個(gè)參數(shù),const Scalar&類型的borderValue,當(dāng)邊界為常數(shù)時(shí)的邊界值,有默認(rèn)值morphologyDefaultBorderValue(),一般我們不用去管他。需要用到它時(shí),可以看官方文檔中的createMorphologyFilter()函數(shù)得到更詳細(xì)的解釋。

使用erode函數(shù),一般我們只需要填前面的三個(gè)參數(shù),后面的四個(gè)參數(shù)都有默認(rèn)值。而且往往結(jié)合getStructuringElement一起使用。

結(jié)構(gòu)元素的API函數(shù)接口

cv::Mat kernel = getStructuringElement(int shape,Size ksize,Point anchor);
//返回值:返回指定形狀和尺寸的結(jié)構(gòu)元素
 
 
//結(jié)構(gòu)元素的定義:形狀 (MORPH_RECT(矩形核)
//MORPH_CROSS(十字交叉形核) 
//MORPH_ELLIPSE(橢圓形核));結(jié)構(gòu)元素大??;錨點(diǎn) 默認(rèn)是Point(-1, -1)意思就是中心像素,也可以自己指定
 
//函數(shù)接口示例
cv::Mat elementRect,elementCross,elementEllipse;
 
    elementRect = cv::getStructuringElement(cv::MORPH_RECT,cv::Size(3,3),cv::Point(-1,-1));
 
    elementCross = 
    cv::getStructuringElement(cv::MORPH_CROSS,cv::Size(3,3),cv::Point(-1,-1));
 
    elementEllipse = 
    cv::getStructuringElement(cv::MORPH_ELLIPSE,cv::Size(5,5),cv::Point(-1,-1));
 

此外,我們也可以自定義結(jié)構(gòu)元素,如下:

使用Mat_模板類自定義5×5大小十字形、菱形、方形、x形結(jié)構(gòu)元素:

 //自定義核(結(jié)構(gòu)元素)
    cv::Mat_<uchar> cross(5,5);
    cv::Mat_<uchar> diamond(5,5);
    cv::Mat_<uchar> x(5,5);
    cv::Mat_<uchar> square(5,5);
 
    // Creating the cross-shaped structuring element
    cross <<
            0, 0, 1, 0, 0,
            0, 0, 1, 0, 0,
            1, 1, 1, 1, 1,
            0, 0, 1, 0, 0,
            0, 0, 1, 0, 0;
 
    // Creating the diamond-shaped structuring element
    diamond <<
            0, 0, 1, 0, 0,
            0, 1, 1, 1, 0,
            1, 1, 1, 1, 1,
            0, 1, 1, 1, 0,
            0, 0, 1, 0, 0;
 
    // Creating the x-shaped structuring element
    x <<
            1, 0, 0, 0, 1,
            0, 1, 0, 1, 0,
            0, 0, 1, 0, 0,
            0, 1, 0, 1, 0,
            1, 0, 0, 0, 1;
 
    // Creating the square-shaped structuring element
    square <<
            1, 1, 1, 1, 1,
            1, 1, 1, 1, 1,
            1, 1, 1, 1, 1,
            1, 1, 1, 1, 1,
            1, 1, 1, 1, 1;
 
    int xnr = x.rows;
    int xnl = x.cols;
    for(int j = 0;j<xnr;j++)
    {
        char *data = x.ptr<char>(j);
        for(int i = 0; i<xnl; i++)
        {
            int value = data[i];
            std::cout<<value<<" ";
        }
        std::cout<<std::endl;
    }

三.形態(tài)學(xué)操作—腐蝕

腐蝕就是清除掉圖像的一些毛刺和細(xì)節(jié),腐蝕一般可以用來消除噪點(diǎn),分割出獨(dú)立的圖像元素等。其本質(zhì)上也是一種空間濾波,設(shè)定一個(gè)掩模,掩模中心逐次滑過每一個(gè)像素點(diǎn),當(dāng)前像素點(diǎn)(即掩模中心所對(duì)應(yīng)的位置)的值設(shè)為掩模覆蓋區(qū)域中像素的最小值。

腐蝕原理

膨脹或者腐蝕操作就是將圖像(或圖像的一部分區(qū)域,我們稱之為圖像A)與結(jié)構(gòu)元素(我們稱之為卷積核B)進(jìn)行卷積。核可以是任何的形狀和大小,擁有一個(gè)單獨(dú)定義出來的參考點(diǎn),我們稱其為錨點(diǎn)(anchorpoin)。多數(shù)情況下,核是一個(gè)小的中間帶有參考點(diǎn)和實(shí)心正方形或者圓盤,可以把核視為模板或者掩碼。掩膜中心位置的像素點(diǎn)是否與周圍領(lǐng)域的像素點(diǎn)顏色一樣(即是否是白色點(diǎn),即像素值是否為255),若一致,則保留,不一致則該點(diǎn)變?yōu)楹谏ㄖ导礊?)。

腐蝕函數(shù)API接口

dst=cv2.erode(  
        InputArray src,  
        OutputArray dst,  
        InputArray kernel,  
        Point anchor=Point(-1,-1),  
        int iterations=1,  
        int borderType=BORDER_CONSTANT,  
        const Scalar& borderValue=morphologyDefaultBorderValue()  
     );  

參數(shù)說明:

第一個(gè)參數(shù),InputArray類型的src,輸入圖像,即源圖像,填Mat類的對(duì)象即可。圖像通道的數(shù)量可以是任意的,但圖像深度應(yīng)為CV_8U,CV_16U,CV_16S,CV_32F或 CV_64F其中之一。

第二個(gè)參數(shù),OutputArray類型的dst,即目標(biāo)圖像,需要和源圖片有一樣的尺寸和類型。

第三個(gè)參數(shù),InputArray類型的kernel,膨脹操作的核。若為NULL時(shí),表示的是使用參考點(diǎn)位于中心3x3的核。

我們一般使用函數(shù) getStructuringElement配合這個(gè)參數(shù)的使用。getStructuringElement函數(shù)會(huì)返回指定形狀和尺寸的結(jié)構(gòu)元素(內(nèi)核矩陣)。

其中,getStructuringElement函數(shù)的第一個(gè)參數(shù)表示內(nèi)核的形狀,我們可以選擇如下三種形狀之一:

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

而getStructuringElement函數(shù)的第二和第三個(gè)參數(shù)分別是內(nèi)核的尺寸以及錨點(diǎn)的位置。

我們一般在調(diào)用erode以及dilate函數(shù)之前,先定義一個(gè)Mat類型的變量來獲得getStructuringElement函數(shù)的返回值。對(duì)于錨點(diǎn)的位置,有默認(rèn)值Point(-1,-1),表示錨點(diǎn)位于中心。且需要注意,十字形的element形狀唯一依賴于錨點(diǎn)的位置。而在其他情況下,錨點(diǎn)只是影響了形態(tài)學(xué)運(yùn)算結(jié)果的偏移。

getStructuringElement函數(shù)相關(guān)的調(diào)用示例代碼如下:

調(diào)用這樣之后,我們便可以在接下來調(diào)用erode或dilate函數(shù)時(shí),第三個(gè)參數(shù)填保存了getStructuringElement返回值的Mat類型變量。對(duì)應(yīng)于我們上面的示例,就是填element變量。

第四個(gè)參數(shù),Point類型的anchor,錨的位置,其有默認(rèn)值(-1,-1),表示錨位于中心。

第五個(gè)參數(shù),int類型的iterations,迭代使用erode()函數(shù)的次數(shù),默認(rèn)值為1。

第六個(gè)參數(shù),int類型的borderType,用于推斷圖像外部像素的某種邊界模式。注意它有默認(rèn)值BORDER_DEFAULT。

第七個(gè)參數(shù),const Scalar&類型的borderValue,當(dāng)邊界為常數(shù)時(shí)的邊界值,有默認(rèn)值morphologyDefaultBorderValue(),一般我們不用去管他。需要用到它時(shí),可以看官方文檔中的createMorphologyFilter()函數(shù)得到更詳細(xì)的解釋。

使用erode函數(shù),一般我們只需要填前面的三個(gè)參數(shù),后面的四個(gè)參數(shù)都有默認(rèn)值。而且往往結(jié)合getStructuringElement一起使用。

腐蝕的具體操作是:用一個(gè)結(jié)構(gòu)元素(一般是3×3的大小)掃描圖像中的每一個(gè)像素,用結(jié)構(gòu)元素中的每一個(gè)像素與其覆蓋的像素做“與”操作,如果都為1,則該像素為1,否則為0。

膨脹的具體操作是:用一個(gè)結(jié)構(gòu)元素(一般是3×3的大小)掃描圖像中的每一個(gè)像素,用結(jié)構(gòu)元素中的每一個(gè)像素與其覆蓋的像素做“與”操作,如果都為0,則該像素為0,否則為1。

代碼實(shí)現(xiàn):

#include"stdafx.h"
#include <opencv2/opencv.hpp>
#include <iostream>
#include<stdio.h>
using namespace cv;
using namespace std;
 
 
int _tmain(int argc, _TCHAR* argv[])
{
	Mat image1 = imread("F:/photo/qx.jpg", 1);
	namedWindow("input_picture1");
	imshow("input_picture1", image1);
 
	Mat image2;
	Mat image3;
	cvtColor(image1, image2, COLOR_RGB2GRAY);
	namedWindow("input_picture2");
	imshow("input_picture2", image2);
 
	threshold(image2, image3, 65, 255, THRESH_BINARY);
	namedWindow("input_picture3");
	imshow("input_picture3", image3);
 
	Mat eroded;
	erode(image3, eroded, Mat());
	namedWindow("erode");
	imshow("erode", eroded);
 
	Mat dilated;
	dilate(image3, dilated, Mat());
	namedWindow("dilate");
	imshow("dilate", dilated);
 
	waitKey(0);
	return 0;
}

圖像處理效果

原圖和灰度圖

灰度圖和二值化圖: 

 二值化圖像腐蝕膨脹效果:

到此這篇關(guān)于OpenCV圖像處理之實(shí)現(xiàn)圖像膨脹腐蝕操作的文章就介紹到這了,更多相關(guān)OpenCV圖像膨脹腐蝕內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 深入解析C++編程中基類與基類的繼承的相關(guān)知識(shí)

    深入解析C++編程中基類與基類的繼承的相關(guān)知識(shí)

    這篇文章主要介紹了C++編程中基類與基類的繼承的相關(guān)知識(shí),包括多個(gè)基類繼承與虛擬基類等重要知識(shí),需要的朋友可以參考下
    2016-01-01
  • 關(guān)于C語言函數(shù)strstr()的分析以及實(shí)現(xiàn)

    關(guān)于C語言函數(shù)strstr()的分析以及實(shí)現(xiàn)

    以下是對(duì)C語言中strstr()函數(shù)的使用進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以參考下
    2013-07-07
  • C++中指針函數(shù)與函數(shù)指針的使用

    C++中指針函數(shù)與函數(shù)指針的使用

    今天小編就為大家分享一篇關(guān)于C++中指針函數(shù)與函數(shù)指針的使用,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • C語言超詳細(xì)講解getchar函數(shù)的使用

    C語言超詳細(xì)講解getchar函數(shù)的使用

    C 庫函數(shù) int getchar(void) 從標(biāo)準(zhǔn)輸入 stdin 獲取一個(gè)字符(一個(gè)無符號(hào)字符)。這等同于 getc 帶有 stdin 作為參數(shù),下面讓我們?cè)敿?xì)來看看
    2022-05-05
  • C++如何計(jì)算二進(jìn)制數(shù)中1的個(gè)數(shù)

    C++如何計(jì)算二進(jìn)制數(shù)中1的個(gè)數(shù)

    這篇文章主要介紹了C++如何計(jì)算二進(jìn)制數(shù)中1的個(gè)數(shù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • Linux UDP服務(wù)端和客戶端程序的實(shí)現(xiàn)

    Linux UDP服務(wù)端和客戶端程序的實(shí)現(xiàn)

    這篇文章主要介紹了Linux UDP服務(wù)端和客戶端程序的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • 基于OpenCv的運(yùn)動(dòng)物體檢測(cè)算法

    基于OpenCv的運(yùn)動(dòng)物體檢測(cè)算法

    這篇文章主要為大家詳細(xì)介紹了基于OpenCv的運(yùn)動(dòng)物體檢測(cè)算法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • C++中try throw catch異常處理的用法示例

    C++中try throw catch異常處理的用法示例

    這篇文章主要給大家介紹了關(guān)于C++中try throw catch異常處理的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者使用C++具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • Qt實(shí)現(xiàn)http服務(wù)的示例代碼

    Qt實(shí)現(xiàn)http服務(wù)的示例代碼

    這篇文章將為大家詳細(xì)講解有關(guān)Qt如何實(shí)現(xiàn)http服務(wù),小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲
    2023-04-04
  • C++ 基類指針和子類指針相互賦值的實(shí)現(xiàn)方法

    C++ 基類指針和子類指針相互賦值的實(shí)現(xiàn)方法

    下面小編就為大家?guī)硪黄狢++ 基類指針和子類指針相互賦值的實(shí)現(xiàn)方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-12-12

最新評(píng)論