📄 contour.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 + -