计算像素轮廓的像素面积算法

计算像素轮廓的像素面积算法

此算法适用于求封闭像素轮廓,或者非封闭像素轮廓所谓成像素区域的面积大小。其中,像素轮廓点必须为,按一定顺序排列的离散点序列,本文以逆时针为例,若读者感兴趣,可自行修改为顺时针方向为顺序的代码。

Contour为轮廓空间点的结构体,使用的时候用malloc分配连续的内存块,contourApproxAreaMark函数中的像素面积统一近似为整型,_rContours为输入的待面积筛选的轮廓空间点内存块,_Width为轮廓所在图像的宽,_Height为轮廓所在图像的高,_MinArea为轮廓像素面积下限,_MaxArea为轮廓像素面积上限,返回值为去除了面积范围之内轮廓之后的轮廓空间点。

typedef struct Contours
{
	int height;
	int width;
	int stateFlag;
} contour;

contour* contourApproxAreaMark( contour* _rContours,
				const int _Width, const int _Height,
				const int _MinArea, const int _MaxArea )
{
	int point_Count_Now = 0;//当前轮廓点总数
	int i = 0, j = 0;//轮廓点计数
	int start_I = 0, start_J = 0;//记录轮廓起点坐标
	int vector_1[2] = {0}, vector_2[2] = {0};//记录计算三角形面积的临时逆时针向量
	int temp_Triangle_Area = 0;//轮廓中临时三角形面积两倍变量
	int temp_Area = 0;//临时轮廓面积变量
	int set0_Count = 0;//用于对筛选轮廓置零的计数器
	int temp_Offset = 0;//临时偏移量保存
	contour* contour_New_Ptr = NULL;//返回的新轮廓空间点首地址


	point_Count_Now = _rContours[0].stateFlag;
	_rContours[0].stateFlag = 1;
	while ( _rContours[i].height > 0 )
	{
		set0_Count = 0;
		temp_Area = 0;
		if ( 0 != _rContours[i].stateFlag )
		{
			start_I = _rContours[i].height;
			start_J = _rContours[i].width;
			set0_Count ++;
			while ( 0 == _rContours[i+set0_Count].stateFlag )
			{
				vector_1[0] = _rContours[i+set0_Count].width - start_J;//第一个向量修改更新
				vector_1[1] = _rContours[i+set0_Count].height - start_I; 
				vector_2[0] = _rContours[i+set0_Count+1].width - _rContours[i+set0_Count].width;//第二个向量修改更新
				vector_2[1] = _rContours[i+set0_Count+1].height - _rContours[i+set0_Count].height;
				temp_Triangle_Area = vector_1[0]*vector_2[1] - vector_1[1]*vector_2[0];//三角形面积的两倍
				//若结果为正数:向量关系为左转;结果为负数:向量关系为右转。以左转为正方向
				temp_Area += temp_Triangle_Area;//加入到轮廓面积中
				set0_Count ++;
			}
			temp_Area = abs(temp_Area);
			temp_Offset = set0_Count + 1;//储存偏移量
			if ( temp_Area*0.5 < _MinArea || temp_Area*0.5 > _MaxArea )
			{
				point_Count_Now -= (set0_Count+1);
				while ( set0_Count )
				{
					_rContours[i+set0_Count].stateFlag = 3;
					set0_Count --;
				}
				_rContours[i].stateFlag = 3;
			}
		}
		i += temp_Offset;
	}

	contour_New_Ptr = ( contour *)malloc( point_Count_Now * sizeof(contour) );//新轮廓空间
	i = 0; j = 0;
	while ( _rContours[i].height > 0 )
	{
		if ( 3 != _rContours[i].stateFlag )
		{
			contour_New_Ptr[j].height = _rContours[i].height;
			contour_New_Ptr[j].width = _rContours[i].width;
			contour_New_Ptr[j].stateFlag = _rContours[i].stateFlag;
			j ++;
		}
		i ++;
	}
	contour_New_Ptr[0].stateFlag = point_Count_Now;//将现轮廓点数量保存在第一个轮廓空间点的状态位
	free(_rContours);
	return contour_New_Ptr;
}


你可能感兴趣的:(Image,algorithm)