2008年6月30日 星期一

OpenCV繪圖的實作-cvFillPoly

接下來的也是實心多邊型函數,但是這個功能強大多了,也有點複雜,它可以藉由點集合陣列的分群,來做出兩個以上的多邊型,但是對點集合有幾個限制的條件.

cvFillPoly()函式的實作
#include <cv.h>
#include <highgui.h>

IplImage *Image1;
CvPoint PointArray1[7];
CvScalar Color;

CvSize TextSize;
CvFont Font1;
CvPoint TextPosition;
int main()
{
    CvSize ImageSize1 = cvSize(1000,700);
    Image1 = cvCreateImage(ImageSize1,IPL_DEPTH_8U,3);

    PointArray1[0]=cvPoint(200,200);
    PointArray1[1]=cvPoint(400,150);
    PointArray1[2]=cvPoint(650,230);
    PointArray1[3]=cvPoint(800,300);
    PointArray1[4]=cvPoint(900,550);
    PointArray1[5]=cvPoint(700,600);
    PointArray1[6]=cvPoint(100,500);

    CvPoint *PointArray[2]= {&PointArray1[0],&PointArray1[4]};

    CvScalar Color=CV_RGB(255,0,0);
    int PolyVertexNumber[2]={4,3};
    int BlockNumber=2;

    cvFillPoly(Image1,PointArray,PolyVertexNumber,BlockNumber,Color,CV_AA,0);

    cvInitFont( &Font1,CV_FONT_HERSHEY_SIMPLEX,0.5,0.5,0.0,1, CV_AA );

    cvPutText(Image1,"1(200,200)",cvPoint(180,180),&Font1,CV_RGB(255,0,0));
    cvPutText(Image1,"2(400,150)",cvPoint(400,150),&Font1,CV_RGB(255,0,0));
    cvPutText(Image1,"3(650,230)",cvPoint(650,230),&Font1,CV_RGB(255,0,0));
    cvPutText(Image1,"4(800,300)",cvPoint(800,300),&Font1,CV_RGB(255,0,0));
    cvPutText(Image1,"5(900,550)",cvPoint(900,550),&Font1,CV_RGB(255,0,0));
    cvPutText(Image1,"6(700,600)",cvPoint(700,620),&Font1,CV_RGB(255,0,0));
    cvPutText(Image1,"7(100,500)",cvPoint(90,520),&Font1,CV_RGB(255,0,0));

    cvNamedWindow("FillPoly",1);
    cvShowImage("FillPoly",Image1);
    cvWaitKey(0);
}

執行結果:
(1)原始結果


(2)BlockNumber=2,PolyVertexNumber[2]={3,3}


(3)BlockNumber=1,PolyVertexNumber[1]={3,3}


(4)BlockNumber=1,PolyVertexNumber[1]={7}


這裡給它了7個點的點集合,並且用CvFont跟cvPutText()的方式列出他們點座標的位置,跟之前cvFillConvexPoly()不一樣的地方,它把點集合放在二維陣列裡,這裡的二維陣列,可以自己設定每個空間長度都不一樣,像上面的程式範例,這個二維陣列被分為兩個,第一個長度為4第二個長度為3,然後設定要繪製兩個多邊型區塊,選定第一個長度為四的要用到4個點,第二個長度為三的要用到3個點,接著就繪製實心多邊型,這樣的目的,實際上可以轉換成另一個問題來解釋:

有七個點集合,它們被分為兩群,第一群有四個點集合,第二群被分為三個點集合,要從這兩群裡面各做一個多邊型,要選定要製作多邊型的點,第一群不能超過四個點,第二群不能超過三個點,而所需要製作的多邊形區塊數為兩個,因此這裡選擇了製作出一個四邊形跟一個三邊型,而四邊形跟三角形的點座標就是被分開的那兩群.

因此,這裡的輸入就出現了限制條件
1.七個點集合最多只能被分成1~7群
2.挑選點數目的群數時可以小於等於一開始所設定的分群數,當小於時,後面的的點數量會累加,
  每群被選定的點數目不能超過每一群裡面的所有點數量
3.多邊型的區塊數必須小於等於所有的群數

接著是延伸比較難的部份,一個點集合有N個,可以將點集合任意的分群,而每一群只能製作一個多邊型,接著,選定要製作多少個多邊型區塊,再從每一群中挑出自己選定的點個數來製作多邊型.

因此,可以分析的出來點的分群可以分成
1.1≦Group≦N這麼多群
2.每一群可以選定的點為1≦PolyVertexNumber(i)≦MAX_POINT_NUMBER(i),PolyVertexNumber可以設定的群
   數為,1≦n≦Group
     當n<Group,則
   MAX_POINT_NUMBER(n)=MAX_POINT_NUMBER(n+1)+MAX_POINT_NUMBER(n+2)+...MAX_POINT_NUMBER(Group)
3.可以製作的多邊型數目為1≦PolyBlockNumber≦n

為什麼要有這樣的限制條件,因為如果沒照這限制條件的話cvFillPoly()就會出現錯誤,當然啦,它可以將點集合分群,決定繪製多邊型數,及選定被分群的點集合數目,超出範圍當然畫不出來啦.

七個點集合被分群的情形


點集合資料結構的排列狀態


也可以用三個陣列實作多邊型二維陣列


如果用三個以上的陣列實作的話,將會影響記憶體區段,原本存取的是連續記憶體區段,卻會變成不連續的記憶體,會影響到空間局部性,也就是存取記憶體時的分頁替換會造成速度下降,這是作業系統原理的分頁相關部分.

cvFillPoly()
製作多個或一個填充多邊型,第一個引數放目標圖片,下一個一定要放CvPoint資料結構二維陣列,再來是二維陣列內多邊型點集合數分配,各二維陣列內陣列點集合區塊數,顏色,線條種類,比例大小縮放.
cvFillPoly(IplImage資料結構,CvPoint二維陣列,分配二維陣列的各多邊型頂點,選定需要製作幾個多邊型,CvScalar顏色,線條種類,比例大小縮放數據)



1 意見:

匿名 提到...

您好,在下第一次接觸opencv
請問前輩,opencv算c++語言吧?有辦法將他繪出的圖形(例如正方形)座標傳給fortran處理嗎?

Copyright 2008-2009,yester