opencv——拟合圆

#include "stdafx.h"
#include "cv.h"
#include "highgui.h"
#include "cxcore.h"
#include "cvaux.h"
#include <iostream>
#include"Timer.h"
using namespace std;
int otsu2 (IplImage *image);
CvBox2D findRectContours(const IplImage *gray);
void main()
{
    
     IplImage* img =cvLoadImage("mark1.jpg",0);
    // cvCopyImage(srcImgGrey,img0tsu);
     MyTimer mt;
     mt.Reset();
     mt.Start();
     //Sleep(1000);
     
     int thre2;
     thre2 = otsu2(img);
     //cout<<"The Threshold of this Image in Otsu is:"<<thre2<<endl;//输出显示阀值
     cvThreshold(img,img,thre2,255,CV_THRESH_BINARY); // 二值化 
     
                                                                                                                                                              
    // CvMemStorage * storage = cvCreateMemStorage(0);
    // CvSeq * contour = 0;

     //cvFindContours(img,storage,&contour,sizeof(CvContour),1,2);
      CvBox2D box=findRectContours(img);
      mt.End();
     
      cout<<box.center.x<<endl<<box.center.y<<endl<<box.size.height<<endl<<box.size.width<<endl<<mt.costTime<<endl;
      cvDrawCircle(img,cvPoint(box.center.x,box.center.y),1,cvScalar(255,255,255),2,8,0);
         cvNamedWindow("img", CV_WINDOW_AUTOSIZE );
      cvShowImage( "img", img);//显示图像 
     cvReleaseImage(&img);
     cvWaitKey(0);




}

CvBox2D findRectContours(const IplImage *gray)
{
    
    
    CvBox2D box;

    CvSeq* firstContour = NULL;
    CvMemStorage* storage = cvCreateMemStorage(0);
    IplImage* contourImg = cvCreateImage(cvGetSize(gray), gray->depth, 1);
    cvCopy(gray, contourImg);
     cvFindContours(contourImg, storage, &firstContour, sizeof(CvContour), 1,2);
    CvSeq* maxContour = firstContour;
    CvSeq* Contour = firstContour;
    while(Contour)
    {
        if(maxContour->total <  Contour->total)
        {
            maxContour = Contour;
        }
        Contour = Contour->h_next;
    }

    if(maxContour)
    {
         box = cvFitEllipse2(maxContour);
        // CvPoint2D32f cross;
        // float radius;
          //cvMinEnclosingCircle(maxContour,&cross,&radius);
     //   cout<<cross.x<<endl<<cross.y<<endl;
        //box.center.x=cross.x;box.center.y=cross.y;box.size.width=radius;
    }
    //cvDrawContours(contourImg,maxContour,cvScalar(0,0,255),cvScalar(0,0,255),1,1,0,cvPoint(0,0));
    cvReleaseMemStorage(&storage);
    return box;
}
/*======================================================================*/
/* OTSU global thresholding routine */
/*======================================================================*/
int otsu2 (IplImage *image)
{
    int w = image->width;
    int h = image->height;

    unsigned char*np; // 图像指针
    unsigned char pixel;
    int thresholdValue=1; // 阈值
    int ihist[256]; // 图像直方图,256个点

    int i, j, k; // various counters
    int n, n1, n2, gmin, gmax;
    double m1, m2, sum, csum, fmax, sb;

    // 对直方图置零...
    memset(ihist, 0, sizeof(ihist));

    gmin=255; gmax=0;
    // 生成直方图
    for (i =0; i < h; i++) 
    {
        np = (unsigned char*)(image->imageData + image->widthStep*i);
        for (j =0; j < w; j++) 
        {
            pixel = np[j];
            ihist[ pixel]++;
            if(pixel > gmax) gmax= pixel;
            if(pixel < gmin) gmin= pixel;
        }
    }

    // set up everything
    sum = csum =0.0;
    n =0;

    for (k =0; k <=255; k++) 
    {
        sum += k * ihist[k]; /* x*f(x) 质量矩*/
        n += ihist[k]; /* f(x) 质量 */
    }

    if (!n) 
    {
        // if n has no value, there is problems...
        //fprintf (stderr, "NOT NORMAL thresholdValue = 160
");
        thresholdValue =160;
        goto L;
    }

    // do the otsu global thresholding method
    fmax =-1.0;
    n1 =0;
    for (k =0; k <255; k++) 
    {
        n1 += ihist[k];
        if (!n1) { continue; }
        n2 = n - n1;
        if (n2 ==0) { break; }
        csum += k *ihist[k];
        m1 = csum / n1;
        m2 = (sum - csum) / n2;
        sb = n1 * n2 *(m1 - m2) * (m1 - m2);
        /* bbg: note: can be optimized. */
        if (sb > fmax)
        {
            fmax = sb;
            thresholdValue = k;
        }
    }

L:
    for (i =0; i < h; i++) 
    {
        np = (unsigned char*)(image->imageData + image->widthStep*i);
        for (j =0; j < w; j++) 
        {
            if(np[j] >= thresholdValue)
                np[j] =255;
            else np[j] =0;
        }
    }

    //cout<<"The Threshold of this Image in Otsu is:"<<thresholdValue<<endl;
    return(thresholdValue);
}

原文地址:https://www.cnblogs.com/nanyangzp/p/3496517.html