十年網(wǎng)站開發(fā)經(jīng)驗 + 多家企業(yè)客戶 + 靠譜的建站團(tuán)隊
量身定制 + 運營維護(hù)+專業(yè)推廣+無憂售后,網(wǎng)站問題一站解決
本篇文章重點為大家講解一下通過OpenCV實現(xiàn)圖像距離變換,有需要的小伙伴可以參考一下。

堅守“ 做人真誠 · 做事靠譜 · 口碑至上 · 高效敬業(yè) ”的價值觀,專業(yè)網(wǎng)站建設(shè)服務(wù)10余年為成都不銹鋼雕塑小微創(chuàng)業(yè)公司專業(yè)提供成都定制網(wǎng)站營銷網(wǎng)站建設(shè)商城網(wǎng)站建設(shè)手機(jī)網(wǎng)站建設(shè)小程序網(wǎng)站建設(shè)網(wǎng)站改版,從內(nèi)容策劃、視覺設(shè)計、底層架構(gòu)、網(wǎng)頁布局、功能開發(fā)迭代于一體的高端網(wǎng)站建設(shè)服務(wù)。
圖像中兩個像素之間的距離有多種定義方式,圖像處理中常用的距離有歐式距離、街區(qū)距離和棋盤距離,歐式距離略。
兩個像素點X方向和Y方向的距離之和。歐式距離表示的是從一個像素點到另一個像素點的最短距離,然而有時我們并不能以兩個點之間連線的方向前進(jìn),例如在一個城市內(nèi)兩點之間的連線可能存在障礙物的阻礙,因此從一個點到另一個點需要沿著街道行走,因此這種距離的度量方式被稱為街區(qū)距離。街區(qū)距離就是由一個像素點到另一個像素點需要沿著X方向和Y方向一共行走的距離,數(shù)學(xué)表示形式如式所示。
OpenCV實現(xiàn)圖像距離變換詳解OpenCV實現(xiàn)圖像距離變換詳解
兩個像素點X方向距離和Y方向距離的最大值。與街區(qū)距離相似,棋盤距離也是假定兩個像素點之間不能夠沿著連線方向靠近,像素點只能沿著X方向和Y方向移動,但是棋盤距離并不是表示由一個像素點移動到另一個像素點之間的距離,而是表示兩個像素點移動到同一行或者同一列時需要移動的最大距離,數(shù)學(xué)表示形式如式所示。
CV_EXPORTS_AS(distanceTransformWithLabels) void distanceTransform( InputArray src, OutputArray dst,
OutputArray labels, int distanceType, int maskSize,
int labelType = DIST_LABEL_CCOMP );
OpenCV實現(xiàn)圖像距離變換詳解OpenCV實現(xiàn)圖像距離變換詳解
該函數(shù)原型在對圖像進(jìn)行距離變換的同時會生成Voronoi圖,但是有時只是為了實現(xiàn)對圖像的距離變換,并不需要使用Voronoi圖,而使用該函數(shù)必須要求創(chuàng)建一個Mat類變量用于存放Voronoi圖,占用了內(nèi)存資源,因此distanceTransform()函數(shù)的第二種函數(shù)原型中取消了生成Voronoi圖,只輸出距離變換后的圖像
void distanceTransform( InputArray src, OutputArray dst,
int distanceType, int maskSize, int dstType=CV_32F);
該函數(shù)原型中的主要參數(shù)含義與前一種函數(shù)原型相同,前兩個參數(shù)為輸入圖像和輸出圖像,第三個參數(shù)和為距離變換過程中使用的距離種類。函數(shù)中第四個參數(shù)是距離變換掩碼矩陣的大小,由于街區(qū)距離(Dist_L1)和棋盤距離(Dist_C)對掩模尺寸沒有要求,因此該參數(shù)在選擇街區(qū)距離和棋盤距離時被強(qiáng)制設(shè)置為3,同樣掩模尺寸的大小對歐式距離(Dist_L2)計算的精度有影響,為了獲取較為精確的時,一般使用5×5的掩模矩陣。函數(shù)最后一個參數(shù)是輸出圖像的數(shù)據(jù)類型,雖然可以在CV_8U和CV_32F兩個類型中任意選擇,但是圖像輸出時實際的數(shù)據(jù)類型與距離變換時選擇的距離種類有著密切的聯(lián)系,CV_8U只能使用在計算街區(qū)距離的條件下,當(dāng)計算歐式距離和棋盤距離時,即使該參數(shù)設(shè)置為CV_8U,實際的輸出圖像的數(shù)據(jù)類型也是CV_32F。
//
// Created by smallflyfly on 2021/6/15.
//
#include "opencv2/opencv.hpp"
#include "opencv2/highgui.hpp"
#include "utils.hpp"
#include
using namespace std;
using namespace cv;
int main() {
// 自定義矩陣
Mat a = (Mat_(5, 5) "test.jpg", IMREAD_GRAYSCALE);
if (im.empty()) {
cerr "image file read error" 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;
}