随机霍夫变换检测圆,请各路大虾指点迷津

pcgg5244 2011-02-04 02:14:12
在做一个随机霍夫变换检测圆的题目,不能直接使用OPENCV的函数,在网上找了很多资料,先用CANNY算子检测边缘,然后用随机霍夫变换,但是实现起来就是检测不出,请大家帮忙看下,下面是代码

//剩下的点
int GetCount(BYTE* pData,SIZE sizeImage)
{
int n=0;
for(int y=0;y<sizeImage.cy;y++)
{
for(int x=0;x<sizeImage.cx;x++)
{
if(128<=*(pData+y*sizeImage.cx+x))
{
n++;
}
}
}
return n;
}
//偏移转换成位置
void GetPoint(BYTE* pData,SIZE sizeImage,int nPos,POINT* point)
{
int i=0;
for(int y=0;y<sizeImage.cy;y++)
{
for(int x=0;x<sizeImage.cx;x++)
{
if(128 <= *(pData+y*sizeImage.cx+x))
{
i++;
if(nPos == i)
{
point->x=x;
point->y=y;
return;
}
}
}
}
}

void RemoveCircle(BYTE* pData,SIZE sizeImage,Circle* circle)
{
for(int y=0;y<sizeImage.cy;y++)
{
for(int x=0;x<sizeImage.cx;x++)
{
if(128 <= *(pData+y*sizeImage.cx+x))
{
double a=circle->a;
double b=circle->b;
double r=circle->r;
double dd=abs(sqrt(pow(a-x,2)+pow(b-y,2))-r);
if(dd<4*r*EE)
{
*(pData+sizeImage.cx*y+x)=0;
}
}
}
}
}
int GetRandom(BYTE* pData,SIZE sizeImage,POINT* point)
{
int n=GET_RANDOM(0,GetCount(pData,sizeImage)-1);
GetPoint(pData,sizeImage,n,point);
return n;
}

BOOL GetCircle(POINT* pt,Circle* circle )
{
double d12,d23,k12,k23;
double a,b,r;
if(pt[0].y != pt[1].y && pt[1].y != pt[2].y)
{
k12=(pt[0].x-pt[1].x)/(pt[1].y-pt[0].y);
k23=(pt[1].x-pt[2].x)/(pt[2].y-pt[1].y);
if(k12 != k23)
{
d12=(pt[0].y+pt[1].y-k12*(pt[0].x+pt[1].x))/2;
d23=(pt[1].y+pt[2].y-k23*(pt[1].x+pt[2].x))/2;
a=(d12-d23)/(k23-k12);
b=k12*a+d12;
r=sqrt(pow(pt[0].x-a,2)+pow(pt[0].y-b,2));
}
else
{
return FALSE;
}
}
else
{
return FALSE;
}
circle->a=a;
circle->b=b;
circle->r=r;
return TRUE;
}
//检测是否为圆
BOOL CheckCircle(BYTE* pData,SIZE sizeImage,Circle* circle)
{
double a=circle->a;
double b=circle->b;
double r=circle->r;
double dx,dy,e1,e2,dd;
double k=0;
for(int y=0;y<sizeImage.cy;y++)
{
for(int x=0;x<sizeImage.cx;x++)
{
if(128 <= *(pData+y*sizeImage.cx+x))
{
dx=x;
dy=y;
e1=r;
e2=0.707*r;
//if((((dx>=a-e1 && dx<=a-e2)||(dx<=a+e1 && dx>=a+e2))&& dy<=b+e2 && dy>=b-e2)|| \
(((dy>=b-e1 && dy<=b-e2) || (dy<=b+e1 && dy>=b+e2))&&(dx>=a-e2 && dx<=a+e2)))
//{
dd=sqrt(pow(x-a,2)+pow(y-b,2));
if(abs(dd-r)<r*EE)
{
k++;
}
//}
}
}
}
return k>KK*2*PI*r;
}

void Display(CDC* pDC,Circle* cir)
{
// TODO: 在此添加命令处理程序代码
for(int i=0;i<MAX_CIRCLE;i++)
{
int x0=(cir+i)->a;
int y0=(cir+i)->b;
CPen pen(PS_SOLID,1,RGB(0,0,255));
CPen* pOld=pDC->SelectObject(&pen);
pDC->MoveTo(x0-2,y0);
pDC->LineTo(x0+3,y0);
pDC->MoveTo(x0,y0-2);
pDC->LineTo(x0,y0+3);
int x1=x0-(cir+i)->r;
int y1=y0-(cir+i)->r;
int x2=x0+(cir+i)->r;
int y2=y0+(cir+i)->r;
int sx,sy;
for(int y=y1;y<y2;y++)
{
int x=x0-sqrt(pow((double)(cir+i)->r,2)-pow((double)(y-y0),2));
if(y==y1)
{
pDC->MoveTo(x,y);
}
else
{
pDC->LineTo(sx,sy);
}
sx=x;
sy=y;
}
for(int y=y2;y>=y1;y--)
{
int x=x0+sqrt(pow((double)(cir+i)->r,2)-pow((double)(y-y0),2));
pDC->LineTo(x,y);
}
pDC->SelectObject(&pOld);
}
}
//霍夫变换
void HoughTransform(BYTE* pData,SIZE sizeImage)
{
CDC* pDC=pView->GetDC();
int direct[8][2]={{1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1}};
int Timeout=MAX_FAIL;
int k=0;
Circle cir[MAX_CIRCLE]={0};
CPoint point[3000];
BYTE* pImage=new BYTE[sizeImage.cx*sizeImage.cy];
memcpy(pImage,pData,sizeImage.cx*sizeImage.cy);
while(Timeout--)
{
if(GetCount(pImage,sizeImage)<50)
break;
POINT pt[3]={0};
GetRandom(pImage,sizeImage,&pt[0]);
//pDC->SetPixel(pt[0],RGB(255,255,0));
if(pt[0].x>=1&&pt[0].x<sizeImage.cx-1 &&pt[0].y>=1&&pt[0].y<sizeImage.cy-1)
{
BYTE* pCur=pImage+pt[0].x+pt[0].y*sizeImage.cx;
BYTE* pPre=NULL;
BYTE* pNext=NULL;
BYTE* pStart=pCur;
int ii=0;
while(ii<3000)
{point[ii]=0;ii++;}
int i=0;
while(1)
{
if(pStart==pCur)
break;
int j=0;
while(j<8)
{
pNext=pCur+direct[j][0]+direct[j][1]*sizeImage.cx;
if(pPre==pNext)
break;
int x=(pNext-pImage)%sizeImage.cx;
int y=(pNext-pImage)/sizeImage.cx;
if(x>=1 && x<sizeImage.cx-1 &&y>=1 &&y<=sizeImage.cy)
{
if(128<= *pNext )
{
if(pPre!=pNext)
{
pPre=pCur;
pCur=pNext;
}
break;
}
}
j++;
}
if(8==j || pPre==pNext)
break;
i++;
}
i=0;
while(1)
{
int j=0;
while(j<8)
{
pNext=pCur+direct[j][0]+direct[j][1]*sizeImage.cx;
int x=(pNext-pImage)%sizeImage.cx;
int y=(pNext-pImage)/sizeImage.cx;
if(x>=1 && x<sizeImage.cx-1 &&y>=1 &&y<=sizeImage.cy)
{
if(128<= *pNext )
{
*pCur=0;
pPre=pCur;
pCur=pNext;
point[i].x=x;
point[i].y=y;
//pDC->SetPixel(x,y,RGB(0,0,255));
break;
}
}
j++;
}
if(8==j)
break;
i++;
}

if(i>5)
{
int j=0;
while(j<i)
{
//pDC->SetPixel(point[j],RGB(0,0,255));
j++;
}
pt[1]=point[i/3];
pt[2]=point[i-1];
Circle circle ;
if(GetCircle(pt,&circle ))
{
if(CheckCircle(pData,sizeImage,&circle))
{
cir[k]=circle;
k++;
RemoveCircle(pData,sizeImage,&circle);
}
}
}
}
}
delete [] pImage;
Display(pDC,cir);
//TRACE(_T("%d,%dover\n"),sizeImage.cx,sizeImage.cy);
}
//这里做预处理,灰度,CANNY
UINT TransformThread(LPVOID lpv)
{
CHomework3Doc* pDoc=(CHomework3Doc*)lpv;
Bitmap* bmp=pDoc->m_pBitmap;
BitmapData data;
int PixelFormat=bmp->GetPixelFormat();
int ColorWidth=GetPixelFormatSize(PixelFormat);
ColorWidth>>=3;
Gdiplus::Rect r(0, 0, bmp->GetWidth(), bmp->GetHeight());
bmp->LockBits(&r, ImageLockModeRead | ImageLockModeWrite,PixelFormat, &data);
CSize sizeImage(data.Width,data.Height);
BYTE* pSrc=new BYTE[sizeImage.cx * sizeImage.cy];
BYTE* pDst=new BYTE[sizeImage.cx * sizeImage.cy];
BYTE* p = (BYTE*)data.Scan0;
BYTE* pa=pSrc;
BYTE* pe = p + data.Width * data.Height * ColorWidth;
for (; p < pe; p += ColorWidth)
{
if(ColorWidth<=1)
{
*pa=p[0];
}
else if(ColorWidth==2)
{
*pa=0.5*p[0]+0.5*p[1];
}
else if(ColorWidth==3 ||ColorWidth==4 )
{
*pa=0.3*p[0]+0.59*p[1]+0.11*p[2];
}
else
{
break;
}
pa++;
}

//Laplace(pSrc,sizeImage);
//MedianFilter(pSrc,TRUE);
//MedianFilter(pSrc,FALSE);
#if 1
Canny(pSrc,sizeImage,0.1,0.8,0.76,pDst);
RemoveNoise(pDst,sizeImage);
#else
SobelOperator(pDst,sizeImage,pdGrad);
int i=0;
while(i<sizeImage.cx*sizeImage.cy)
{
//*(pDst+i)=*(pSrc+i);
if(*(pdGrad+i)<0.8)
*(pDst+i)=255;
i++;
}
#endif

#if 0
p = (BYTE*)data.Scan0;
pa=pDst;
for(;p<pe;p+=ColorWidth)
{
int i=0;
while(i<ColorWidth)
{
p[i]=*pa;
i++;
}
pa++;
}
#endif
bmp->UnlockBits(&data);
HoughTransform(pDst,sizeImage);
delete [] pDst;
delete [] pSrc;
return 0;
}

...全文
600 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
yjz_uestc 2011-07-26
  • 打赏
  • 举报
回复
个人认为还是自己写比较好,比如做图像处理
evilsim 2011-05-12
  • 打赏
  • 举报
回复
帮顶。老师也让我写这代码。可惜完全写不出来啊。
peter_nj_RD 2011-02-07
  • 打赏
  • 举报
回复
呵呵,看来老毛的作业做的比较纠结啊! 话说,老师要求随机霍夫算法检测圆部分要自己写。 哇!写了这么多?过来膜拜一下!嘿嘿
贝隆 2011-02-06
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 kingjumby 的回复:]
OpenCV做好的为啥不用?
[/Quote]
+1
kingjumby 2011-02-05
  • 打赏
  • 举报
回复
OpenCV做好的为啥不用?

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧