- 论坛徽章:
- 0
|
/*******************************************************************************************
* Filename : OverlapStampProcess.cpp
*Creat by elite for XXXXXXX Tech LTD.
********************************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include "OverlapStampProcess.h"
typedef struct point{
int x;
int y;
} point;
#define element point
#define IncLen 20//栈增长长度
/***************************************************************************/
/***用C语言实现栈类***用C语言实现栈类***用C语言实现栈类***用C语言实现栈类****************/
/***************************************************************************/
typedef struct StackClass{
element *top;
element *base;
int EleNum;
int StackLength;
void (*push)(struct StackClass *,element);//插入元素
bool (*pop)(struct StackClass *,element & ;//删除元素
//struct StackClass* this_p //this指针
}stack;
//***********************************************************//
//*函数功能:元素入栈 //
//++++++++++++++++++++++++++++++++++++++++++++++++++++//
void f_push(stack *s,element e)
{
element *temp;
if((s->EleNum)+1<=s->StackLength)
{
s->top[0] = e;
s->EleNum++;
s->top++;
}
else
{
temp = new element[(s->StackLength)+IncLen];
memcpy(temp,s->base,(s->StackLength)*sizeof(element));
delete[] s->base;
s->base = temp;
s->top = temp + (s->EleNum);
s->StackLength = s->StackLength + IncLen;
s->top[0] = e;
s->EleNum++;
s->top++;
}
}
//***********************************************************//
//*函数功能:元素出栈 //
//++++++++++++++++++++++++++++++++++++++++++++++++++++//
bool f_pop(stack *s,element &e)
{
element temp;
if(s->EleNum>=1)
{
s->top--;
temp = s->top[0];
s->EleNum--;
e = temp;
return true;
}
else
{
printf("The stack is empty, No element to pop !" ;
return false;
}
}
//***********************************************************//
//*函数功能:栈的构造函数 //
//++++++++++++++++++++++++++++++++++++++++++++++++++++//
stack *StackCreat(int Length)
{
stack *temp = NULL;
temp = new stack[1];
temp->base = new element[Length];
temp->top = temp->base;
temp->StackLength = Length;
temp->EleNum = 0;
temp->push = f_push;
temp->pop = f_pop;
//temp->this_p = temp;
return temp;
}
//***********************************************************//
//*函数功能:栈的析构函数 //
//++++++++++++++++++++++++++++++++++++++++++++++++++++//
void StackDestroy(stack *s)
{
delete[] s->base;
delete[] s;
s = NULL;
}
//****************************************************************************//
//***用C语言实现栈类***用C语言实现栈类***用C语言实现栈类***用C语言实现栈类*****************//
//***************************************************************************//
typedef struct s_figure{
point* p;
int PointNumber;
}figure;//保存图像轮廓的数据元素
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//+函数功能:寻找轮廓(对图像最好先进行膨胀处理,填充断裂) //
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
figure GetFigure(unsigned char* img, int SizeX, int SizeY)
{
int i,j,k;
bool sign = false;
point tmp;
figure rst;
rst.p = new point[2*SizeX*SizeY];
rst.PointNumber = 0;
k = 0;
//get the top-left points and insert it
for(i = 0;i < SizeY;i++)
{
for(j = 0;j < SizeX;j++)
{
if(img[i*SizeX + j] == 255)
{
rst.p[k].x = j;
rst.p[k].y = i;
tmp.x = j;
tmp.y = i;
k++;
sign = true;
break;
}
}
if(sign == true)
break;
}
//get the top-right points and insert it
for(i = 0;i < SizeY;i++)
{
for(j = SizeX - 1;j > -1;j--)
{
if(img[i*SizeX + j] == 255)
{
rst.p[k].x = j;
rst.p[k].y = i;
k++;
sign = true;
break;
}
}
if(sign == true)
break;
}
//judge if top-left == top-right ?
if((rst.p[k].x == rst.p[k-1].x)&&(rst.p[k].y == rst.p[k-1].y))
{
k--;
}
//get the other points and insert it
for(i = rst.p[k-1].y+1;i < SizeY;i++)
for(j = SizeX-1;j > -1;j--)
{
if(img[i*SizeX + j] == 255)
{
rst.p[k].x = j;
rst.p[k].y = i;
k++;
break;
}
}
//delete bottom-left point
k--;
//get the bottom-left point
for(i = SizeY - 1;i > -1;i--)
{
for(j = 0;j < SizeX;j++)
{
if(img[i*SizeX + j] == 255)
{
rst.p[k].x = j;
rst.p[k].y = i;
k++;
sign = true;
break;
}
}
if(sign == true)
break;
}
//judge if bottom-left == bottom-right ?
if((rst.p[k].x == rst.p[k-1].x)&&(rst.p[k].y == rst.p[k-1].y))
{
k--;
}
//get the other points and insert it
for(i = rst.p[k-1].y-1;i > tmp.y;i--)
for(j = 0;j < SizeX;j++)
{
if(img[i*SizeX + j] == 255)
{
rst.p[k].x = j;
rst.p[k].y = i;
k++;
break;
}
}
figure rst1;
rst1.p = new point[k];
rst1.PointNumber = k;
memcpy(rst1.p,rst.p,k*sizeof(point));
delete[] rst.p;
return rst1;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//+函数功能:对blob进行排序 //
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
void sort(point *ESrc,int NumSrc,point *&EDst)
{
int i,/*Min,*/MinY;
//int point;
//int *EDst;
EDst = new point[NumSrc];
MinY = 0;
for(i=1;i<NumSrc;i++)
{
if(ESrc.y < ESrc[MinY].y) MinY = i;
}
/*
for(i=0;i<=MinY;i++)
{
if(ESrc.y == ESrc[MinY].y)
{
Min = i;
break;
}
}
*/
if(MinY == 0) memcpy(EDst,ESrc,NumSrc*sizeof(point));
else
{
memcpy(EDst,ESrc+MinY,(NumSrc-MinY)*sizeof(point));
memcpy(EDst+NumSrc-MinY,ESrc,MinY*sizeof(point));
}
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//+函数功能:对blob进行水平序排序 //
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
void Qsort(point *ESrc,int NumSrc,point *&EDst)
{}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//+函数功能:求线段拐向 //
//说明:如果回值大于0,说明NowPoint在线段next-top的右侧;如果 //
//等于0,在同一直线上;如果小于0,在线段左侧. //
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
int GetCross(point next,point top,point NowPoint)
{
point d1,d2;
int cross;
d1.x = NowPoint.x - next.x;
d1.y = NowPoint.y - next.y;
d2.x = top.x - next.x;
d2.y = top.y - next.y;
cross = d1.x*d2.y - d1.y*d2.x;
return cross;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//+函数功能:求凸包边界 //
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
void Convex(point *EpSrc,int NumSrc,point *&EDst,int &NumDst)//考虑用队列传入参数
{
point *ESort = NULL;//存储排序后的blob
point *ESrc = NULL;
int i,j;
stack *s = NULL;
element top,next;//存储栈中弹出进行比较的元素
//对blob排序
sort(EpSrc,NumSrc,ESort);//排序问题----have bug
ESrc = new point[NumSrc+1];
memcpy(ESrc,ESort,NumSrc*sizeof(point));//Add first point
ESrc[NumSrc].y = ESort[0].y;
ESrc[NumSrc].x = ESort[0].x;
//求取凸包边点
s = StackCreat(NumSrc*2);
s->push(s,ESrc[0]);//入栈数据未变
s->push(s,ESrc[1]);
for(i=2;i<NumSrc+1;i++)//对所有点进行定顶点法则判定
{
int temp = s->EleNum;
for(j=temp;j>1;j--)//回溯所有已经入栈的点
{
s->pop(s,top);
s->pop(s,next);
if(GetCross(next,top,ESrc)<0)//如果cross大于零则当前点位于线段top-next右侧
{
//当前点也入栈,然后跳出循环
s->push(s,next);
s->push(s,top);
s->push(s,ESrc);
break;
}
//栈顶元素出栈,继续计算当前点是否边界点
else s->push(s,next);
}
if(s->EleNum == 1) s->push(s,ESrc);//如果栈中只剩起始点,则将当前点压入栈顶
}
//丢弃栈顶元素,因为起点重复
s->pop(s,top);
//输出凸包边点
NumDst = s->EleNum;
EDst = new point[NumDst];
point temp;
for(i=0;i<NumDst;i++)
{
s->pop(s,temp);
EDst[NumDst - 1 - i].x = temp.x;
EDst[NumDst - 1 - i].y = temp.y;
}
//释放内存
delete[] ESort;
//销毁栈
StackDestroy(s);
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//+函数功能:计算库章凸包 //
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
figure CptStampCvx(unsigned char* img, int SizeX, int SizeY)
{
figure src,dst;
src = GetFigure(img, SizeX, SizeY);
Convex(src.p,src.PointNumber,dst.p,dst.PointNumber);
delete src.p;
return dst;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//+函数功能:判断两点是否八邻域连接 //
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
bool IsNear(point p1, point p2, int SizeX, int SizeY)
{
int x1,x2,y1,y2;
int length = SizeX - 1,high = SizeY - 1;
x1 = p1.x - 1;
x2 = p1.x + 1;
y1 = p1.y - 1;
y2 = p1.y + 1;
if(x1 < 0)
x1 = 0;
if(x2 > length)
x2 = length;
if(y1 < 0)
y1 = 0;
if(y2 > high)
y2 = high;
if(p2.x < x2 && p2.x > x1 && p2.y < y2 && p2.y > y1)
{
return true;
}
else
{
return false;
}
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//+函数功能:构造凸包连续边界 //
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
void ConnectConvex(unsigned char* img, int SizeX, int SizeY,
point* PointList, int num)
{
int i;
bool sign = false;
stack *s;//用队列或链表保存结果
s = StackCreat(100*num);
s->push(s,PointList[0]);
printf("saved p 0 \n" ;
for(i = 1;i < num;i++)//num
{
//store(PointList);
//s->push(s,PointList);
sign = IsNear(PointList[i-1], PointList, SizeX, SizeY);
if(sign == false)
{
int diffx,diffy;
diffx = PointList.x - PointList[i-1].x;
diffy = PointList.y - PointList[i-1].y;
if(diffx == 0)
{
int start,end;
if(PointList[i-1].y < PointList.y)
{
start = PointList[i-1].y;
end = PointList.y;
}
else
{
end = PointList[i-1].y;
start = PointList.y;
}
point NewPoint;
NewPoint.x = PointList[i-1].x;
for(NewPoint.y = start+1;NewPoint.y < end;(NewPoint.y)++)
{
s->push(s,NewPoint);
}
}
else
{
if(diffy == 0)
{
int start,end;
if(PointList[i-1].x < PointList.x)
{
start = PointList[i-1].x;
end = PointList.x;
}
else
{
end = PointList[i-1].x;
start = PointList.x;
}
point NewPoint;
NewPoint.y = PointList[i-1].y;
for(NewPoint.x = start+1;NewPoint.x < end;(NewPoint.x)++)
{
s->push(s,NewPoint);
}
}
else
{
int a,b;
a = 10000*diffy/diffx;
b = 10000*PointList.y - a*PointList.x;
int start,end;
point NewPoint;
if(abs(diffx) > abs(diffy))
{
if(PointList[i-1].x < PointList.x)
{
start = PointList[i-1].x;
end = PointList.x;
}
else
{
end = PointList[i-1].x;
start = PointList.x;
}
for(NewPoint.x = start+1;NewPoint.x < end;(NewPoint.x)++)
{
NewPoint.y = a*(NewPoint.x)+b;
NewPoint.y = ((NewPoint.y)+5000)/10000;
//store(NewPoint);
s->push(s,NewPoint);
}
}
else
{
if(PointList[i-1].y < PointList.y)
{
start = PointList[i-1].y;
end = PointList.y;
}
else
{
end = PointList[i-1].y;
start = PointList.y;
}
for(NewPoint.y = start+1;NewPoint.y < end;(NewPoint.y)++)
{
NewPoint.x = (10000*NewPoint.y -b)/a;
NewPoint.x = ((NewPoint.x)*10 + 5)/10;
//store(NewPoint);
s->push(s,NewPoint);
}
}
}
}
}
else
{
s->push(s,PointList);
printf("saved p %d \n",i);
}
s->push(s,PointList);
}
memset(img, 0, 3*SizeX*SizeY);
int size = SizeX*SizeY;
point p;
do
{
s->pop(s,p);
img[p.y*SizeX+p.x] = 128;
//img[size+p.y*SizeX+p.x] = 250;
//img[2*size+p.y*SizeX+p.x] = 250;
} while(s->EleNum > 1);
StackDestroy(s);
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//+函数功能:填充凸包内部 //
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
void FillImg(unsigned char* img, int SizeX, int SizeY)
{
int i,j/*,StartX,StartY,EndX,EndY*/;
for(i = 0;i < SizeY; i++)
for(j = 0;j < SizeX;j++)
{
int size = i*SizeX+j;
if(img[size] != 12
{
img[size] = 255;
}
else
{
break;
}
}
for(i = 0;i < SizeY; i++)
for(j = SizeX-1;j > -1;j--)
{
int size = i*SizeX+j;
if(img[size] != 12
{
img[size] = 255;
}
else
{
break;
}
}
for(i = 0;i < SizeY; i++)
for(j = 0;j < SizeX;j++)
{
int size = i*SizeX+j;
if(img[size] == 12
{
img[size] = 255;
}
else
{
img[size] = 255 - img[size];
}
}
}
底下其他函数不贴了
[ 本帖最后由 zhichiamd 于 2007-4-19 12:37 编辑 ] |
-
原始.JPG
(8.83 KB, 下载次数: 47)
原始图像
-
结果.JPG
(3.03 KB, 下载次数: 50)
处理后图像
|