c/c++中opencv實(shí)現(xiàn)腐蝕的示例代碼
圖像腐蝕 (Erosion) 是形態(tài)學(xué)圖像處理中的一種基本操作。它通常用于去除圖像中的小型噪聲、分離連接的物體以及細(xì)化二值圖像中的物體。本文將詳細(xì)介紹腐蝕的原理,并演示如何使用 C++ 和 OpenCV 庫(kù)來(lái)實(shí)現(xiàn)圖像腐蝕。
什么是圖像腐蝕?
圖像腐蝕可以被看作是用一個(gè)特定的結(jié)構(gòu)元素(也稱為核或掩模)“探測(cè)”或“掃描”輸入圖像的過(guò)程。對(duì)于二值圖像,如果結(jié)構(gòu)元素下的所有像素都為前景像素(通常為白色,值為1或255),則輸出圖像中結(jié)構(gòu)元素錨點(diǎn)對(duì)應(yīng)的像素才被置為前景像素,否則置為背景像素(通常為黑色,值為0)。對(duì)于灰度圖像,輸出像素的值是結(jié)構(gòu)元素覆蓋區(qū)域內(nèi)所有像素的最小值。
簡(jiǎn)單來(lái)說(shuō),腐蝕操作會(huì):
- 縮小 亮色區(qū)域(前景)。
- 擴(kuò)大 暗色區(qū)域(背景)。
- 消除小的、孤立的亮色噪點(diǎn)。
其效果就像是用結(jié)構(gòu)元素“腐蝕”掉前景物體的邊界。
結(jié)構(gòu)元素 (Kernel)
結(jié)構(gòu)元素是一個(gè)小的二值矩陣(或灰度矩陣),它定義了腐蝕操作的鄰域范圍和形狀。結(jié)構(gòu)元素的中心點(diǎn)通常被稱為“錨點(diǎn)”。OpenCV 提供了 cv::getStructuringElement()
函數(shù)來(lái)方便地創(chuàng)建常見的結(jié)構(gòu)元素。
常用的結(jié)構(gòu)元素形狀包括:
cv::MORPH_RECT
: 矩形cv::MORPH_ELLIPSE
: 橢圓形cv::MORPH_CROSS
: 十字形
// 創(chuàng)建一個(gè) 5x5 大小的矩形結(jié)構(gòu)元素 cv::Mat kernel_rect = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(5, 5)); // 創(chuàng)建一個(gè) 5x5 大小的橢圓形結(jié)構(gòu)元素 cv::Mat kernel_ellipse = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(5, 5)); // 創(chuàng)建一個(gè) 5x5 大小的十字形結(jié)構(gòu)元素 cv::Mat kernel_cross = cv::getStructuringElement(cv::MORPH_CROSS, cv::Size(5, 5));
結(jié)構(gòu)元素的大小和形狀對(duì)腐蝕結(jié)果有顯著影響。
OpenCV 中的 cv::erode() 函數(shù)
OpenCV 提供了 cv::erode()
函數(shù)來(lái)實(shí)現(xiàn)圖像腐蝕。
函數(shù)原型:
void cv::erode( cv::InputArray src, // 輸入圖像 cv::OutputArray dst, // 輸出圖像 cv::InputArray kernel, // 用于腐蝕的結(jié)構(gòu)元素 cv::Point anchor = cv::Point(-1,-1), // 結(jié)構(gòu)元素內(nèi)錨點(diǎn)的位置。默認(rèn)值 (-1,-1) 表示錨點(diǎn)在核中心。 int iterations = 1, // 腐蝕操作迭代次數(shù) int borderType = cv::BORDER_CONSTANT, // 像素外推方法 const cv::Scalar& borderValue = cv::morphologyDefaultBorderValue() //邊界不變時(shí)的邊界值 );
參數(shù)說(shuō)明:
src
: 輸入圖像,可以是任意通道數(shù)的圖像,但深度應(yīng)為CV_8U
,CV_16U
,CV_16S
,CV_32F
或CV_64F
。dst
: 輸出圖像,與src
具有相同的大小和類型。kernel
: 結(jié)構(gòu)元素。如果傳入一個(gè)空的cv::Mat()
,則默認(rèn)使用一個(gè) 3x3 的矩形核。anchor
: 錨點(diǎn)位置。默認(rèn)值cv::Point(-1,-1)
表示錨點(diǎn)在結(jié)構(gòu)元素的中心。iterations
: 腐蝕操作執(zhí)行的次數(shù)。多次迭代等同于使用一個(gè)由原始核通過(guò)自身膨脹(相應(yīng)次數(shù))得到的更大的核。borderType
: 用于推斷圖像外部像素的邊界模式。borderValue
: 當(dāng)borderType
為cv::BORDER_CONSTANT
時(shí)使用的邊界值。
C++ 代碼示例
下面是一個(gè)完整的 C++ 示例,演示了如何加載圖像并對(duì)其進(jìn)行腐蝕操作:
#include <opencv2/opencv.hpp> #include <iostream> int main(int argc, char** argv) { // 1. 加載圖像 // 將 "your_image_path.png" 替換為你的圖像路徑 cv::Mat srcImage = cv::imread("your_image_path.png", cv::IMREAD_COLOR); // 檢查圖像是否成功加載 if (srcImage.empty()) { std::cerr << "錯(cuò)誤: 無(wú)法加載圖像!" << std::endl; return -1; } // 2. 創(chuàng)建腐蝕后的輸出圖像 cv::Mat erodedImage; // 3. 定義結(jié)構(gòu)元素 (核) // 嘗試不同的形狀和大小 // int erosion_size = 3; // 核大小,可以調(diào)整 // cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, // cv::Size(2 * erosion_size + 1, 2 * erosion_size + 1), // cv::Point(erosion_size, erosion_size)); // 使用一個(gè)簡(jiǎn)單的 5x5 矩形核 cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(5, 5)); // 你也可以嘗試: // cv::Mat element = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(5, 5)); // cv::Mat element = cv::getStructuringElement(cv::MORPH_CROSS, cv::Size(5, 5)); // 如果不指定核,OpenCV 會(huì)默認(rèn)使用一個(gè) 3x3 的矩形核 // cv::Mat element; // 使用默認(rèn) 3x3 核 // 4. 執(zhí)行腐蝕操作 // 可以指定迭代次數(shù),例如 iterations = 2 int iterations = 1; cv::erode(srcImage, erodedImage, element, cv::Point(-1,-1), iterations); // 5. 顯示原始圖像和腐蝕后的圖像 cv::imshow("原始圖像", srcImage); cv::imshow("腐蝕后的圖像", erodedImage); // 6. 等待用戶按鍵,然后關(guān)閉窗口 cv::waitKey(0); cv::destroyAllWindows(); return 0; }
編譯和運(yùn)行說(shuō)明 (以 g++ 為例):
g++ your_source_file.cpp -o erode_example $(pkg-config --cflags --libs opencv4) ./erode_example
(請(qǐng)確保你已安裝 OpenCV 并配置好 pkg-config,如果使用 OpenCV 3,將 opencv4
替換為 opencv
)
代碼解析
#include <opencv2/opencv.hpp>
: 包含了 OpenCV 的主要頭文件。cv::imread("your_image_path.png", cv::IMREAD_COLOR)
: 加載指定路徑的彩色圖像。你需要將"your_image_path.png"
替換為實(shí)際的圖像文件路徑。srcImage.empty()
: 檢查圖像是否成功加載。cv::getStructuringElement(cv::MORPH_RECT, cv::Size(5, 5))
: 創(chuàng)建一個(gè) 5x5 大小的矩形結(jié)構(gòu)元素。你可以修改形狀 (MORPH_ELLIPSE
,MORPH_CROSS
) 和大小 (cv::Size
) 來(lái)觀察不同的效果。cv::erode(srcImage, erodedImage, element, cv::Point(-1,-1), iterations)
: 對(duì)srcImage
應(yīng)用腐蝕操作,使用element
作為結(jié)構(gòu)元素,迭代iterations
次,并將結(jié)果存儲(chǔ)在erodedImage
中。cv::Point(-1,-1)
表示錨點(diǎn)在核的中心。cv::imshow()
: 顯示原始圖像和處理后的圖像。cv::waitKey(0)
: 等待用戶按下任意鍵。cv::destroyAllWindows()
: 關(guān)閉所有 OpenCV 創(chuàng)建的窗口。
腐蝕的效果和應(yīng)用場(chǎng)景
- 去除小的獨(dú)立噪聲點(diǎn): 對(duì)于二值圖像中的“椒鹽噪聲”中的“鹽”點(diǎn)(孤立的白色像素點(diǎn)),腐蝕操作非常有效。
- 細(xì)化物體輪廓: 使二值圖像中前景物體的尺寸變小,線條變細(xì)。
- 分離物體: 如果兩個(gè)物體之間有細(xì)微的連接,腐蝕操作可以斷開這些連接,從而將它們分離。
- 獲取物體的核心區(qū)域: 多次腐蝕可以逐步剝離物體的外層像素,最終得到物體的核心部分。
- 在其他更復(fù)雜形態(tài)學(xué)操作(如開運(yùn)算、閉運(yùn)算)中作為基礎(chǔ)步驟。
可調(diào)整的參數(shù)及其影響
- 結(jié)構(gòu)元素的大小:
- 較小的結(jié)構(gòu)元素產(chǎn)生的腐蝕效果較弱,對(duì)圖像的改變較小。
- 較大的結(jié)構(gòu)元素產(chǎn)生的腐蝕效果較強(qiáng),會(huì)更顯著地縮小或消除物體。
- 結(jié)構(gòu)元素的形狀:
- 矩形核對(duì)水平和垂直方向的腐蝕程度相同。
- 線型核(例如,一個(gè)水平或垂直的細(xì)長(zhǎng)矩形)會(huì)主要在與核垂直的方向上腐蝕物體。例如,水平線核會(huì)使物體在垂直方向上變細(xì)。
- 十字形核和橢圓形核根據(jù)其形狀特性進(jìn)行腐蝕。
- 迭代次數(shù) (
iterations
):- 增加迭代次數(shù)會(huì)增強(qiáng)腐蝕效果,類似于使用一個(gè)更大的結(jié)構(gòu)元素(但不完全相同,多次小核迭代與一次大核迭代在邊界處理上可能有細(xì)微差別)。
總結(jié)
圖像腐蝕是形態(tài)學(xué)圖像處理中一個(gè)強(qiáng)大且基礎(chǔ)的工具。通過(guò)選擇合適的結(jié)構(gòu)元素大小、形狀以及迭代次數(shù),可以有效地修改圖像中物體的形狀和大小,以達(dá)到去噪、分割和特征提取等目的。OpenCV 的 cv::erode()
函數(shù)為我們提供了一個(gè)簡(jiǎn)單易用的接口來(lái)實(shí)現(xiàn)這一功能。鼓勵(lì)讀者多多嘗試不同的參數(shù)組合,觀察它們對(duì)圖像處理結(jié)果的具體影響。
到此這篇關(guān)于c/c++中opencv實(shí)現(xiàn)腐蝕的示例代碼的文章就介紹到這了,更多相關(guān)opencv 腐蝕內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于C++語(yǔ)言實(shí)現(xiàn)機(jī)動(dòng)車違章處罰管理系統(tǒng)
這篇文章主要介紹了基于C++語(yǔ)言實(shí)現(xiàn)機(jī)動(dòng)車違章處罰管理系統(tǒng)的相關(guān)資料,需要的朋友可以參考下2016-07-07C語(yǔ)言實(shí)現(xiàn)時(shí)區(qū)轉(zhuǎn)換函數(shù)的實(shí)例
這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)時(shí)區(qū)轉(zhuǎn)換函數(shù)的實(shí)例的相關(guān)資料,這里分析需求并提供實(shí)現(xiàn)代碼,需要的朋友可以參考下2017-08-08C/C++多參數(shù)函數(shù)參數(shù)的計(jì)算順序與壓棧順序的示例代碼
這篇文章主要介紹了C/C++多參數(shù)函數(shù)參數(shù)的計(jì)算順序與壓棧順序,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06C語(yǔ)言數(shù)學(xué)問(wèn)題與簡(jiǎn)單DP01背包問(wèn)題詳解
這篇文章主要介紹了C語(yǔ)言數(shù)學(xué)問(wèn)題買不到的數(shù)目、螞蟻感冒、飲料換購(gòu)與簡(jiǎn)單DP01背包問(wèn)題的解決,屬于藍(lán)橋杯省賽中的題目,感興趣的同學(xué)來(lái)看看吧2022-04-04C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)與算法之排序總結(jié)(一)
這篇文章主要介紹了數(shù)據(jù)結(jié)構(gòu)與算法中的插入類和交換類的各種排序,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2021-12-12嵌入式C語(yǔ)言輕量級(jí)程序架構(gòu)內(nèi)核編寫
這篇文章主要介紹了嵌入式C語(yǔ)言輕量級(jí)程序架構(gòu)內(nèi)核編寫,文章將讓大家學(xué)到輕量級(jí)程序架構(gòu)的內(nèi)核實(shí)現(xiàn)原理、輕量級(jí)程序架構(gòu)的設(shè)計(jì)思想、了解單片機(jī)常用的程序架構(gòu)等更多C語(yǔ)言輕量級(jí)程序架構(gòu)相關(guān)內(nèi)容,需要的朋友可以參考一下2022-03-03求素?cái)?shù),用vector存儲(chǔ)的實(shí)現(xiàn)方法
本篇文章是對(duì)求素?cái)?shù),用vector存儲(chǔ)的實(shí)現(xiàn)方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05