凸包(convex hull)是乙個計算幾何(圖形學)中的概念,在乙個實數向量空間v中,對於給定集合x,所有包含x的凸集的交集s被稱為x的凸包。
x的凸包可以用x內所有點(x1, x2….xn)的線性組合來構造。在二維歐幾里得空間中,凸包可以想象為一條剛好包著所有點的橡皮圈,用不嚴謹的話來講,給定二維平面上的點集,凸包就是將最外層的點連線起來構成的凸多邊形,它能包含點集中所有的點。常見的有graham』s scan法和jarvis步進法
凸包可以想象成一條剛好包住所有點的橡皮圈,對於二維的影象,凸包就是將最外層的點連線起來構成凸多邊形,它能包含點集中所有的點。物體的凸包檢測常常用於物體識別、手勢識別及邊界檢測等領域。
opencv提供了函式convexhull()用於對物體輪廓凸包進行檢測,對形狀凸包缺陷分析時使用convexitydefects()函式,每個缺陷區包含四個特徵量:起始點,結束點,距離及最遠點。
graham掃瞄法通過不斷在凸殼中加入新的點和去除影響凸性的點,最後形成凸包。演算法的主體由兩部分組成,先是排序,然後掃瞄。
(1)點集排序
為了得到加入新點的順序,graham掃瞄法的第一步是對點集排序,對雜亂的點集進行梳理,這也是這種演算法能夠得到更高效的根本原因。排序的方法有極角座標排序(極角序)和直角座標排序(水平序)兩種方法。在實現的時候,直角座標排序比較方便。
對於極角序,首先選取乙個參考點,一般選取橫座標最小的點作為參考點,如果有多個這樣的點就從這些點鐘選取縱座標最小的點。如下圖:
這樣就決定了參考點的性質:點集中任意兩點和參考點鎖成的倒角為銳角。
極角排序以參考點為極角座標系原點,根據上述參考點性質,可以設所有點的極角均在(-90,90]之間,排序完成後如下圖所示:
(2)棧掃瞄
graham掃瞄用的棧,其核心思想是按照拍好的序一次加入新點得到的邊,邊的尋找符合左旋判定。如果和上一條邊成左轉關係就壓棧繼續,如果右轉就出棧直到和棧頂兩點的邊成左轉關係,壓棧繼續。其棧掃瞄過程如下圖所示:
其演算法流程如下:
1.照橫座標最小的點(如有一樣則取相同點縱座標更小的點)
2.從這點開始卷包裹,照最靠近外側的點(通過叉積比較)
3.遍歷所有點,直到重新找到起點,退出。
opencv提供了convexhull()函式來查詢影象中物體的凸包,起函式定義如下:
void cv::convexhull ( inputarray points,
outputarray hull,
bool clockwise = false,
bool returnpoints = true
)
points:輸入的二維點集,mat型別資料即可
hull:輸出引數,用於輸出函式呼叫後找到的凸包
clockwise:操作方向,當識別符號為真時,輸出凸包為順時針方向,否則為逆時針方向。
returnpoints:操作識別符號,預設值為true,此時返回各凸包的各個點,否則返回凸包各點的指數,當輸出陣列時std::vector時,此標識被忽略。
#include#includeusing namespace std;
using namespace cv;
mat src1, src2, gray_img, dst;
int value = 100;
int max_value = 255;
void demo(int, void*);
int main()
namedwindow("input", cv_window_autosize);
imshow("input", src1);
namedwindow("output", cv_window_autosize);
cvtcolor(src1, gray_img, cv_bgr2gray);
createtrackbar("creattrackbar", "output", &value, max_value, demo);
demo(0, 0);
waitkey(0);
return 0;
}void demo(int, void*)
rng rng(12345);
for (size_t i = 0; i < contours.size(); i++)
imshow("output", src3);
}
ACM 尋找凸包
尋找凸包 點集q的凸包ch q 是乙個最小的凸多邊形p,它滿足q中的每個點或者在p的邊界上,或者在p的內部。現對於給定的點集q,求q的凸包ch q 的頂點集合。輸入 輸入有若干組測試資料。每一組測試資料的第一行上有整數n,表示該組測試資料有n個點組成的。接下來有n行,其每一行上有二個正整數,之間用乙...
opencv學習之尋找凸包,使用多邊形包圍輪廓
include stdafx.h include opencv2 highgui highgui.hpp include opencv2 imgproc imgproc.hpp include using namespace cv using namespace std define window ...
opencv計算點集凸包
點集求凸包的問題經常會遇到,給出了一種思路,有空了再仔細研究,本文總結了opencv中相關的方法並給出乙個例項。參考 hull cv.convexhull points hull clockwise returnpoints 引數說明 points 點集。需要注意的是,該引數輸入的座標系是向右為x,...