2011年2月22日 星期二

(OpenCV) 迴旋積遮罩的生成與釋放

OpenCV的IplConvKernel結構與cvCreateStructuringElementEx函式、cvReleaseStructuringElement函式說明
(注意 : IplConvKernel, 第一個字母為大寫的i, 第三個字母為小寫的L)


當要對一image做影像處理時 (例如:邊緣加強, 銳利化),
會使用到mask, 而以下要提到的就是mask的設定.

結構IplConvKernel : mask(遮罩)架構
typedef struct _IplConvKernel
{
int nCols; //mask的行數
int nRows; //mask的列數
int anchorX; //mask的中心點(X offset)
int anchorY; //mask的中心點(Y offset)
int *values; //mask矩陣
int nShiftR; //不知道???
}
IplConvKernel;

函式cvCreateStructuringElementEx : 產生mask(遮罩)
IplConvKernel* cvCreateStructuringElementEx(
int cols, //指定mask有幾行
int rows, //指定mask有幾列
int anchorX, //mask的中心點(X offset)
int anchorY, //mask的中心點(Y offset)
int shape, //mask的形狀, CV_SHAPE_RECT(矩形), CV_SHAPE_CROSS(十字), CV_SHAPE_ELLIPSE(橢圓), CV_SHAPE_CUSTOM(自訂)
int* values=NULL ); //當shape=CV_SHAPE_CUSTOM才有用, 若違NULL, 則視為矩形; 1代表pixel需要被參考, 0代表不需理會

函式cvReleaseStructuringElement : Release mask(遮罩)
void cvReleaseStructuringElement( IplConvKernel** element );


範例1 : 產生一個3x2的矩形遮罩, 中心點在(0, 0)位置
1(a00), 1(a01)
1(a10), 1(a11)
1(a20), 1(a21) (a00為中心點)
code : IplConvKernel *mask = cvCreateStructuringElementEx(2, 3, 0, 0, CV_SHAPE_RECT, 0);
結果 : mask->nCols = 2
mask->nRows = 3
mask->anchorX = 0
mask->anchorY = 0
mask->values = 1(a00), 1(a01), 1(a10), 1(a11), 1(a20), 1(a21)
mask->nShiftR = 0

範例2 : 產生一個5x5的十字遮罩, 中心點在(2, 2)位置
0(a00), 0(a01), 1(a02), 0(a03), 0(a04)
0(a10), 0(a11), 1(a12), 0(a13), 0(a14)
1(a20), 1(a21), 1(a22), 1(a23), 1(a24)
0(a30), 0(a31), 1(a32), 0(a33), 0(a34)
0(a40), 0(a41), 1(a42), 0(a43), 0(a44) (a22為中心點)
code : IplConvKernel *mask = cvCreateStructuringElementEx(5, 5, 2, 2, CV_SHAPE_CROSS, 0);
結果 : mask->nCols = 5
mask->nRows = 5
mask->anchorX = 2
mask->anchorY = 2
mask->values = 0(a00), 0(a01), 1(a02), 0(a03), 0(a04), 0(a10), 0(a11), 1(a12), 0(a13), 0(a14), 1(a20), 1(a21), 1(a22), 1(a23), 1(a24), 0(a30), 0(a31), 1(a32), 0(a33), 0(a34), 0(a40), 0(a41), 1(a42), 0(a43), 0(a44)
mask->nShiftR = 1

範例3 : 產生一個3x2的十字遮罩, 中心點在(1, 0)位置 (注意中心點的位置)
1(a00), 1(a01)
0(a10), 1(a11)
0(a20), 1(a21) (a01為中心點)
code : IplConvKernel *mask = cvCreateStructuringElementEx(2, 3, 1, 0, CV_SHAPE_CROSS, 0);
結果 : mask->nCols = 2
mask->nRows = 3
mask->anchorX = 1
mask->anchorY = 0
mask->values = 1(a00), 1(a01), 0(a10), 1(a11), 0(a20), 1(a21)
mask->nShiftR = 1

範例4 : 產生一個5x5的橢圓遮罩, 中心點在(2, 2)位置
0(a00), 0(a01), 1(a02), 0(a03), 0(a04)
1(a10), 1(a11), 1(a12), 1(a13), 1(a14)
1(a20), 1(a21), 1(a22), 1(a23), 1(a24)
1(a30), 1(a31), 1(a32), 1(a33), 1(a34)
0(a40), 0(a41), 1(a42), 0(a43), 0(a44) (a22為中心點)
code : IplConvKernel *mask = cvCreateStructuringElementEx(5, 5, 2, 2, CV_SHAPE_ELLIPSE, 0);
結果 : mask->nCols = 5
mask->nRows = 5
mask->anchorX = 2
mask->anchorY = 2
mask->values = 0(a00), 0(a01), 1(a02), 0(a03), 0(a04), 1(a10), 1(a11), 1(a12), 1(a13), 1(a14), 1(a20), 1(a21), 1(a22), 1(a23), 1(a24), 1(a30), 1(a31), 1(a32), 1(a33), 1(a34), 0(a40), 0(a41), 1(a42), 0(a43), 0(a44)
mask->nShiftR = 100

範例5 : 產生一個5x5的橢圓遮罩, 中心點在(1, 1)位置 (注意 : 橢圓並沒有因為中心點不一樣而位移)
0(a00), 0(a01), 1(a02), 0(a03), 0(a04)
1(a10), 1(a11), 1(a12), 1(a13), 1(a14)
1(a20), 1(a21), 1(a22), 1(a23), 1(a24)
1(a30), 1(a31), 1(a32), 1(a33), 1(a34)
0(a40), 0(a41), 1(a42), 0(a43), 0(a44) (a11為中心點)
code : IplConvKernel *mask = cvCreateStructuringElementEx(5, 5, 1, 1, CV_SHAPE_ELLIPSE, 0);
結果 : mask->nCols = 5
mask->nRows = 5
mask->anchorX = 1
mask->anchorY = 1
mask->values = 0(a00), 0(a01), 1(a02), 0(a03), 0(a04), 1(a10), 1(a11), 1(a12), 1(a13), 1(a14), 1(a20), 1(a21), 1(a22), 1(a23), 1(a24), 1(a30), 1(a31), 1(a32), 1(a33), 1(a34), 0(a40), 0(a41), 1(a42), 0(a43), 0(a44)
mask->nShiftR = 100

範例6 : 產生一個3x2的橢圓遮罩, 中心點在(1, 1)位置
0(a00), 1(a01)
1(a10), 1(a11)
0(a20), 1(a21) (a11為中心點)
code : IplConvKernel *mask = cvCreateStructuringElementEx(2, 3, 1, 1, CV_SHAPE_ELLIPSE, 0);
結果 : mask->nCols = 2
mask->nRows = 3
mask->anchorX = 1
mask->anchorY = 1
mask->values = 0(a00), 1(a01), 1(a10), 1(a11), 0(a20), 1(a21)
mask->nShiftR = 100

範例7 : 產生一個3x2的橢圓遮罩, 中心點在(0, 1)位置 (注意 : 再次驗證, 橢圓並沒有因為中心點不一樣而位移)
0(a00), 1(a01)
1(a10), 1(a11)
0(a20), 1(a21) (a10為中心點)
code : IplConvKernel *mask = cvCreateStructuringElementEx(2, 3, 0, 1, CV_SHAPE_ELLIPSE, 0);
結果 : mask->nCols = 2
mask->nRows = 3
mask->anchorX = 0
mask->anchorY = 1
mask->values = 0(a00), 1(a01), 1(a10), 1(a11), 0(a20), 1(a21)
mask->nShiftR = 100
結論 : 使用橢圓遮罩, 需特別注意

範例8 : 產生一個3x3的自訂遮罩, 中心點在(1, 1)位置
1(a00), 0(a01), 1(a02)
0(a10), 1(a11), 0(a12)
1(a20), 0(a21), 1(a22) (a11為中心點)
code : IplConvKernel *mask;
int mask_value[9] = {1, 0, 1, 0, 1, 0, 1, 0, 1};
mask = cvCreateStructuringElementEx(3, 3, 1, 1, CV_SHAPE_CUSTOM, mask_value);
結果 : mask->nCols = 3
mask->nRows = 3
mask->anchorX = 1
mask->anchorY = 1
mask->values = 1(a00), 0(a01), 1(a02), 0(a10), 1(a11), 0(a12), 1(a20), 0(a21), 1(a22)
mask->nShiftR = 100

當產生出來的mask再也用不到的時候, 記得要將mask所佔的記憶體給釋放掉。
code : cvReleaseStructuringElement(&mask);

沒有留言:

張貼留言