⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 contour.cpp

📁 图像处理软件,功能比较基础
💻 CPP
字号:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include "imgproc.h"
//轮廓跟踪
int SearchSingleContour(unsigned char **Image,short Row,short Col,
				COORD2d *Start,unsigned char *LinkerCode,short *PointNum,
				unsigned char labelnum)
{
	unsigned char NextToCurrent,PrevToCurrent;	//the relative direction
	short c_x,c_y;	//the coordinate of current point
	unsigned char n[8];
	short i,j;
	//搜索起始点
	Start->x = -1;
	Start->y = -1;
	for(i=0;i<Row;i++) {
		for(j=0;j<Col-1;j++) {
			if((j==0)&&(Image[i][j]==labelnum)) {
				Start->x = j;
				Start->y = i;
				i=Row;
				j=Col;
			}
			else if((Image[i][j]==0) && (Image[i][j+1]==labelnum)) {
				Start->x = j+1;
				Start->y = i;
				i = Row;
				j = Col;
			}
		}
	}
	if(Start->x<0) return 0;


	c_y = Start->y;
	c_x = Start->x;
	*PointNum = 0;
	Image[c_y][c_x] = 1;
	
	if(Image[c_y+1][c_x-1]==labelnum) {
		NextToCurrent = 5;
		Image[c_y+1][c_x-1] = 1;
		c_y = c_y+1;
		c_x = c_x-1;}
	else if(Image[c_y+1][c_x] == labelnum) {
			NextToCurrent = 6;
			Image[c_y+1][c_x] = 1;
			c_y = c_y+1;}
		else if(Image[c_y+1][c_x+1] == labelnum) {
				NextToCurrent = 7;
				Image[c_y+1][c_x+1] = 1;
				c_y = c_y+1;
				c_x = c_x+1;}
			else if(Image[c_y][c_x+1] == labelnum) {
					NextToCurrent = 0;
					Image[c_y][c_x+1] = 1;
					c_x = c_x+1;}
				else return 0;
	LinkerCode[*PointNum] = NextToCurrent;
	(*PointNum)++;
	
	do{
		PrevToCurrent = (NextToCurrent+4)%8;
		for(i=0;i<8;i++) {
			switch((PrevToCurrent+i+1)%8) {
				case 0:
					if((c_x+1)>=Col) n[i] = 0;
					else	n[i] = Image[c_y][c_x+1];
					break;
				case 1:
					if((c_y-1)<0 || (c_x+1)>=Col) n[i] = 0;
					else	n[i] = Image[c_y-1][c_x+1];
					break;
				case 2:
					if( (c_y-1)<0 ) n[i] = 0;
					else	n[i] = Image[c_y-1][c_x];
					break;
				case 3:
					if( (c_y-1)<0 || (c_x-1)<0 ) n[i] = 0;
					else n[i] = Image[c_y-1][c_x-1];
					break;
				case 4:
					if( (c_x-1)<0 ) n[i] = 0;
					else	n[i] = Image[c_y][c_x-1];
					break;
				case 5:
					if((c_y+1)>=Row || (c_x-1)<0) n[i] = 0;
					else 	n[i] = Image[c_y+1][c_x-1];
					break;
				case 6:
					if((c_y+1)>=Row ) n[i] = 0;
					else 	n[i] = Image[c_y+1][c_x];
					break;
				case 7:
					if((c_y+1)>=Row || (c_x+1)>=Col) n[i] = 0;
					else	n[i] = Image[c_y+1][c_x+1];
				default: ;
				}
			}
		for(i=0;i<6;i++) 
			if((n[i]==0) && (n[i+1]==labelnum) && (n[i+2]==0) ) n[i+1]=0;
		for(i=7;i>0;i--) 
			if((n[i]==labelnum)&&(n[i-1]==0)) break;
//		for(i=0;i<7;i++) 
//			if((n[i]==0)&&(n[i+1]==1)) return 0;
				//if(*PointNum<10) return 0;
			
		//if(n[6]==0) break;		
		NextToCurrent = (PrevToCurrent+i+1)%8;
		LinkerCode[*PointNum] = NextToCurrent;
		(*PointNum)++;
		switch(NextToCurrent) {
			case 0:
				c_y = c_y;
				c_x = c_x+1;
				break;
			case 1:
				c_y = c_y-1;
				c_x = c_x+1;
				break;
			case 2:
				c_y = c_y-1;
				break;
			case 3:
				c_y = c_y-1;
				c_x = c_x-1;
				break;
			case 4:
				c_x = c_x-1;
				break;
			case 5:
				c_y = c_y+1;
				c_x = c_x-1;
				break;
			case 6:
				c_y = c_y+1;
				break;
			case 7:
				c_y = c_y+1;
				c_x = c_x+1;
			default: ;
			}
		Image[c_y][c_x] = 1;
	}		
	while( (abs(c_y-Start->y)>1) || (abs(c_x-Start->x)>1) );
	if(*PointNum<10) return 2;
	return 1;
	}

//计算链码的长度
double ChainLength(unsigned char *LinkerCode,short PointNum)
{
	int i;
	double t;
	t = 0.0;
	for(i=0;i<PointNum;i++) {
		if(LinkerCode[i]%2) t = t+sqrt(2.0);
		else t = t+1.0;
	}
	return t;
}

//计算参数坐标
int ParaCoord(unsigned char *LinkerCode,short PointNum,
			  COORD2d Start,COORD2df *Para,short ParaNum)
{
	short i,j;
	double step;
	double PrevLen,NextLen;
	double LineLen;
	COORD2d Prev,Next;

//	*ParaNum = 2*PointNum;
	step = ChainLength(LinkerCode,PointNum)/(ParaNum);

	
	Para[0].x = Start.x;
	Para[0].y = Start.y;

	PrevLen = 0;
	NextLen = 0;
	LineLen = 0.0;
	Prev.x = Start.x;
	Prev.y = Start.y;
	j=1;
	LineLen = LineLen + step*j;

	for(i=0;i<PointNum;i++) {
		if(LinkerCode[i]%2) {
			switch(LinkerCode[i]) {
			case 1:
				Next.x = Prev.x+1;
				Next.y = Prev.y-1;
				break;
			case 3:
				Next.x = Prev.x-1;
				Next.y = Prev.y-1;
				break;
			case 5:
				Next.x = Prev.x-1;
				Next.y = Prev.y+1;
				break;
			case 7:
				Next.x = Prev.x+1;
				Next.y = Prev.y+1;
				break;
			}
			NextLen = PrevLen+sqrt(2.0);
		}
		else {
			switch(LinkerCode[i]) {
			case 0:
				Next.x = Prev.x+1;
				Next.y = Prev.y;
				break;
			case 2:
				Next.x = Prev.x;
				Next.y = Prev.y-1;
				break;
			case 4:
				Next.x = Prev.x-1;
				Next.y = Prev.y;
				break;
			case 6:
				Next.x = Prev.x;
				Next.y = Prev.y+1;
				break;
			}
			NextLen = PrevLen + 1.0;
		}
		while((LineLen>PrevLen) &&  (LineLen<NextLen) ) { 
			Para[j].x = Prev.x+(LineLen-PrevLen)*
							(Next.x-Prev.x)/(NextLen-PrevLen);
			Para[j].y = Prev.y+(LineLen-PrevLen)*
							(Next.y-Prev.y)/(NextLen-PrevLen);
			j++;
			LineLen = LineLen+step;
		}
		PrevLen = NextLen;
		Prev.x = Next.x;
		Prev.y = Next.y;
	}
	return 1;
}

int curvature(COORD2df *Para,short ParaNum,double *curv)
{
	double x1,x11,y1,y11;
	short i;
	double step;

	step = 1.0/ParaNum;
	for(i=0;i<ParaNum;i++) {
		x1 = (Para[(i+1)%ParaNum].x-Para[i%ParaNum].x)/step;
		y1 = -(Para[(i+1)%ParaNum].y-Para[i%ParaNum].y)/step;
//		x1 = (Para[(i+1)%ParaNum].x-Para[(i-1+ParaNum)%ParaNum].x)/2/step;
//		y1 = -(Para[(i+1)%ParaNum].y-Para[(i-1+ParaNum)%ParaNum].y)/2/step;

		x11 = (Para[(i+1)%ParaNum].x-Para[(i-1)<0?(i-1+ParaNum):(i-1)%ParaNum].x)/step/step;
		y11 = -(Para[(i+1)%ParaNum].y-Para[(i-1)<0?(i-1+ParaNum):(i-1)%ParaNum].y)/step/step;
		curv[i] = (x1*y11-y1*x11)/pow((x1*x1+y1*y1),1.5);
	}
	return 1;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -