耗时一周,终告完成。喜欢就拿去。
#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;
}