耗时一周,终告完成。喜欢就拿去。

#include "cv.h"
#include <windows.h>
#include "highgui.h"
#include <cvaux.h>
#include <cxcore.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <cvcam.h>
#include <iostream.h>
#include<stdio.h>
double zt;

int area_max(CvSeq* contours,int g);
int main( int argc, char** argv )
{  
    //
 CvCapture* capture=cvCaptureFromCAM(0);//打开摄像头
 cvWaitKey(50);//使摄像头稳定
 //-------------------获取当前帧---------
    IplImage* src_img;
 cvNamedWindow( "cam", CV_WINDOW_AUTOSIZE );
 IplImage* dst_img;
 ShellExecute(NULL,"open","car.exe",NULL,NULL,SW_SHOWNORMAL); //将本程序计算得到的旋转信息送入car.exe ,这个程序可以自己写,主要是一个小车控制的程序,这个很简单,自己动下手。
 while(cvWaitKey()!=27)
 {
 src_img=cvQueryFrame(capture);

 CvBox2D box;
 CvPoint pt0, pt;
 CvPoint2D32f box_vtx[4];
 CvMemStorage* storage = cvCreateMemStorage(0);
 CvSeq* contours = cvCreateSeq( CV_SEQ_KIND_GENERIC|CV_32SC2, sizeof(CvContour),
                                    sizeof(CvPoint), storage );
 IplImage* img = cvCreateImage( cvSize(src_img->width,src_img->height), 8, 1 );
 dst_img =cvCloneImage(src_img);
    cvCvtColor( src_img, dst_img, CV_BGR2HSV );
    CvScalar c;
    int color_fix = 30;//h色度,s饱和度,v亮度,30是检测绿色的
    for(int y =0 ;y<src_img->height; y++)
        for(int x =0;x<src_img->width;x++ )
        {
           
            c = cvGetAt(dst_img,y,x); //row i, column j
            int h  = (int)c.val[0];   
            int s = (int)c.val[1];
            int v  =  (int)c.val[2];

            //catch the green points
            c = cvGetAt(src_img,y,x); //row i, column j
            int blue  = (int)c.val[0];   
            int green = (int)c.val[1];
            int red  =  (int)c.val[2];           
           
            int fixplus_hue = (abs(60 + color_fix)%255);
            int fixsub_hue = (abs(60 - color_fix)%255);
            if ( (h<fixplus_hue) && (h>fixsub_hue) && (s>40) && (v>60)) 
            {                
                ((uchar*)(dst_img->imageData + dst_img->widthStep*y))[x*3] = 255;
                ((uchar*)(dst_img->imageData + dst_img->widthStep*y))[x*3+1] = 255;
                ((uchar*)(dst_img->imageData + dst_img->widthStep*y))[x*3+2] = 255;
            }
            else
            {

                ((uchar*)(dst_img->imageData + dst_img->widthStep*y))[x*3] = 0;
                ((uchar*)(dst_img->imageData + dst_img->widthStep*y))[x*3+1] = 0;
                ((uchar*)(dst_img->imageData + dst_img->widthStep*y))[x*3+2] = 0;
            }
        } 
  cvSmooth(dst_img, dst_img,  CV_GAUSSIAN, 5, 5, 0,0);
  cvErode(dst_img,dst_img,0,4);//膨胀
        cvDilate(dst_img,dst_img,0,4);//腐蚀
     cvCvtColor( dst_img, dst_img, CV_HSV2BGR ); 
        cvCvtColor( dst_img, img, CV_BGR2GRAY);
  cvThreshold(img,img,0,255,CV_THRESH_BINARY);//图像二值化
  //cvAdaptiveThreshold( img, img, 255,CV_ADAPTIVE_THRESH_MEAN_C,CV_THRESH_BINARY,3, 5 );
   
     int g=cvFindContours( img, storage, &contours, sizeof(CvContour),
                        CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0) );//目标物要为白色
  if(g!=0&&g<5)
  {
  int yv=area_max(contours,g);
       ////////////////////////////////////////
  for(int uu=0;uu<yv;uu++)
  {
   contours=contours->h_next;
  }
  box = cvMinAreaRect2(contours, 0);
  cvBoxPoints( box, box_vtx );//计算四个角坐标
  pt0.x = cvRound(box_vtx[3].x);
        pt0.y = cvRound(box_vtx[3].y);
        for( int i = 0; i < 4; i++ )
        {
         pt.x = cvRound(box_vtx[i].x);
         pt.y = cvRound(box_vtx[i].y);
         cvLine(src_img, pt0, pt, CV_RGB(255, 0, 0), 1, CV_AA, 0);
         pt0 = pt;
        }
        int x[4][2],j,a,b;
        for(i=0;i<4;i++)
  {
         x[i][0]=box_vtx[i].x;
         x[i][1]=box_vtx[i].y;
  }
        for(i=0;i<4;i++)
  {
         for(j=i;j<4;j++)
   {
          if(x[i][0]<x[j][0]) //如需逆序,i,j位置换下
    {
           a=x[i][0];
           x[i][0]=x[j][0];
           x[j][0]=a;
        b=x[i][1];
           x[i][1]=x[j][1];
           x[j][1]=b;
    }
   }
  }
  double px[2][2]={0};
  if(x[0][1]<x[1][1])
  {
   px[0][0]=x[0][0];
         px[0][1]=x[0][1];
  }
  else
  {
   px[0][0]=x[1][0];
         px[0][1]=x[1][1];
  }

  if(x[2][1]<x[3][1])
  {
         px[1][0]=x[2][0];
         px[1][1]=x[2][1];
  }
  else
  {
         px[1][0]=x[3][0];
         px[1][1]=x[3][1];
  }
        //px为四个角的排序,最大角为75,超过判断方法失效 
   double t[1][1];
      CvMat* f=cvCreateMat(1,1,CV_64F); /* 每幅图像的旋转向量 */
   if(px[0][1]<px[1][1])
   {
    if(box.angle>5)
    {
     cout<<"左"<<box.angle<<endl;
     zt=1;
           t[0][0]=box.angle;
         cvSetData(f,t,f->step);
        cvSave("datae.XML",f);
     cvWaitKey(50);
    }
    else
    {
     cout<<"前"<<endl;
     zt=3;
    }
   }
      if(px[0][1]>px[1][1])
   {
    if(90-box.angle>5)
    {
     cout<<"右"<<90-box.angle<<endl;
           zt=2;
     t[0][0]=90-box.angle;
         cvSetData(f,t,f->step);
        cvSave("datae.XML",f);
     cvWaitKey(50);
    }
     else
    {
     cout<<"前"<<endl;
     zt=3;
    }
   }
   cvShowImage("cam",src_img);
         cvWaitKey(10);
  }
  else
  {
          cout<<zt<<endl;
  }
     double t_date[1][1];
        t_date[0][0]=zt;
     CvMat* rr=cvCreateMat(1,1,CV_64F); /* 每幅图像的旋转向量 */
      cvSetData(rr,t_date,rr->step);
  cvSave("data.XML",rr);
  cvWaitKey(10);
  }
        return 0;
}


int area_max(CvSeq* contours,int g)
{      
       double area[20][2]={0};
  double aread=0;
  int cot;
      aread=fabs(cvContourArea(contours,CV_WHOLE_SEQ));
        area[0][0]=aread;
        area[0][1]=0;
  for(int bv=1;bv<g;bv++)
  {
         aread=fabs(cvContourArea(contours->h_next,CV_WHOLE_SEQ));
   area[bv][0]=aread;
         area[bv][1]=bv;
   contours=contours->h_next;
  }
  double cc=0;
        for(int i=0;i<g;i++)
  {
   if(cc<area[i][0])
   {
   cc=area[i][0];
      cot=i;
   }
  }
  return cot;
}

posted on 2010-07-11 20:18  kong_weixi  阅读(383)  评论(0编辑  收藏  举报