📄 segment.cpp
字号:
#include <stdafx.h>
#include <stdio.h>
#include <math.h>
#include "common.h"
#include "basic.h"
#include "label.h"
#include "improc.h"
#include "segment.h"
int Otsu1(unsigned char** Image, int YStart, int XStart, int Row, int Col)
{
unsigned char **subimg;
int threshold;
int i,j;
subimg = (unsigned char **)fspace_2d(Row,Col,sizeof(unsigned char));
if(!subimg) return 0;
for(i=0; i<Row; i++)
for(j=0; j<Col; j++) subimg[i][j] = Image[i+YStart][j+XStart];
threshold = Otsu_2d(subimg,Row,Col);
ffree_2d((void **)subimg,Row);
return threshold;
}
int Otsu_2d(unsigned char **Image,int Row,int Col)
{
int i,j,GreyValue;
int OT; /* Optimal Threshold */
double BCV; /* Between Class Variance */
long w0,u0,Ave,Num,Count[MAXGRAYLEVEL+1];
double Vb;
for(i=0;i<=MAXGRAYLEVEL;i++) Count[i] = 0;
Num = 0;
for(i=0;i<Row;i++)
for(j=0;j<Col;j++)
if(Image[i][j])
{
Count[Image[i][j]]++;
Num++;
}
GreyValue = 0;
while(!Count[GreyValue]) GreyValue++;
w0 = Count[GreyValue];
u0 = GreyValue * Count[GreyValue];
Ave = u0;
for(i=GreyValue+1;i<=MAXGRAYLEVEL;i++)
Ave += i * Count[i];
OT = 0;
BCV = 0.0;
// Num = (long)Row * Col;
while(w0<Num)
{
Vb = ((double)Ave * w0 / Num - u0) * ((double)Ave * w0 / Num - u0)
/ w0 / (Num - w0);
if (Vb>BCV)
{
OT = GreyValue;
BCV = Vb;
}
GreyValue++;
w0 += Count[GreyValue];
u0 += GreyValue * Count[GreyValue];
}
return(OT);
}
/****************************** Otsu ******************************/
/* To get Otsu threshold */
int Otsu(unsigned char **Image,int Row,int Col)
{
int i,j,GreyValue;
int OT; /* Optimal Threshold */
double BCV; /* Between Class Variance */
long w0,u0,Ave,Num,Count[MAXGRAYLEVEL+1];
double Vb;
for(i=0;i<=MAXGRAYLEVEL;i++) Count[i] = 0;
for(i=0;i<Row;i++)
for(j=0;j<Col;j++)
Count[Image[i][j]]++;
GreyValue = 0;
while(!Count[GreyValue]) GreyValue++;
w0 = Count[GreyValue];
u0 = GreyValue * Count[GreyValue];
Ave = u0;
for(i=GreyValue+1;i<=MAXGRAYLEVEL;i++)
Ave += i * Count[i];
OT = 0;
BCV = 0.0;
Num = (long)Row * Col;
while(w0<Num)
{
Vb = ((double)Ave * w0 / Num - u0) * ((double)Ave * w0 / Num - u0)
/ w0 / (Num - w0);
if (Vb>BCV)
{
OT = GreyValue;
BCV = Vb;
}
GreyValue++;
w0 += Count[GreyValue];
u0 += GreyValue * Count[GreyValue];
}
return(OT);
}
/* Maxium Entrop Methord */
/************************** MaxEntropy ****************************/
int MaxEntropy(unsigned char **Image,int Row,int Col)
{
int i,j,GrayValue,MaxGrayValue,OT;
unsigned long Num,Count[MAXGRAYLEVEL+1],Ps;
double H,H1,H2,Hm,Hs;
double BV;
Num = (long)Row * Col;
for(i=0;i<=MAXGRAYLEVEL;i++) Count[i] = 0;
for(i=0;i<Row;i++)
for(j=0;j<Col;j++)
Count[Image[i][j]]++;
GrayValue = 0;
while(!Count[GrayValue]) GrayValue++;
MaxGrayValue = MAXGRAYLEVEL;
while(!Count[MaxGrayValue]) MaxGrayValue--;
Ps = Count[GrayValue];
Hs = Count[GrayValue] * log((double)Count[GrayValue]/Num);
H = H1 = H2 = Hm = 0;
BV = -100000000.0;
for(i=GrayValue;i<=MaxGrayValue;i++)
{
if(Count[i] != 0)
Hm += Count[i] * log((double)Count[i]/Num);
}
while(GrayValue < MaxGrayValue-1)
{
GrayValue++;
Ps += Count[GrayValue];
if(Count[GrayValue] != 0)
{
Hs += Count[GrayValue] * log((double)Count[GrayValue]/Num);
H1 = log((double)Ps/Num) - Hs/Ps;
H2 = log(1-(double)Ps/Num) + (Hs-Hm)/(Num-Ps);
H = H1+H2;
if(H>BV)
{
BV = H;
OT = GrayValue;
}
}
}
return(OT);
}
void Motsu(int Row, int Col, unsigned char** OriginalImg,
unsigned char ** SegmentImg,double EntropyThreshold )
{
COORDINATE Left_Up,Right_Down;
unsigned char **MidImg;
int Threshold;
int LabelNum,AreaRow,AreaCol,i,j;
static int LastArea[20],CorrentArea[20];
int Number;
double LocalEntropy;//,EntropyThreshold;
int Time=0, Flag=1;
double AreaThreshold;
MidImg=(unsigned char**)fspace_2d(Row,Col,sizeof(unsigned char));
//EntropyThreshold=1.5;
Threshold=NonlineOtsu(OriginalImg,0,0,Row,Col,(double)0.1);
for(i=0;i<20;i++)
{LastArea[i]=2000000;
CorrentArea[i]=2000000;}
for(i=0;i<Row;i++)
for(j=0;j<Col;j++)
{if(OriginalImg[i][j]>=Threshold) SegmentImg[i][j]=255;
else SegmentImg[i][j]=0;}
while((Flag==1)&&(Time<10))
{Time++;
Flag=0;
LabelNum=Label(SegmentImg,Row,Col,LABELMODE_1,50);
for(i=0;i<Row;i++)
for(j=0;j<Col;j++)
MidImg[i][j]=0;
for(Number=0;Number<LabelNum;Number++)
{Right_Down.x=0;
Right_Down.y=0;
Left_Up.x=Col-1;
Left_Up.y=Row-1;
for(i=0;i<Row;i++)
for(j=0;j<Col;j++)
{
if(SegmentImg[i][j]==(MAXLEVEL-Number))
{
if(i<Left_Up.y) Left_Up.y=i;
if(i>Right_Down.y) Right_Down.y=i;
if(j<Left_Up.x) Left_Up.x=j;
if(j>Right_Down.x) Right_Down.x=j;
}
}
AreaRow=Right_Down.y-Left_Up.y+1;
AreaCol=Right_Down.x-Left_Up.x+1;
LastArea[Number]=CorrentArea[Number];
CorrentArea[Number]=AreaRow*AreaCol;
AreaThreshold=(double)CorrentArea[Number]/LastArea[Number];
LocalEntropy=Entropy(OriginalImg,Left_Up.y,Left_Up.x,AreaRow,AreaCol);
if((LocalEntropy>EntropyThreshold)&&((AreaThreshold<0.99)||(AreaThreshold>1.01)))
{
Threshold=NonlineOtsu(OriginalImg,Left_Up.y,Left_Up.x,AreaRow,AreaCol,(double)0.1);
//printf("Threshold=%d\n",Threshold);
Flag=1;
for(i=Left_Up.y;i<Left_Up.y+AreaRow;i++)
for(j=Left_Up.x;j<Left_Up.x+AreaCol;j++)
if(OriginalImg[i][j]>Threshold) MidImg[i][j]=255;
}
else{
for(i=Left_Up.y;i<Left_Up.y+AreaRow;i++)
for(j=Left_Up.x;j<Left_Up.x+AreaCol;j++)
MidImg[i][j]=SegmentImg[i][j];
}
}
for(i=0;i<Row;i++)
for(j=0;j<Col;j++)
SegmentImg[i][j]=MidImg[i][j];
}
ffree_2d((void **)MidImg,Row);
}
int NonlineOtsu(unsigned char** Image, int YStart, int XStart, int Row, int Col, double C)
{
int i,j,GreyValue;
int OT; /* Optimal Threshold */
double BCV; /* Between Class Variance */
long w0,u0,Ave,Num,Count[MAXLEVEL+1];
double Vb;
for(i=0;i<=MAXLEVEL;i++) Count[i] = 0;
for(i=YStart;i<YStart+Row;i++)
for(j=XStart;j<XStart+Col;j++)
Count[Image[i][j]]++;
GreyValue = 0;
while(!Count[GreyValue]) GreyValue++;
w0 = Count[GreyValue];
u0 = GreyValue * Count[GreyValue];
Ave = u0;
for(i=GreyValue+1;i<=MAXLEVEL;i++)
Ave += i * Count[i];
if (Ave==u0) return(-1);
OT = 0;
BCV = 0.0;
Num = (long)Row * Col;
while(w0<Num)
{
Vb = ((double)Ave * w0 / Num - u0) * ((double)Ave * w0 / Num - u0) / w0 / (Num - w0);
Vb /= ((double)u0 / w0 + C);
if (Vb>BCV)
{
OT = GreyValue;
BCV = Vb;
}
GreyValue++;
w0 += Count[GreyValue];
u0 += GreyValue * Count[GreyValue];
}
return(OT);
}
void MotsuWithStd(int Row, int Col, unsigned char** OriginalImg,
unsigned char ** SegmentImg,double EntropyThreshold )
{
COORDINATE Left_Up,Right_Down;
unsigned char **MidImg;
int Threshold;
int LabelNum,AreaRow,AreaCol,i,j;
static int LastArea[20],CorrentArea[20];
int Number;
double LocalEntropy;//,EntropyThreshold;
int Time=0, Flag=1;
double AreaThreshold;
double Avg;
MidImg=(unsigned char**)fspace_2d(Row,Col,sizeof(unsigned char));
//EntropyThreshold=1.5;
Threshold=NonlineOtsu(OriginalImg,0,0,Row,Col,(double)0.1);
for(i=0;i<20;i++)
{LastArea[i]=2000000;
CorrentArea[i]=2000000;}
for(i=0;i<Row;i++)
for(j=0;j<Col;j++)
{if(OriginalImg[i][j]>=Threshold) SegmentImg[i][j]=255;
else SegmentImg[i][j]=0;}
while((Flag==1)&&(Time<10))
{Time++;
Flag=0;
LabelNum=Label(SegmentImg,Row,Col,LABELMODE_1,50);
for(i=0;i<Row;i++)
for(j=0;j<Col;j++)
MidImg[i][j]=0;
for(Number=0;Number<LabelNum;Number++)
{Right_Down.x=0;
Right_Down.y=0;
Left_Up.x=Col-1;
Left_Up.y=Row-1;
for(i=0;i<Row;i++)
for(j=0;j<Col;j++)
{
if(SegmentImg[i][j]==(MAXLEVEL-Number))
{
if(i<Left_Up.y) Left_Up.y=i;
if(i>Right_Down.y) Right_Down.y=i;
if(j<Left_Up.x) Left_Up.x=j;
if(j>Right_Down.x) Right_Down.x=j;
}
}
AreaRow=Right_Down.y-Left_Up.y+1;
AreaCol=Right_Down.x-Left_Up.x+1;
LastArea[Number]=CorrentArea[Number];
CorrentArea[Number]=AreaRow*AreaCol;
AreaThreshold=(double)CorrentArea[Number]/LastArea[Number];
Avg = ucAverage(OriginalImg,Left_Up.y,Left_Up.x,AreaRow,AreaCol,0);
LocalEntropy = ucDeviation(OriginalImg,Left_Up.y,Left_Up.x,AreaRow,AreaCol,Avg,0);
// LocalEntropy=Entropy(OriginalImg,Left_Up.y,Left_Up.x,AreaRow,AreaCol);
if((LocalEntropy>EntropyThreshold)&&((AreaThreshold<0.99)||(AreaThreshold>1.01)))
{
Threshold=NonlineOtsu(OriginalImg,Left_Up.y,Left_Up.x,AreaRow,AreaCol,(double)0.1);
//printf("Threshold=%d\n",Threshold);
Flag=1;
for(i=Left_Up.y;i<Left_Up.y+AreaRow;i++)
for(j=Left_Up.x;j<Left_Up.x+AreaCol;j++)
if(OriginalImg[i][j]>Threshold) MidImg[i][j]=255;
}
else{
for(i=Left_Up.y;i<Left_Up.y+AreaRow;i++)
for(j=Left_Up.x;j<Left_Up.x+AreaCol;j++)
MidImg[i][j]=SegmentImg[i][j];
}
}
for(i=0;i<Row;i++)
for(j=0;j<Col;j++)
SegmentImg[i][j]=MidImg[i][j];
}
ffree_2d((void **)MidImg,Row);
}
int GrdientSeg(unsigned char **oriimg,int YStart,int XStart,int Row,int Col)
{
double **g,**d;
double aver,dev,gthreshold;
double ratio;
double total;
int count,i,j;
g = (double **)fspace_2d(Row,Col,sizeof(double));
d = (double **)fspace_2d(Row,Col,sizeof(double));
if(!g||!d) return 0;
Sobel(oriimg,YStart,XStart,Row,Col,g,d,1);
aver = fAverage(g,0,0,Row,Col,0);
dev = fDeviation(g,0,0,Row,Col,aver,0);
ratio = 2;
gthreshold = aver + ratio * dev;
total = 0;
count = 0;
for(i=0; i<Row; i++)
for(j=0; j<Col; j++)
{
if(g[i][j]>gthreshold)
{
total += oriimg[i+YStart][j+XStart];
count++;
}
}
return((int)(total/count));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -