结构元素的扩展操作
在介绍新的扩展形态学变换函数之前,介绍一组结构元素的扩展操作,包括结构元素的拷贝、取反和取映射操作。这些操作将在后面的形态学变换中经常出现。
函数:lhStructuringElementCopy
功能:获得形态学结构元素的拷贝
参数:se 输入结构元素
返回:se的拷贝,注意:在不使用时需要用cvReleaseStructuringElement释放
源码:
IplConvKernel* lhStructuringElementCopy(IplConvKernel* se)
{
IplConvKernel* copy = cvCreateStructuringElementEx( se->nCols, se->nRows,
se->anchorX, se->anchorY, 0, NULL );
copy->nShiftR = se->nShiftR;
memcpy( copy->values, se->values, sizeof(int) * se->nRows * se->nCols );
return copy;
}
函数:lhStructuringElementNot
功能:获得与当前形态学结构元素相反的结构元素
参数:se 输入结构元素
返回:se的取反,注意:在不使用时需要用cvReleaseStructuringElement释放
源码:
IplConvKernel* lhStructuringElementNot(IplConvKernel* se)
{
IplConvKernel* temp = cvCreateStructuringElementEx( se->nCols, se->nRows,
se->anchorX, se->anchorY, 0, NULL );
temp->nShiftR = se->nShiftR;
memcpy( temp->values, se->values, sizeof(int) * se->nRows * se->nCols );
for(int i=0; i<temp->nRows * temp->nCols ; i++)
temp->values[i] = !temp->values[i] ;
return temp;
}
函数:lhStructuringElementMap
功能:获得当前形态学结构元素的映射(反射)结构元素
参数:se 输入结构元素
返回:se的映射(反射),注意:在不使用时需要用cvReleaseStructuringElement释放
源码:
IplConvKernel* lhStructuringElementMap(IplConvKernel* se)
{
CvMat *mat = cvCreateMat( se->nRows, se->nCols, CV_32SC1);
memcpy(mat->data.i, se->values, sizeof(int) * se->nRows * se->nCols );
cvFlip(mat, NULL, -1);
IplConvKernel* semap = cvCreateStructuringElementEx( se->nCols, se->nRows,
se->nCols-se->anchorX-1, se->nRows-se->anchorY-1, 0, NULL );
semap->nShiftR = se->nShiftR;
memcpy( semap->values, mat->data.i, sizeof(int) * se->nRows * se->nCols );
cvReleaseMat(&mat);
return semap;
}
函数:lhMorpStructuringElementCard
功能:获得当前形态学结构元素的基数
参数:se 输入结构元素
返回:结构元素的基数
int lhStructuringElementCard(IplConvKernel* se)
{
assert(se != NULL);
int i, cnt = 0;
for (i=0; i<se->nCols*se->nRows; i++)
{
cnt += se->values[i];
}
return cnt;
}
函数:lhStructuringElementLine
功能:形态学线性结构元素的创建,常用于形态学方向分析
参数:angle len 分别为线性结构元素的角度和长度
返回:线性结构元素的指针
IplConvKernel* lhStructuringElementLine(unsigned int angle, unsigned int len)
{
assert(len > 2);
angle = angle%180;
CvPoint p1 = {0};
CvPoint p2 = {0};
int width = cvRound(len*cos((float)angle*CV_PI/180.0));
int height = cvRound(len*sin((float)angle*CV_PI/180.0));
height = height >= 1 ? height : 1;
if (width < 0)
{
width = width <= -1 ? width : -1;
p1.x = 0;
p1.y = 0;
p2.x = -width -1;
p2.y = height -1;
}
else
{
width = width >= 1 ? width : 1;
p1.x = 0;
p1.y = height -1;
p2.x = width -1;
p2.y = 0;
}
CvMat *temp = cvCreateMat(height, width, CV_32SC1);
cvZero(temp);
cvLine(temp, p1, p2, cvScalar(1,1,1), 1, 4, 0);
IplConvKernel* se = cvCreateStructuringElementEx( width, height,
(width-1)/2, (height-1)/2, CV_SHAPE_CUSTOM, temp->data.i );
cvReleaseMat(&temp);
return se;
}