ZUDN

博客园 首页 新随笔 联系 订阅 管理

#include <fstream.h>
#include <iostream.h>
#include <iomanip.h>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <malloc.h>
#include <conio.h>
#include <math.h>
#include <WINDEF.H>
#include  "cv.h"
#include "highgui.h"
#include "svm.h"
#include "malloc.h"
#define Malloc(type,n) (type *)malloc((n)*sizeof(type))

class CBmp
{
public:
// 图像匹配
//图像平移

 double *  contrastvector(IplImage *src);  //由图像计算得出16为对比度特征
 struct svm_model * Mysvmtrain(struct svm_parameter param,struct svm_problem prob);//计算训练图像文件夹,得到对比度与能见度,得到训练好的模型
    double Mysvmtest(struct svm_model * model,double *cutcondata); //将测试对比度值输入训练好模型,输出能见度
 struct svm_parameter setmyparameter();
 void do_corss_validation();
 struct svm_problem setmyproblem(char *ImageName,char *NameVisibility);
 CBmp();
    virtual ~CBmp();

    double * cutcondata;
 struct svm_parameter param;  // set by parse_command_line
    struct svm_problem prob;
 struct svm_node *x_space;// set by read_problem
 struct svm_model *model;

};

CBmp::CBmp()
{
 cutcondata=NULL;
 cutcondata=new double[16];
 prob.y=NULL;
 prob.x=NULL;
 model=NULL;
}

CBmp::~CBmp()
{
 if(cutcondata!=NULL)
 {
  delete [] cutcondata;
  cutcondata = NULL;
 }
  if (prob.y!=NULL)
  {
   free (prob.y);
  }
 
  if (prob.x!=NULL)
  {
   free (prob.x);
  }
 if (&param!=NULL)
 {
  svm_destroy_param(&param);
 }
 if (model!=NULL)
 {
  svm_destroy_model(model);
 }
}

//图像匹配
//图像平移

//////////////////////////////
//计算图像对比度,作为图像特征
//////////////////////////////
double * CBmp::contrastvector(IplImage *src)
{
 if( src == 0 )
  return 0;
 int **imggray;
 imggray=NULL;
 double **condata;
 condata=NULL;
    int height,width;
    IplImage* pImg8u;// 声明IplImage 变量,用于图像格式转换
 cvSetImageROI( src, cvRect(0,10,600,400)); //设置ROI区域
 pImg8u = cvCreateImage(cvGetSize(src), 8, 1); //创建1位8通道图像
    cvCvtColor(src, pImg8u, CV_BGR2GRAY);//灰度化
 cvResetImageROI(src); //重置ROI参数
 height=pImg8u->height;//得到图像的高
 width=pImg8u->width;//得到图像的宽
 imggray=new int *[height];  //动态二维数组,分配内存
 for(int i=0;i<height;i++)
       imggray[i]=new int [width];
 for(i=0;i<height;i++)      //二维数组初始化为0
        for(int j=0;j<width;j++)
           imggray[i][j]=0;
  
  //图像灰度值输入imggray[][],为后面计算对比度值
  CvScalar s;
  for( i=0;i<height;i++)
  {
   for(int j=0;j<width;j++)
   {
    s=cvGet2D(pImg8u,i,j); //得到像素点(i,j)的RGB值
    int gray=s.val[0];     // 灰度图像R=G=B=gray
    imggray[i][j]=gray;
   }
  }
  double ap=0,cp=0;
  double contrast=0;
  int tp=0;
  double temp=0;
  condata=new double*[height];
  for(i=0;i<height;i++)
   condata[i]=new double[width];//存储对比度值矩阵,二维动态数组
  for(i=0;i<height;i++)//读取imggray[][]中存储的灰度值
  {
   for(int j=0;j<width;j++)
    
    if(j<=0)  //越界
     ap=0;
    else     //比较该点与左邻域点的对比度值
    {
     tp=max(imggray[i][j],imggray[i][j-1]);
     if (tp=0)
      ap=0;
     else
         ap=abs(imggray[i][j]-imggray[i][j-1]);
     tp=max(imggray[i][j],imggray[i][j-1]);
     ap=ap/tp;
     }
    }
    if(i<=0)
     cp=0;
    else   //比较该点与上邻域点的对比度值
     
    {
     tp=max(imggray[i][j],imggray[i-1][j]);
     if (tp=0)
      cp=0;
     else
       cp=abs(imggray[i][j]-imggray[i-1][j]);
     tp=max(imggray[i][j],imggray[i-1][j]);
     cp=cp/tp;
     }
    }
    contrast=max(ap,cp);
    contrast=max(contrast,0);
    condata[i][j]=contrast;
   }
  }

 int n=0;
    int j,k,w;
    double sumcon=0;
 double avercon=0;
 double nn=height*width/(16);
// cutcondata=new double[16];
 for(i=0;i<(16);i++)
  cutcondata[i]=0;
 
    for(i=0;i<=3;i++)
 {
  for(j=0;j<=3;j++)
  {
   for(k=i*height/4;k<(i+1)*height/4;k++)
   {
    for(w=j*width/4;w<(j+1)*width/4;w++)
    {
     sumcon+=condata[k][w];
    }
     
   avercon=sumcon/nn;
   avercon=max(avercon,0);
   cutcondata[n]=avercon;
   sumcon=0;
   n++;
  }
 }
 cvReleaseImage(&pImg8u);
 if(condata!=NULL)
 {
  for(int k=0;k<height;k++)//清除内存
   delete condata[k];
  delete []condata;
//  condata=NULL;
 }
    if(imggray!=NULL)
 {
  for(int k=0;k<height;k++)
   delete imggray[k];
  delete []imggray;
//  imggray=NULL;
 }

 return cutcondata;
}
///////////////////////////////////////////////
///设置svm训练参数
///////////////////////////////////////////////
struct svm_parameter CBmp::setmyparameter()
{
 //svm_type可以是C_SVC、NU_SVC、ONE_CLASS、EPSILON_SVR或NU_SVR其中的一种。
 // C_SVC: C-SVM 分类 NU_SVC: nu-SVM 分类 ONE_CLASS: one-class-SVM EPSILON_SVR: epsilon-SVM回归 NU_SVR: nu-SVM回归
 param.kernel_type = RBF;  //核函数类型RBF
 
 param.degree = 3;         //核函数中的degree设置(默认3)
 param.gamma = 0.0012; // 核函数中的gamma函数设置,默认1/k,1/num_features
 param.coef0 = 0.01;      //核函数中的coef0设置(默认0)
 param.nu = 0.1;        //设置v-SVC,一类SVM和v- SVR的参数(默认0.5)
 param.cache_size = 100;  //设置cache内存大小,以MB为单位(默认40)
 param.C = 10000;           //设置C-SVC,e -SVR和v-SVR损失函数(默认1)
 param.eps = 1e-3;      //设置允许的终止判据(默认0.001)
 param.p = 10000;       //设置e -SVR 中损失函数p的值(默认0.1)
 param.shrinking = 0;  //是否采用启发式,0或1(默认1)
 param.probability = 0;
 param.nr_weight = 10;
 param.weight_label = NULL;
 param.weight = NULL;   //设置第几类的参数C为weight?C(C-SVC中的C)(默认1)
 
    param.svm_type=NU_SVR;
 return param;
}
////////////////////////////////////////////
//设置svm训练数据
////////////////////////////////////////////
struct svm_problem CBmp::setmyproblem(char *ImageName,char *NameVisibility)
{
// char * endptr;
 char *p;
 int a;
 double v;
 double vi;

 ifstream fin1(ImageName);
 ifstream fin2(NameVisibility);
 double *cutcondata=NULL;
 const int LINE_LENGTH = 70;
 char *model_file_name ="svm.model";   //保存训练完的模型名称
 char str1[420][LINE_LENGTH];//创建二维字符串数组,可存放850行,每行存放40个字符。
 char str2[420][30];   //存放能见度

 int i=0;
 IplImage* img;
 
 while(fin1.getline(str1[i],LINE_LENGTH))
 {
  i++;
 }
 prob.l=i;
 prob.y = Malloc(double,prob.l);
 prob.x = Malloc(struct svm_node *,prob.l);
 x_space = Malloc(struct svm_node,(17*prob.l));
 fin1.clear();
 fin1.seekg(0);//重新将指针定位到文件流头部
 i=0;
 while( fin1.getline(str1[i],LINE_LENGTH) )//按行读入info2.txt中字符串,读入str数组
 {
  fin2.getline(str2[i],30);
  p=strstr(str1[i],"2");
  a=strncmp(p,str2[i],16);
  if (a==0)
  {
   img=cvLoadImage(str1[i],1);//载入图像
   prob.x[i]=&x_space[i*17];
   cutcondata=contrastvector(img);//计算对比度
   for (int j=0;j<16;j++)
   {
    x_space[i*17+j].index=j+1;
    x_space[i*17+j].value=cutcondata[j];
   }
   x_space[17*i+16].index=-1;
   p=strtok(str2[i],"\t");
   p=strtok(NULL,"\t");
   v=atof(p);
   vi=(v-500)/19500;
   prob.y[i]=vi;
   cvReleaseImage(&img);
   i++;
  }
 }
 fin2.close();
 fin1.close();

 // ofstream fout("test_visibility.txt");//数据输出到shuju_gan1.txt中
 // for (i=0;i<prob.l;i++)
 // {
 //  fout<<"第"<<i<<"幅图像的能见度与对比度值:\n";
 //  fout<<setiosflags(ios::left)<<prob.y[i];
 //  for (int j=0;j<16;j++)
 //  {
 //   fout<<setiosflags(ios::left)<<"\t"<<prob.x[i][j].index<<":"<<prob.x[i][j].value;
 //  }
 //  fout<<endl;
 // }
 // fout.close();
  return prob;

}
///////////////////////////////
//交叉优化
////////////////////////////////
void CBmp::do_corss_validation()
{
 
 int i;
 int total_correct = 0;
 double total_error = 0;
 int    nr_fold=10;
 double sumv = 0, sumy = 0, sumvv = 0, sumyy = 0, sumvy = 0;
 double *target = Malloc(double,prob.l);

 svm_cross_validation(&prob,&param,nr_fold,target);
 if(param.svm_type == EPSILON_SVR ||
    param.svm_type == NU_SVR)
 {
  for(i=0;i<prob.l;i++)
  {
   double y = prob.y[i];
   double v = target[i];
   total_error += (v-y)*(v-y);
   sumv += v;
   sumy += y;
   sumvv += v*v;
   sumyy += y*y;
   sumvy += v*y;
  }
 
 }
 else
 {
  for(i=0;i<prob.l;i++)
   if(target[i] == prob.y[i])
    ++total_correct;
 // printf("Cross Validation Accuracy = %g%%\n",100.0*total_correct/prob.l);
 }
 free(target);
}
////////////////////////////////////////////////////////////
//遍历训练图像文件夹,计算出对比度与能见度,训练SVM回归模型
///////////////////////////////////////////////////////////
struct svm_model * CBmp::Mysvmtrain(struct svm_parameter param,struct svm_problem prob)
{

 char model_file_name[]="svm.model";

// do_corss_validation();
 model=svm_train(&prob,&param);
 svm_save_model(model_file_name,model);
// free(prob.y);
// free(prob.x);
// free(x_space);
 return model;


}
/////////////////////////////////////////////////////////////////
//测试
/////////////////////////////////////////////////////////////////
double CBmp::Mysvmtest(struct svm_model * model,double * cutcondata)
{
 struct svm_node * testcondata;//将对比度格式转换为svm_node型
 testcondata = Malloc(struct svm_node,17);//为testcondata分配内存,存储16维对比度
    for (int i=0;i<16;i++)
 {
      testcondata[i].index=(i+1);
   testcondata[i].value=cutcondata[i];
 }
 testcondata[16].index=-1;
 double testvisibility;
 testvisibility=svm_predict(model,testcondata);   //释放内存testcondata);//计算得出的测试能见度值,
   free (testcondata);
 return testvisibility;    //输出计算得出的能见度值
}


int main()
 
    CBmp Bitmap;
 struct svm_model * model;
 struct svm_parameter param;
 struct svm_problem prob;
 char *ImageName="D:\\MyProjects\\dayvisibility\\trainimage\\info.txt";
 char *NameVisibility="D:\\MyProjects\\dayvisibility\\trainimage\\trainnamevisibility.txt";
 const int LINE_LENGTH = 70;
 char str1[420][LINE_LENGTH];//创建二维字符串数组,可存放850行,每行存放40个字符。

 param=Bitmap.setmyparameter();
 prob=Bitmap.setmyproblem(ImageName,NameVisibility);
 model=Bitmap.Mysvmtrain(param,prob);
 
 char * filename=(char *)("2010051711172501.bmp");
 IplImage *img=cvLoadImage(filename,1);

 double* contrast_vector=Bitmap.contrastvector(img);

 double visi=Bitmap.Mysvmtest(model,contrast_vector);
 double visibility=19500*visi+500;
 cout<<endl<<endl<<visibility<<endl;
 getch();
return 1;


}

posted on 2011-08-29 15:50  ZUDN  阅读(3394)  评论(1编辑  收藏  举报