opencv——pcb上寻找mark点(拟合椭圆的方法)

#include "stdafx.h"
// FitCircle.cpp : 定义控制台应用程序的入口


#include "cv.h"
#include "highgui.h"
#include "cxcore.h"
#include "cvaux.h"
#include <iostream>

using namespace cv;
using namespace std;
void main()
{

    int BasicGlobalThreshold(int*pg,int start,int end);
      CvBox2D findRectContours(IplImage *src);
    IplImage* imgGrey=cvLoadImage("5_000004.bmp",0);
    //IplImage* imgGrey=cvLoadImage("28027.jpg",0);
     cvNamedWindow("原始图像");
    //cvShowImage("fa",imgGrey);
    cvShowImage("原始图像",imgGrey);
    double t=(double)getTickCount();
   
    IplImage* imgBasicGlobalThreshold = cvCreateImage(cvGetSize(imgGrey),IPL_DEPTH_8U,1);
    cvCopyImage(imgGrey,imgBasicGlobalThreshold);
    int pg[256],i,thre; 
    for (i=0;i<256;i++) pg[i]=0;
    for (i=0;i<imgBasicGlobalThreshold->imageSize;i++) // 直方图统计
    pg[(BYTE)imgBasicGlobalThreshold->imageData[i]]++; 
    thre = BasicGlobalThreshold(pg,0,256); // 确定阈值
    cout<<"The Threshold of this Image in BasicGlobalThreshold is:"<<thre<<endl;//输出显示阀值

    cvThreshold(imgBasicGlobalThreshold,imgBasicGlobalThreshold,thre,255,CV_THRESH_BINARY); // 二值化 
    cvNamedWindow("二值图像");
    cvShowImage("二值图像",imgBasicGlobalThreshold);
    CvBox2D box=findRectContours(imgBasicGlobalThreshold);
    t=((double)getTickCount()-t)/getTickFrequency();
    cout<<t<<"  mark点坐标"<<box.center.x<<"\t"<<box.center.y<<endl<<"半径"<<box.size.width<<endl;

    cvWaitKey(0);

    
}

  CvBox2D findRectContours(IplImage *src)
{
   CvBox2D box1;
   IplImage* des=cvCreateImage(cvGetSize(src),src->depth,src->nChannels);
    cvZero(des);

    CvMemStorage* memory=cvCreateMemStorage(0);
    CvSeq* Icontour=NULL;
    CvSeq* maxContour =NULL;

    cvShowImage("原始图像1",src);
    cvFindContours(src,memory,&Icontour, sizeof(CvContour),CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE,cvPoint(0,0));
    double area=0;
    double maxArea=0;
     
    while(Icontour)
    {
        area=fabs(cvContourArea(Icontour,CV_WHOLE_SEQ));
        //cout<<area<<endl;
        //cvDrawContours(src, Icontour,
        //    CV_RGB(255,255,255), CV_RGB(255, 255,255),
        //    0, 1, 8, cvPoint(0,0));
        //
        if(area>500 && area<20000)
        {
            goto l1;
           
        }
        else
            goto l2;
l1:        CvBox2D box0=cvFitEllipse2(Icontour);
        float a=(float)box0.size.height/(float)box0.size.width;
        //cout<<area<<endl;
        if(fabs(a)<=1.5)
        {
            cvDrawContours(des, Icontour,
            CV_RGB(255,255,255), CV_RGB(255, 255,255), 0, 1, 8, cvPoint(0,0));
            box1=box0;
        
         cvDrawCircle(des,cvPoint(box0.center.x,box0.center.y),1,cvScalar(255,255,255),2,8,0);
        //cvDrawContours(des,maxContour,cvScalar(0,0,255),cvScalar(0,0,255),1,1,0,cvPoint(0,0));
        
        
        }
        //    maxContour = Icontour;
            
l2:      Icontour =Icontour->h_next;
    }
       cvShowImage("fds",des);
    
    return box1;
    
}
/*============================================================================
=  代码内容:基本全局阈值法   迭代法                            
==============================================================================*/
int BasicGlobalThreshold(int*pg,int start,int end)
{       
    
    //  基本全局阈值法


    int  i,t,t1,t2,k1,k2;
    double u,u1,u2;    
    t=0;     
    u=0;
    for (i=start;i<end;i++) 
    {
        t+=pg[i];        
        u+=i*pg[i];
    }
    k2=(int) (u/t);                          //  计算此范围灰度的平均值    
    do 
    {
        k1=k2;
        t1=0;    
        u1=0;
        for (i=start;i<=k1;i++) 
        {             //  计算低灰度组的累加和
            t1+=pg[i];    
            u1+=i*pg[i];
        }
        t2=t-t1;
        u2=u-u1;
        if (t1) 
            u1=u1/t1;                     //  计算低灰度组的平均值
        else 
            u1=0;
        if (t2) 
            u2=u2/t2;                     //  计算高灰度组的平均值
        else 
            u2=0;
        k2=(int) ((u1+u2)/2);                 //  得到新的阈值估计值
    }
    while(k1!=k2);                           //  数据未稳定,继续
    //cout<<"The Threshold of this Image in BasicGlobalThreshold is:"<<k1<<endl;
    return(k1);                              //  返回阈值
}

posted @ 2013-12-29 16:23  nanyangzp  阅读(3774)  评论(0编辑  收藏  举报