您好,登錄后才能下訂單哦!
本篇內容主要講解“OpenCV怎么實現圖像距離變換”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“OpenCV怎么實現圖像距離變換”吧!
圖像中兩個像素之間的距離有多種定義方式,圖像處理中常用的距離有歐式距離、街區距離和棋盤距離
歐式距離 略
兩個像素點X方向和Y方向的距離之和。歐式距離表示的是從一個像素點到另一個像素點的最短距離,然而有時我們并不能以兩個點之間連線的方向前進,例如在一個城市內兩點之間的連線可能存在障礙物的阻礙,因此從一個點到另一個點需要沿著街道行走,因此這種距離的度量方式被稱為街區距離。街區距離就是由一個像素點到另一個像素點需要沿著X方向和Y方向一共行走的距離,數學表示形式如式所示。
兩個像素點X方向距離和Y方向距離的最大值。與街區距離相似,棋盤距離也是假定兩個像素點之間不能夠沿著連線方向靠近,像素點只能沿著X方向和Y方向移動,但是棋盤距離并不是表示由一個像素點移動到另一個像素點之間的距離,而是表示兩個像素點移動到同一行或者同一列時需要移動的最大距離,數學表示形式如式所示。
CV_EXPORTS_AS(distanceTransformWithLabels) void distanceTransform( InputArray src, OutputArray dst, OutputArray labels, int distanceType, int maskSize, int labelType = DIST_LABEL_CCOMP );
src:輸入圖像,數據類型為CV_8U的單通道圖像
dst:輸出圖像,與輸入圖像具有相同的尺寸,數據類型為CV_8U或者CV_32F的單通道圖像。
labels:二維的標簽數組(離散Voronoi圖),與輸入圖像具有相同的尺寸,數據類型為CV_32S的單通道數據。
distanceType:選擇計算兩個像素之間距離方法的標志,其常用的距離度量方法在表6-1給出。
maskSize:距離變換掩碼矩陣的大小,參數可以選擇的尺寸為DIST_MASK_3(3×3)和DIST_MASK_5(5×5).
labelType:要構建的標簽數組的類型,可以選擇的參數在表給出。
該函數用于實現圖像的距離變換,即統計圖像中所有像素距離0像素的最小距離。
函數的第一個參數為待距離變換的輸入圖像,輸入圖像要求必須是CV_8U的單通道圖像。
函數第二個參數是原圖像距離變換后的輸出圖像,與輸入圖像具有相同的尺寸,圖像中每個像素值表示該像素在原圖像中距離0像素的最小距離。由于圖像的尺寸可能大于256,因此圖像中某個像素距離0像素的最近距離有可能會大于255,為了能夠正確的統計出每一個像素距離0像素的最小距離,輸出圖像的數據類型可以選擇CV_8U或者CV_32F。
函數第三個參數是原圖像的Voronoi圖,輸出圖像是數據類型為CV_32S單通道圖像,圖像尺寸與輸入圖像相同。
函數第四個參數是距離變換過程中使用的距離種類,常用的距離為歐式距離(DIST_L2)、街區距離(DIST_L1)和棋盤距離(DIST_C)。
函數第五個參數是求取路徑時候的掩碼尺寸,該尺寸與選擇的距離種類有著密切的關系,當選擇使用街區距離時,掩碼尺寸選擇3×3還是5×5對計算結果都沒有影響,因此為了加快函數運算速度,默認選擇掩碼尺寸為3×3;當選擇歐式距離時,掩碼尺寸為3×3時是粗略的計算兩個像素之間的距離,而當掩碼尺寸為5×5時是精確的計算兩個像素之間的距離,精確計算與粗略計算兩者之間存在著較大的差異,因此在使用歐式距離時推薦使用5×5掩碼;當選擇棋盤距離時,掩碼的尺寸對計算結果也沒有影響,因此可以隨意選擇。
函數的最后一個參數為構建標簽數組的類型,當labelTypeDIST_LABEL_CCOMP時,該函數會自動在輸入圖像中找到0像素的連通分量,并用不同的標簽標記它們。當labelTypeDIST_LABEL_CCOMP時,該函數掃描輸入圖像并用不同的標簽標記所有0像素。
該函數原型在對圖像進行距離變換的同時會生成Voronoi圖,但是有時只是為了實現對圖像的距離變換,并不需要使用Voronoi圖,而使用該函數必須要求創建一個Mat類變量用于存放Voronoi圖,占用了內存資源,因此distanceTransform()函數的第二種函數原型中取消了生成Voronoi圖,只輸出距離變換后的圖像
void distanceTransform( InputArray src, OutputArray dst, int distanceType, int maskSize, int dstType=CV_32F);
src:輸入圖像,數據類型為CV_8U的單通道圖像
dst:輸出圖像,與輸入圖像具有相同的尺寸,數據類型為CV_8U或者CV_32F的單通道圖像。
distanceType:選擇計算兩個像素之間距離方法的標志,其常用的距離度量方法在表6-1給出。
maskSize:距離變換掩碼矩陣的大小,參數可以選擇的尺寸為DIST_MASK_3(3×3)和DIST_MASK_5(5×5)。
dstType:輸出圖像的數據類型,可以是CV_8U或者CV_32F。
該函數原型中的主要參數含義與前一種函數原型相同,前兩個參數為輸入圖像和輸出圖像,第三個參數和為距離變換過程中使用的距離種類。函數中第四個參數是距離變換掩碼矩陣的大小,由于街區距離(Dist_L1)和棋盤距離(Dist_C)對掩模尺寸沒有要求,因此該參數在選擇街區距離和棋盤距離時被強制設置為3,同樣掩模尺寸的大小對歐式距離(Dist_L2)計算的精度有影響,為了獲取較為精確的時,一般使用5×5的掩模矩陣。函數最后一個參數是輸出圖像的數據類型,雖然可以在CV_8U和CV_32F兩個類型中任意選擇,但是圖像輸出時實際的數據類型與距離變換時選擇的距離種類有著密切的聯系,CV_8U只能使用在計算街區距離的條件下,當計算歐式距離和棋盤距離時,即使該參數設置為CV_8U,實際的輸出圖像的數據類型也是CV_32F。
// // 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); // 轉為二值圖像 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; }
到此,相信大家對“OpenCV怎么實現圖像距離變換”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。