画像処理基本アルゴリズムチェーンコード境界追跡


チェーンコードは画像抽出の後期、すなわちモード識別において重要な特徴であり、例えばデジタル識別や文字識別においてチェーンコードの特徴が用いられるが、チェーンコードの抽出は境界追跡アルゴリズムによって境界シーケンスを取得することができ、境界シーケンスではなく境界シーケンスであることに注意し、境界は容易に取得することができる.しかし境界の点を一定の順序で出力するには手間がかかる.次に、境界追跡アルゴリズムを使用して境界を取得し、スタックに格納します(ここでのスタックは実際にはC++コンテナクラスであり、仮想スタックです).
点の8隣接情報を用いて,次の点を境界点として選択するアルゴリズムは,画像上がターゲット点であり,最上位,最左の点を選択できる開始点を選択する必要がある.次に、8つの隣接領域の点を確認し、右下45°の位置から探し始め、ターゲット点であれば時計回り90°を次の探し方向とし、そうでなければ反時計回り45°を探し続け、上記の手順を繰り返すと見つかります.
具体的な手順はアルゴリズムで説明されています.
/************************************************************************/
/*        ,                          */
/************************************************************************/
//                  
#include
#include 
#include 
#include 
using namespace std;



int main(){ 
	IplImage * image,*image2;
	image = cvLoadImage("E:\\image\\mapleleaf.tif",0);
	cvNamedWindow("image",1);
	cvShowImage("image",image);

	image2 = cvCreateImage(cvSize(image->width, image->height),image->depth,1);
	cvZero(image2);//image2    0
	//         
	CvPoint startPoint = cvPoint(0,0);
	bool bFindStartpoint = false;
	int i ,j;
	unsigned char * ptr,*dst;
	stack board;//     x  ,     y  

	//     
	CvPoint currentPoint = cvPoint(0,0);
	//   8     
	int directions[8][2] = {{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1}}; 
	int beginDirection = 0;
	bool bFindBoardpoint = false;//            
	for (i = 0 ; i< image->height && bFindStartpoint == false; i++)
	{
		for (j = 0 ; j< image->width && bFindStartpoint == false; j++)
		{
			ptr = (unsigned char *)(image->imageData + i*image->widthStep + j);
			if (*ptr == 255)
			{
				startPoint.x = j;
				startPoint.y = i;
				bFindStartpoint = true;
				//cout<imageData + (currentPoint.y + directions[beginDirection][1])* image->widthStep + currentPoint.x + directions[beginDirection][0]);
			if (*ptr == 255)
			{
				bFindBoardpoint = true;
				currentPoint.x +=  directions[beginDirection][0];
				currentPoint.y  += directions[beginDirection][1];
				/************************************************************************/
				/*                                 */
				/************************************************************************/
				// 、         
				dst  = (unsigned char *)image2->imageData + currentPoint.y * image2->widthStep + currentPoint.x;
				*dst = 255;

				// 、               
				board.push(currentPoint.x);
				board.push(currentPoint.y);

				if (currentPoint.x == startPoint.x  && currentPoint.y == startPoint.y )
				{
					bFindStartpoint = true;
				}
				//             
				beginDirection -= 2;
				if (beginDirection < 0)
				{
					beginDirection += 8;
				}
				
				
				
			}
			else
			{
				beginDirection ++;
				beginDirection = beginDirection%8;
			}
		}
		//cout<
/************************************************************************/  
/*                          */  
/************************************************************************/  
#include  
#include   
#include   
#include   
using namespace std;  
  
  
  
int main(){   
    IplImage * image,*image2,*image3;  
    image = cvLoadImage("E:\\image\\bottle2.tif",0);  
    cvNamedWindow("image",1);  
    cvShowImage("image",image);  
  
    image2 = cvCreateImage(cvSize(image->width, image->height),image->depth,1);  
    image3 = cvCreateImage(cvSize(image->width, image->height),image->depth,1);  
    cvZero(image2);//image2    0  
    cvZero(image3);  
    //           
    CvPoint startPoint = cvPoint(0,0);  
    bool bFindStartpoint = false;  
    int i ,j;  
    unsigned char * ptr,*dst;  
    stack board;//     x  ,     y    
  
    //       
    CvPoint currentPoint = cvPoint(0,0);  
    //   8       
    int directions[8][2] = {{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1}};   
    int beginDirection = 0;  
    bool bFindBoardpoint = false;//              
    for (i = 0 ; i< image->height && bFindStartpoint == false; i++)  
    {  
        for (j = 0 ; j< image->width && bFindStartpoint == false; j++)  
        {  
            ptr = (unsigned char *)(image->imageData + i*image->widthStep + j);  
            if (*ptr == 255)  
            {  
                startPoint.x = j;  
                startPoint.y = i;  
                bFindStartpoint = true;  
                //cout<imageData + (currentPoint.y + directions[beginDirection][1])* image->widthStep + currentPoint.x + directions[beginDirection][0]);  
            if (*ptr == 255)  
            {  
                bFindBoardpoint = true;  
                currentPoint.x +=  directions[beginDirection][0];  
                currentPoint.y  += directions[beginDirection][1];  
                /************************************************************************/  
                /*                                 */  
                /************************************************************************/  
                // 、           
                dst  = (unsigned char *)image2->imageData + currentPoint.y * image2->widthStep + currentPoint.x;  
                *dst = 255;  
  
                // 、                 
                board.push(currentPoint.x);  
                board.push(currentPoint.y);  
  
                if (currentPoint.x == startPoint.x  && currentPoint.y == startPoint.y )  
                {  
                    bFindStartpoint = true;  
                }  
                //               
                beginDirection -= 2;  
                if (beginDirection < 0)  
                {  
                    beginDirection += 8;  
                }  
                  
                  
                  
            }  
            else  
            {  
                beginDirection ++;  
                beginDirection = beginDirection%8;  
            }  
        }  
        //cout<imageData + i*image->widthStep + j;  
         *ptr = 255;  
          
    }  
    cvNamedWindow("image3",1);  
    cvSaveImage("E:\\image\\bottle2lianma.bmp",image3);  
    cvShowImage("image3",image3);  
  
  
    cvWaitKey(0);  
    return 0;  
}  
転入先http://blog.csdn.net/renshengrumenglibing/article/details/7251072