OpenCV實(shí)現(xiàn)圖像距離變換
圖像中兩個(gè)像素之間的距離有多種定義方式,圖像處理中常用的距離有歐式距離、街區(qū)距離和棋盤距離
歐式距離 略
街區(qū)距離
兩個(gè)像素點(diǎn)X方向和Y方向的距離之和。歐式距離表示的是從一個(gè)像素點(diǎn)到另一個(gè)像素點(diǎn)的最短距離,然而有時(shí)我們并不能以兩個(gè)點(diǎn)之間連線的方向前進(jìn),例如在一個(gè)城市內(nèi)兩點(diǎn)之間的連線可能存在障礙物的阻礙,因此從一個(gè)點(diǎn)到另一個(gè)點(diǎn)需要沿著街道行走,因此這種距離的度量方式被稱為街區(qū)距離。街區(qū)距離就是由一個(gè)像素點(diǎn)到另一個(gè)像素點(diǎn)需要沿著X方向和Y方向一共行走的距離,數(shù)學(xué)表示形式如式所示。
棋盤距離
兩個(gè)像素點(diǎn)X方向距離和Y方向距離的最大值。與街區(qū)距離相似,棋盤距離也是假定兩個(gè)像素點(diǎn)之間不能夠沿著連線方向靠近,像素點(diǎn)只能沿著X方向和Y方向移動(dòng),但是棋盤距離并不是表示由一個(gè)像素點(diǎn)移動(dòng)到另一個(gè)像素點(diǎn)之間的距離,而是表示兩個(gè)像素點(diǎn)移動(dòng)到同一行或者同一列時(shí)需要移動(dòng)的最大距離,數(shù)學(xué)表示形式如式所示。
CV_EXPORTS_AS(distanceTransformWithLabels) void distanceTransform( InputArray src, OutputArray dst, OutputArray labels, int distanceType, int maskSize, int labelType = DIST_LABEL_CCOMP );
- src:輸入圖像,數(shù)據(jù)類型為CV_8U的單通道圖像
- dst:輸出圖像,與輸入圖像具有相同的尺寸,數(shù)據(jù)類型為CV_8U或者CV_32F的單通道圖像。
- labels:二維的標(biāo)簽數(shù)組(離散Voronoi圖),與輸入圖像具有相同的尺寸,數(shù)據(jù)類型為CV_32S的單通道數(shù)據(jù)。
- distanceType:選擇計(jì)算兩個(gè)像素之間距離方法的標(biāo)志,其常用的距離度量方法在表6-1給出。
- maskSize:距離變換掩碼矩陣的大小,參數(shù)可以選擇的尺寸為DIST_MASK_3(3×3)和DIST_MASK_5(5×5).
- labelType:要構(gòu)建的標(biāo)簽數(shù)組的類型,可以選擇的參數(shù)在表給出。
- 該函數(shù)用于實(shí)現(xiàn)圖像的距離變換,即統(tǒng)計(jì)圖像中所有像素距離0像素的最小距離。
- 函數(shù)的第一個(gè)參數(shù)為待距離變換的輸入圖像,輸入圖像要求必須是CV_8U的單通道圖像。
- 函數(shù)第二個(gè)參數(shù)是原圖像距離變換后的輸出圖像,與輸入圖像具有相同的尺寸,圖像中每個(gè)像素值表示該像素在原圖像中距離0像素的最小距離。由于圖像的尺寸可能大于256,因此圖像中某個(gè)像素距離0像素的最近距離有可能會(huì)大于255,為了能夠正確的統(tǒng)計(jì)出每一個(gè)像素距離0像素的最小距離,輸出圖像的數(shù)據(jù)類型可以選擇CV_8U或者CV_32F。
- 函數(shù)第三個(gè)參數(shù)是原圖像的Voronoi圖,輸出圖像是數(shù)據(jù)類型為CV_32S單通道圖像,圖像尺寸與輸入圖像相同。
- 函數(shù)第四個(gè)參數(shù)是距離變換過(guò)程中使用的距離種類,常用的距離為歐式距離(DIST_L2)、街區(qū)距離(DIST_L1)和棋盤距離(DIST_C)。
- 函數(shù)第五個(gè)參數(shù)是求取路徑時(shí)候的掩碼尺寸,該尺寸與選擇的距離種類有著密切的關(guān)系,當(dāng)選擇使用街區(qū)距離時(shí),掩碼尺寸選擇3×3還是5×5對(duì)計(jì)算結(jié)果都沒(méi)有影響,因此為了加快函數(shù)運(yùn)算速度,默認(rèn)選擇掩碼尺寸為3×3;當(dāng)選擇歐式距離時(shí),掩碼尺寸為3×3時(shí)是粗略的計(jì)算兩個(gè)像素之間的距離,而當(dāng)掩碼尺寸為5×5時(shí)是精確的計(jì)算兩個(gè)像素之間的距離,精確計(jì)算與粗略計(jì)算兩者之間存在著較大的差異,因此在使用歐式距離時(shí)推薦使用5×5掩碼;當(dāng)選擇棋盤距離時(shí),掩碼的尺寸對(duì)計(jì)算結(jié)果也沒(méi)有影響,因此可以隨意選擇。
- 函數(shù)的最后一個(gè)參數(shù)為構(gòu)建標(biāo)簽數(shù)組的類型,當(dāng)labelTypeDIST_LABEL_CCOMP時(shí),該函數(shù)會(huì)自動(dòng)在輸入圖像中找到0像素的連通分量,并用不同的標(biāo)簽標(biāo)記它們。當(dāng)labelTypeDIST_LABEL_CCOMP時(shí),該函數(shù)掃描輸入圖像并用不同的標(biāo)簽標(biāo)記所有0像素。
該函數(shù)原型在對(duì)圖像進(jìn)行距離變換的同時(shí)會(huì)生成Voronoi圖,但是有時(shí)只是為了實(shí)現(xiàn)對(duì)圖像的距離變換,并不需要使用Voronoi圖,而使用該函數(shù)必須要求創(chuàng)建一個(gè)Mat類變量用于存放Voronoi圖,占用了內(nèi)存資源,因此distanceTransform()函數(shù)的第二種函數(shù)原型中取消了生成Voronoi圖,只輸出距離變換后的圖像
void distanceTransform( InputArray src, OutputArray dst, int distanceType, int maskSize, int dstType=CV_32F);
- src:輸入圖像,數(shù)據(jù)類型為CV_8U的單通道圖像
- dst:輸出圖像,與輸入圖像具有相同的尺寸,數(shù)據(jù)類型為CV_8U或者CV_32F的單通道圖像。
- distanceType:選擇計(jì)算兩個(gè)像素之間距離方法的標(biāo)志,其常用的距離度量方法在表6-1給出。
- maskSize:距離變換掩碼矩陣的大小,參數(shù)可以選擇的尺寸為DIST_MASK_3(3×3)和DIST_MASK_5(5×5)。
- dstType:輸出圖像的數(shù)據(jù)類型,可以是CV_8U或者CV_32F。
該函數(shù)原型中的主要參數(shù)含義與前一種函數(shù)原型相同,前兩個(gè)參數(shù)為輸入圖像和輸出圖像,第三個(gè)參數(shù)和為距離變換過(guò)程中使用的距離種類。函數(shù)中第四個(gè)參數(shù)是距離變換掩碼矩陣的大小,由于街區(qū)距離(Dist_L1)和棋盤距離(Dist_C)對(duì)掩模尺寸沒(méi)有要求,因此該參數(shù)在選擇街區(qū)距離和棋盤距離時(shí)被強(qiáng)制設(shè)置為3,同樣掩模尺寸的大小對(duì)歐式距離(Dist_L2)計(jì)算的精度有影響,為了獲取較為精確的時(shí),一般使用5×5的掩模矩陣。函數(shù)最后一個(gè)參數(shù)是輸出圖像的數(shù)據(jù)類型,雖然可以在CV_8U和CV_32F兩個(gè)類型中任意選擇,但是圖像輸出時(shí)實(shí)際的數(shù)據(jù)類型與距離變換時(shí)選擇的距離種類有著密切的聯(lián)系,CV_8U只能使用在計(jì)算街區(qū)距離的條件下,當(dāng)計(jì)算歐式距離和棋盤距離時(shí),即使該參數(shù)設(shè)置為CV_8U,實(shí)際的輸出圖像的數(shù)據(jù)類型也是CV_32F。
簡(jiǎn)單示例
// // Created by smallflyfly on 2021/6/15. // #include "opencv2/opencv.hpp" #include "opencv2/highgui.hpp" #include "utils.hpp" #include <iostream> using namespace std; using namespace cv; int main() { // 自定義矩陣 Mat a = (Mat_<uchar>(5, 5) << 1,1,1,1,1, 1,1,1,1,1, 1,1,0,1,1, 1,1,1,1,1, 1,1,1,1,1 ); Mat distL1, distL2, distC; distanceTransform(a, distL1, DIST_L1, 3, CV_8U); distanceTransform(a, distL2, DIST_L2, 5, CV_8U); distanceTransform(a, distC, DIST_C, 3, CV_8U); cout << distL1 << endl; cout << distL2 << endl; cout << distC << endl; Mat im = imread("test.jpg", IMREAD_GRAYSCALE); if (im.empty()) { cerr << "image file read error" << endl; return -1; } resize(im, im, Size(0, 0), 0.5, 0.5); // 轉(zhuǎn)為二值圖像 Mat im1, im2; threshold(im, im1, 125 ,255, THRESH_BINARY); threshold(im, im2, 125, 255, THRESH_BINARY_INV); Mat dist1, dist2; distanceTransform(im1, dist1, DIST_L1, 3, CV_32F); distanceTransform(im2, dist2, DIST_L1, 3, CV_8U); showImage("im1", im1); showImage("dist1", dist1); showImage("im2", im2); showImage("dist2", dist2); waitKey(0); destroyAllWindows(); return 0; }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
VScode配置C語(yǔ)言環(huán)境完整版(親測(cè)可用)
這篇文章主要介紹了VScode配置C語(yǔ)言環(huán)境完整版,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-08-08利用Matlab編寫(xiě)簡(jiǎn)易版連連看小游戲
連連看作為經(jīng)典的小游戲,一定是很多人的回憶吧。本文將用Matlab實(shí)現(xiàn)這一經(jīng)典的游戲,文中示例代碼具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03使用QGraphicsView實(shí)現(xiàn)氣泡聊天窗口+排雷功能
這篇文章主要介紹了使用QGraphicsView實(shí)現(xiàn)氣泡聊天窗口+排雷,重點(diǎn)給大家介紹使用QWebEngineView控件內(nèi)嵌html+CSS的實(shí)現(xiàn)方式,需要的朋友可以參考下2022-04-04淺析C++模板類型中的原樣轉(zhuǎn)發(fā)和可變參數(shù)的實(shí)現(xiàn)
可變參數(shù)模板(variadic templates)是C++11新增的強(qiáng)大的特性之一,它對(duì)模板參數(shù)進(jìn)行了高度泛化,能表示0到任意個(gè)數(shù)、任意類型的參數(shù),這篇文章主要介紹了C++可變參數(shù)模板的展開(kāi)方式,需要的朋友可以參考下2022-08-08C語(yǔ)言對(duì)組文件處理的相關(guān)函數(shù)小結(jié)
這篇文章主要介紹了C語(yǔ)言對(duì)組文件處理的相關(guān)函數(shù)小結(jié),包括setgrent()函數(shù)和getgrent()函數(shù)以及endgrent()函數(shù),需要的朋友可以參考下2015-08-08Qt學(xué)習(xí)教程之對(duì)話框消失動(dòng)畫(huà)效果
這篇文章主要給大家介紹了關(guān)于Qt學(xué)習(xí)教程之對(duì)話框消失動(dòng)畫(huà)效果的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-07-07