OpenCV编写Adaboost源程序

来源:互联网 发布:mac os不支持银联 编辑:程序博客网 时间:2024/05/22 03:14

写在前面:

本文仅为记录编程经验和思路,所给程序并无识别作用(可能是由于特征太少)。


程序主要实现功能:

时间紧迫...这个程序效果很差,只能算个demo。但是还是实现了一下几个主要功能,代码全部为自己编写。
1. 完成了adaboost框架。
2. logistic二值分类作为弱分类器,使用梯度下降法计算(10w次迭代)得到。
3. 计算了几个简单的特征。(灰度均值,颜色均值,灰度方差)。实践表明这些特征不足以描述人脸特征(如果程序没问题的话)。


编程遇到的问题:

logistic回归也是有weighted形式的,类似的只要:在中加入w参数就行了。具体推到过程中,将权重参数w加入到似然函数指数中即可。

freopen("CON","r",stdin)表示回到控制台输入。


贴上自己的代码:(写的不规范,请见谅)。其中输入数据:pos.txt中记录正样本及target位置(可用ObjectMarker标出), neg.txt中记录负样本。

#include <opencv2\opencv.hpp>#include <cstring>#include <cstdio>#include <cmath>#include <ctime>using namespace cv;using std::memset;using std::pow;using std::fabs;using std::log;using std::exp;const int MAX_SAMPLES = 1000;const int MAX_DIMENSION = 200;//number of features;int dimension;int nsamples, npositive, nnegative;//features of image calculated by CALFEATURES functiondouble features[MAX_SAMPLES][MAX_DIMENSION];int isPositive[MAX_SAMPLES];double y[MAX_SAMPLES];//struct for weakclassifierconst int MAX_CLASSIFIER = 200;struct weakClassifier{//theta[0] = b;double theta[MAX_DIMENSION];//classifier vote weight;double alpha;double error;void clear(){for(int i = 0 ; i < MAX_DIMENSION; i++)theta[i] = 1;alpha = 0;error = 1;}double cal(double x[MAX_DIMENSION]){double ans = 0 ;for(int i = 0 ; i < dimension; i++)ans += theta[i]*x[i];return 1/(1 + exp(-ans));}}weakclassifier[MAX_CLASSIFIER];//parameter for adaboostint nweakclassifier = 100;double weight[MAX_SAMPLES];int calbystrongclassifier(double x[MAX_DIMENSION]){int ans = 0;for(int i = 0 ; i < nweakclassifier; i++){double temp = weakclassifier[i].cal(x);if(temp > 0.5)ans += weakclassifier[i].alpha * 1;elseans += weakclassifier[i].alpha * -1;}if(ans > 0)return 1;elsereturn -1;}//cal the feature of the imageint calfeatures(IplImage *inputImage, double features[MAX_DIMENSION]){int nfeatures = 0;int width = inputImage->width;int height = inputImage->height;double thisfeature;double ave;//create gray imageIplImage* gray = cvCreateImage(cvGetSize(inputImage),inputImage->depth,1);cvCvtColor(inputImage, gray, CV_BGR2GRAY);//cal histdouble hist[256];memset(hist, 0, sizeof(hist));for(int i = 0 ; i < gray->height; i++){for(int j = 0 ; j < gray->width; j++){//here it must be strongly converted to type-unsigned charint value = unsigned char(gray->imageData[i*gray->widthStep+j]);hist[value] += 1.0/gray->width/gray->height;}}//init features[0] = 1;features[nfeatures++] = 1;//cal 1st feature: average greythisfeature = 0;for(int i = 0 ; i < 256; i++)thisfeature += i*hist[i];features[nfeatures] = thisfeature;ave = thisfeature;nfeatures++;//cal 2st feature: average greenthisfeature = 0;int sumgreen = 0;for(int i = 0 ; i < height; i++){uchar* ptr = (uchar*)(inputImage->imageData + i * inputImage->widthStep);for(int j = 0 ; j < width; j++){int value = ptr[3*j];sumgreen += value;}}features[nfeatures] = sumgreen*1.0/width/height;ave = thisfeature;nfeatures++;//cal 3st feature: average redthisfeature = 0;int sumred = 0;for(int i = 0 ; i < height; i++){uchar* ptr = (uchar*)(inputImage->imageData + i * inputImage->widthStep);for(int j = 0 ; j < width; j++){int value = ptr[3*j+2];sumred += value;}}features[nfeatures] = sumred*1.0/width/height;ave = thisfeature;nfeatures++;//cal 4st feature: average bluethisfeature = 0;int sumblue = 0;for(int i = 0 ; i < height; i++){uchar* ptr = (uchar*)(inputImage->imageData + i * inputImage->widthStep);for(int j = 0 ; j < width; j++){int value = ptr[3*j+1];sumblue += value;}}features[nfeatures] = sumblue*1.0/width/height;ave = thisfeature;nfeatures++;//cal 5nd feature: grey variancethisfeature = 0;for(int i = 0 ; i < 256; i++)thisfeature += hist[i]*(i-features[0])*(i-features[0]);features[nfeatures] = sqrt(thisfeature*1.0);nfeatures++;cvReleaseImage(&gray);return nfeatures;}//train weak classifier using logisitic regressionweakClassifier trainweakclassifier(){weakClassifier ans;ans.clear();//cal parameter thetasfor(int k = 0 ; k < 100000; k++){int i = rand()%nsamples;int j = rand()%(dimension);ans.theta[j] = ans.theta[j] + weight[i]*0.01*(isPositive[i] - ans.cal(features[i]))*features[i][j];}//cal errorint rightnum = 0;for(int i = 0 ; i < nsamples; i++){double tmp = ans.cal(features[i]);if(tmp > 0.5 && isPositive[i] || tmp < 0.5 && isPositive[i] == false)rightnum ++;}ans.error = (nsamples - rightnum)*1.0/nsamples;//cal alphaans.alpha = 1.0/2*std::log((1-ans.error)/ans.error);return ans;}int main(){srand(int(time(0)));char filename[100];IplImage *inputImage = NULL;nsamples = npositive = nnegative = 0;//read the positive samples to cal the featuresfreopen("pos.txt","r",stdin);while(scanf("%s",filename)!=EOF){int num_1,x1,y1,width1, height1;scanf("%d%d%d%d%d",&num_1,&x1, &y1, &width1, &height1);CvRect roi = cvRect(x1, y1, width1, height1);inputImage = cvLoadImage(filename);cvSetImageROI(inputImage, roi);IplImage* temp = cvCreateImage(cvSize(width1, height1), inputImage->depth, inputImage->nChannels);cvCopy(inputImage, temp);//cvShowImage("a",temp);//cvWaitKey(0);cvReleaseImage(&inputImage);inputImage = NULL;dimension = calfeatures(temp,features[nsamples]);cvReleaseImage(&temp);isPositive[nsamples] = 1;y[nsamples] = 1;nsamples++;npositive++;}//output the features;freopen("CON","w",stdout);for(int i = 0 ; i < nsamples; i++){for(int j = 0 ; j < dimension; j++)printf("%lf ", features[i][j]);printf("\n ");}//read the negative samples to cal the featuresfreopen("neg.txt","r",stdin);while(scanf("%s",filename)!=EOF){inputImage = cvLoadImage(filename);dimension = calfeatures(inputImage, features[nsamples]);//cvShowImage("a",inputImage);//cvWaitKey(0);cvReleaseImage(&inputImage);isPositive[nsamples] = 0;y[nsamples] = -1;nsamples++;nnegative++;}//output the features;freopen("CON","w",stdout);for(int i = npositive ; i < nsamples; i++){for(int j = 0 ; j < dimension; j++)printf("%lf ", features[i][j]);printf("\n");}//adaboost frameworkfor(int i = 0 ; i < nsamples; i++){weight[i] = 1.0/nsamples;}for(int classifierindex = 0 ; classifierindex < nweakclassifier; classifierindex++){weakclassifier[classifierindex] = trainweakclassifier();double error = weakclassifier[classifierindex].error;double alpha = weakclassifier[classifierindex].alpha;if(error > 0.5 || alpha < 0)printf("Error: wrong classifier has been generated. %lf\n", error);printf("%d classifier: %lf\n",classifierindex, error);for(int i = 0 ; i < dimension; i++)printf("%lf ",weakclassifier[classifierindex].theta[i]);printf("\n");double identitysum = 0;for(int sampleindex = 0 ; sampleindex < nsamples; sampleindex++){if(weakclassifier[classifierindex].cal(features[sampleindex]) > 0.5)weight[sampleindex] *= exp(-alpha*y[sampleindex]*1);elseweight[sampleindex] *= exp(-alpha*y[sampleindex]*-1);identitysum += weight[sampleindex];}//reweightfor(int sampleindex = 0 ; sampleindex < nsamples; sampleindex++){weight[sampleindex] /= identitysum;}}double rightsum = 0;for(int i = 0 ; i < npositive; i++){if(calbystrongclassifier(features[i]) == 1 && isPositive[i] == 1)rightsum += 1;if(calbystrongclassifier(features[i]) == -1 && isPositive[i] == 0)rightsum += 1;}printf("测试集的准确率为:%lf\n", rightsum/nsamples);//testfreopen("CON","r",stdin);printf("please input the directory of test image\n");scanf("%s",filename);cvReleaseImage(&inputImage);inputImage = cvLoadImage(filename);cvShowImage("a",inputImage);//cvWaitKey(0);int width = inputImage->width;int height = inputImage->height;int ansx = 0, ansy = 0, answ = 0, ansh = 0;//cvShowImage("a",temp);//cvWaitKey(0);for(int x1 = 0 ; x1 < width; x1 += 10){for(int y1 = 0;  y1 < height; y1 += 10){for(int width1 = 100; x1 + width1 < width; width1 += 10){for(int height1 = 123; y1 + height1 < height; height1 += 10){IplImage* temp = cvCreateImage(cvSize(width1,height1),inputImage->depth, inputImage->nChannels);CvRect roi = cvRect(x1, y1, width1, height1);cvSetImageROI(inputImage, roi);cvCopy(inputImage,temp);cvResetImageROI(inputImage);double tempfeatures[MAX_DIMENSION];//cvShowImage("a",temp);//cvWaitKey(0);calfeatures(temp,tempfeatures);if(calbystrongclassifier( tempfeatures ) == 1){ansx = x1;ansy = y1;answ = width1;ansh = height1;cvShowImage("检测结果",temp);cvWaitKey(0);}cvReleaseImage(&temp);}}}}if(answ && ansh){IplImage* ans = cvCreateImage(cvSize(answ,ansh),inputImage->depth, inputImage->nChannels);cvSetImageROI(inputImage,cvRect(ansx,ansy,answ,ansh));cvCopy(inputImage, ans);cvShowImage("检测结果",ans);cvWaitKey(0);}else{printf("Can not detect.\n");}}



原创粉丝点击