| /*M/////////////////////////////////////////////////////////////////////////////////////// |
| // |
| // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. |
| // |
| // By downloading, copying, installing or using the software you agree to this license. |
| // If you do not agree to this license, do not download, install, |
| // copy or use the software. |
| // |
| // |
| // Intel License Agreement |
| // |
| // Copyright (C) 2000, Intel Corporation, all rights reserved. |
| // Third party copyrights are property of their respective owners. |
| // |
| // Redistribution and use in source and binary forms, with or without modification, |
| // are permitted provided that the following conditions are met: |
| // |
| // * Redistribution's of source code must retain the above copyright notice, |
| // this list of conditions and the following disclaimer. |
| // |
| // * Redistribution's in binary form must reproduce the above copyright notice, |
| // this list of conditions and the following disclaimer in the documentation |
| // and/or other materials provided with the distribution. |
| // |
| // * The name of Intel Corporation may not be used to endorse or promote products |
| // derived from this software without specific prior written permission. |
| // |
| // This software is provided by the copyright holders and contributors "as is" and |
| // any express or implied warranties, including, but not limited to, the implied |
| // warranties of merchantability and fitness for a particular purpose are disclaimed. |
| // In no event shall the Intel Corporation or contributors be liable for any direct, |
| // indirect, incidental, special, exemplary, or consequential damages |
| // (including, but not limited to, procurement of substitute goods or services; |
| // loss of use, data, or profits; or business interruption) however caused |
| // and on any theory of liability, whether in contract, strict liability, |
| // or tort (including negligence or otherwise) arising in any way out of |
| // the use of this software, even if advised of the possibility of such damage. |
| // |
| //M*/ |
| |
| #include "_ml.h" |
| |
| #if 0 |
| |
| ML_IMPL int |
| icvCmpIntegers (const void* a, const void* b) {return *(const int*)a - *(const int*)b;} |
| |
| /****************************************************************************************\ |
| * Cross-validation algorithms realizations * |
| \****************************************************************************************/ |
| |
| // Return pointer to trainIdx. Function DOES NOT FILL this matrix! |
| ML_IMPL |
| const CvMat* cvCrossValGetTrainIdxMatrix (const CvStatModel* estimateModel) |
| { |
| CvMat* result = NULL; |
| |
| CV_FUNCNAME ("cvCrossValGetTrainIdxMatrix"); |
| __BEGIN__ |
| |
| if (!CV_IS_CROSSVAL(estimateModel)) |
| { |
| CV_ERROR (CV_StsBadArg, "Pointer point to not CvCrossValidationModel"); |
| } |
| |
| result = ((CvCrossValidationModel*)estimateModel)->sampleIdxTrain; |
| |
| __END__ |
| |
| return result; |
| } // End of cvCrossValGetTrainIdxMatrix |
| |
| /****************************************************************************************/ |
| // Return pointer to checkIdx. Function DOES NOT FILL this matrix! |
| ML_IMPL |
| const CvMat* cvCrossValGetCheckIdxMatrix (const CvStatModel* estimateModel) |
| { |
| CvMat* result = NULL; |
| |
| CV_FUNCNAME ("cvCrossValGetCheckIdxMatrix"); |
| __BEGIN__ |
| |
| if (!CV_IS_CROSSVAL (estimateModel)) |
| { |
| CV_ERROR (CV_StsBadArg, "Pointer point to not CvCrossValidationModel"); |
| } |
| |
| result = ((CvCrossValidationModel*)estimateModel)->sampleIdxEval; |
| |
| __END__ |
| |
| return result; |
| } // End of cvCrossValGetCheckIdxMatrix |
| |
| /****************************************************************************************/ |
| // Create new Idx-matrix for next classifiers training and return code of result. |
| // Result is 0 if function can't make next step (error input or folds are finished), |
| // it is 1 if all was correct, and it is 2 if current fold wasn't' checked. |
| ML_IMPL |
| int cvCrossValNextStep (CvStatModel* estimateModel) |
| { |
| int result = 0; |
| |
| CV_FUNCNAME ("cvCrossValGetNextTrainIdx"); |
| __BEGIN__ |
| |
| CvCrossValidationModel* crVal = (CvCrossValidationModel*) estimateModel; |
| int k, fold; |
| |
| if (!CV_IS_CROSSVAL (estimateModel)) |
| { |
| CV_ERROR (CV_StsBadArg, "Pointer point to not CvCrossValidationModel"); |
| } |
| |
| fold = ++crVal->current_fold; |
| |
| if (fold >= crVal->folds_all) |
| { |
| if (fold == crVal->folds_all) |
| EXIT; |
| else |
| { |
| CV_ERROR (CV_StsInternal, "All iterations has end long ago"); |
| } |
| } |
| |
| k = crVal->folds[fold + 1] - crVal->folds[fold]; |
| crVal->sampleIdxTrain->data.i = crVal->sampleIdxAll + crVal->folds[fold + 1]; |
| crVal->sampleIdxTrain->cols = crVal->samples_all - k; |
| crVal->sampleIdxEval->data.i = crVal->sampleIdxAll + crVal->folds[fold]; |
| crVal->sampleIdxEval->cols = k; |
| |
| if (crVal->is_checked) |
| { |
| crVal->is_checked = 0; |
| result = 1; |
| } |
| else |
| { |
| result = 2; |
| } |
| |
| __END__ |
| |
| return result; |
| } |
| |
| /****************************************************************************************/ |
| // Do checking part of loop of cross-validations metod. |
| ML_IMPL |
| void cvCrossValCheckClassifier (CvStatModel* estimateModel, |
| const CvStatModel* model, |
| const CvMat* trainData, |
| int sample_t_flag, |
| const CvMat* trainClasses) |
| { |
| CV_FUNCNAME ("cvCrossValCheckClassifier "); |
| __BEGIN__ |
| |
| CvCrossValidationModel* crVal = (CvCrossValidationModel*) estimateModel; |
| int i, j, k; |
| int* data; |
| float* responses_fl; |
| int step; |
| float* responses_result; |
| int* responses_i; |
| double te, te1; |
| double sum_c, sum_p, sum_pp, sum_cp, sum_cc, sq_err; |
| |
| // Check input data to correct values. |
| if (!CV_IS_CROSSVAL (estimateModel)) |
| { |
| CV_ERROR (CV_StsBadArg,"First parameter point to not CvCrossValidationModel"); |
| } |
| if (!CV_IS_STAT_MODEL (model)) |
| { |
| CV_ERROR (CV_StsBadArg, "Second parameter point to not CvStatModel"); |
| } |
| if (!CV_IS_MAT (trainData)) |
| { |
| CV_ERROR (CV_StsBadArg, "Third parameter point to not CvMat"); |
| } |
| if (!CV_IS_MAT (trainClasses)) |
| { |
| CV_ERROR (CV_StsBadArg, "Fifth parameter point to not CvMat"); |
| } |
| if (crVal->is_checked) |
| { |
| CV_ERROR (CV_StsInternal, "This iterations already was checked"); |
| } |
| |
| // Initialize. |
| k = crVal->sampleIdxEval->cols; |
| data = crVal->sampleIdxEval->data.i; |
| |
| // Eval tested feature vectors. |
| CV_CALL (cvStatModelMultiPredict (model, trainData, sample_t_flag, |
| crVal->predict_results, NULL, crVal->sampleIdxEval)); |
| // Count number if correct results. |
| responses_result = crVal->predict_results->data.fl; |
| if (crVal->is_regression) |
| { |
| sum_c = sum_p = sum_pp = sum_cp = sum_cc = sq_err = 0; |
| if (CV_MAT_TYPE (trainClasses->type) == CV_32FC1) |
| { |
| responses_fl = trainClasses->data.fl; |
| step = trainClasses->rows == 1 ? 1 : trainClasses->step / sizeof(float); |
| for (i = 0; i < k; i++) |
| { |
| te = responses_result[*data]; |
| te1 = responses_fl[*data * step]; |
| sum_c += te1; |
| sum_p += te; |
| sum_cc += te1 * te1; |
| sum_pp += te * te; |
| sum_cp += te1 * te; |
| te -= te1; |
| sq_err += te * te; |
| |
| data++; |
| } |
| } |
| else |
| { |
| responses_i = trainClasses->data.i; |
| step = trainClasses->rows == 1 ? 1 : trainClasses->step / sizeof(int); |
| for (i = 0; i < k; i++) |
| { |
| te = responses_result[*data]; |
| te1 = responses_i[*data * step]; |
| sum_c += te1; |
| sum_p += te; |
| sum_cc += te1 * te1; |
| sum_pp += te * te; |
| sum_cp += te1 * te; |
| te -= te1; |
| sq_err += te * te; |
| |
| data++; |
| } |
| } |
| // Fixing new internal values of accuracy. |
| crVal->sum_correct += sum_c; |
| crVal->sum_predict += sum_p; |
| crVal->sum_cc += sum_cc; |
| crVal->sum_pp += sum_pp; |
| crVal->sum_cp += sum_cp; |
| crVal->sq_error += sq_err; |
| } |
| else |
| { |
| if (CV_MAT_TYPE (trainClasses->type) == CV_32FC1) |
| { |
| responses_fl = trainClasses->data.fl; |
| step = trainClasses->rows == 1 ? 1 : trainClasses->step / sizeof(float); |
| for (i = 0, j = 0; i < k; i++) |
| { |
| if (cvRound (responses_result[*data]) == cvRound (responses_fl[*data * step])) |
| j++; |
| data++; |
| } |
| } |
| else |
| { |
| responses_i = trainClasses->data.i; |
| step = trainClasses->rows == 1 ? 1 : trainClasses->step / sizeof(int); |
| for (i = 0, j = 0; i < k; i++) |
| { |
| if (cvRound (responses_result[*data]) == responses_i[*data * step]) |
| j++; |
| data++; |
| } |
| } |
| // Fixing new internal values of accuracy. |
| crVal->correct_results += j; |
| } |
| // Fixing that this fold already checked. |
| crVal->all_results += k; |
| crVal->is_checked = 1; |
| |
| __END__ |
| } // End of cvCrossValCheckClassifier |
| |
| /****************************************************************************************/ |
| // Return current accuracy. |
| ML_IMPL |
| float cvCrossValGetResult (const CvStatModel* estimateModel, |
| float* correlation) |
| { |
| float result = 0; |
| |
| CV_FUNCNAME ("cvCrossValGetResult"); |
| __BEGIN__ |
| |
| double te, te1; |
| CvCrossValidationModel* crVal = (CvCrossValidationModel*)estimateModel; |
| |
| if (!CV_IS_CROSSVAL (estimateModel)) |
| { |
| CV_ERROR (CV_StsBadArg, "Pointer point to not CvCrossValidationModel"); |
| } |
| |
| if (crVal->all_results) |
| { |
| if (crVal->is_regression) |
| { |
| result = ((float)crVal->sq_error) / crVal->all_results; |
| if (correlation) |
| { |
| te = crVal->all_results * crVal->sum_cp - |
| crVal->sum_correct * crVal->sum_predict; |
| te *= te; |
| te1 = (crVal->all_results * crVal->sum_cc - |
| crVal->sum_correct * crVal->sum_correct) * |
| (crVal->all_results * crVal->sum_pp - |
| crVal->sum_predict * crVal->sum_predict); |
| *correlation = (float)(te / te1); |
| |
| } |
| } |
| else |
| { |
| result = ((float)crVal->correct_results) / crVal->all_results; |
| } |
| } |
| |
| __END__ |
| |
| return result; |
| } |
| |
| /****************************************************************************************/ |
| // Reset cross-validation EstimateModel to state the same as it was immidiatly after |
| // its creating. |
| ML_IMPL |
| void cvCrossValReset (CvStatModel* estimateModel) |
| { |
| CV_FUNCNAME ("cvCrossValReset"); |
| __BEGIN__ |
| |
| CvCrossValidationModel* crVal = (CvCrossValidationModel*)estimateModel; |
| |
| if (!CV_IS_CROSSVAL (estimateModel)) |
| { |
| CV_ERROR (CV_StsBadArg, "Pointer point to not CvCrossValidationModel"); |
| } |
| |
| crVal->current_fold = -1; |
| crVal->is_checked = 1; |
| crVal->all_results = 0; |
| crVal->correct_results = 0; |
| crVal->sq_error = 0; |
| crVal->sum_correct = 0; |
| crVal->sum_predict = 0; |
| crVal->sum_cc = 0; |
| crVal->sum_pp = 0; |
| crVal->sum_cp = 0; |
| |
| __END__ |
| } |
| |
| /****************************************************************************************/ |
| // This function is standart CvStatModel field to release cross-validation EstimateModel. |
| ML_IMPL |
| void cvReleaseCrossValidationModel (CvStatModel** model) |
| { |
| CvCrossValidationModel* pModel; |
| |
| CV_FUNCNAME ("cvReleaseCrossValidationModel"); |
| __BEGIN__ |
| |
| if (!model) |
| { |
| CV_ERROR (CV_StsNullPtr, ""); |
| } |
| |
| pModel = (CvCrossValidationModel*)*model; |
| if (!pModel) |
| { |
| return; |
| } |
| if (!CV_IS_CROSSVAL (pModel)) |
| { |
| CV_ERROR (CV_StsBadArg, ""); |
| } |
| |
| cvFree (&pModel->sampleIdxAll); |
| cvFree (&pModel->folds); |
| cvReleaseMat (&pModel->sampleIdxEval); |
| cvReleaseMat (&pModel->sampleIdxTrain); |
| cvReleaseMat (&pModel->predict_results); |
| |
| cvFree (model); |
| |
| __END__ |
| } // End of cvReleaseCrossValidationModel. |
| |
| /****************************************************************************************/ |
| // This function create cross-validation EstimateModel. |
| ML_IMPL CvStatModel* |
| cvCreateCrossValidationEstimateModel( |
| int samples_all, |
| const CvStatModelParams* estimateParams, |
| const CvMat* sampleIdx) |
| { |
| CvStatModel* model = NULL; |
| CvCrossValidationModel* crVal = NULL; |
| |
| CV_FUNCNAME ("cvCreateCrossValidationEstimateModel"); |
| __BEGIN__ |
| |
| int k_fold = 10; |
| |
| int i, j, k, s_len; |
| int samples_selected; |
| CvRNG rng; |
| CvRNG* prng; |
| int* res_s_data; |
| int* te_s_data; |
| int* folds; |
| |
| rng = cvRNG(cvGetTickCount()); |
| cvRandInt (&rng); cvRandInt (&rng); cvRandInt (&rng); cvRandInt (&rng); |
| // Check input parameters. |
| if (estimateParams) |
| k_fold = ((CvCrossValidationParams*)estimateParams)->k_fold; |
| if (!k_fold) |
| { |
| CV_ERROR (CV_StsBadArg, "Error in parameters of cross-validation (k_fold == 0)!"); |
| } |
| if (samples_all <= 0) |
| { |
| CV_ERROR (CV_StsBadArg, "<samples_all> should be positive!"); |
| } |
| |
| // Alloc memory and fill standart StatModel's fields. |
| CV_CALL (crVal = (CvCrossValidationModel*)cvCreateStatModel ( |
| CV_STAT_MODEL_MAGIC_VAL | CV_CROSSVAL_MAGIC_VAL, |
| sizeof(CvCrossValidationModel), |
| cvReleaseCrossValidationModel, |
| NULL, NULL)); |
| crVal->current_fold = -1; |
| crVal->folds_all = k_fold; |
| if (estimateParams && ((CvCrossValidationParams*)estimateParams)->is_regression) |
| crVal->is_regression = 1; |
| else |
| crVal->is_regression = 0; |
| if (estimateParams && ((CvCrossValidationParams*)estimateParams)->rng) |
| prng = ((CvCrossValidationParams*)estimateParams)->rng; |
| else |
| prng = &rng; |
| |
| // Check and preprocess sample indices. |
| if (sampleIdx) |
| { |
| int s_step; |
| int s_type = 0; |
| |
| if (!CV_IS_MAT (sampleIdx)) |
| CV_ERROR (CV_StsBadArg, "Invalid sampleIdx array"); |
| |
| if (sampleIdx->rows != 1 && sampleIdx->cols != 1) |
| CV_ERROR (CV_StsBadSize, "sampleIdx array must be 1-dimensional"); |
| |
| s_len = sampleIdx->rows + sampleIdx->cols - 1; |
| s_step = sampleIdx->rows == 1 ? |
| 1 : sampleIdx->step / CV_ELEM_SIZE(sampleIdx->type); |
| |
| s_type = CV_MAT_TYPE (sampleIdx->type); |
| |
| switch (s_type) |
| { |
| case CV_8UC1: |
| case CV_8SC1: |
| { |
| uchar* s_data = sampleIdx->data.ptr; |
| |
| // sampleIdx is array of 1's and 0's - |
| // i.e. it is a mask of the selected samples |
| if( s_len != samples_all ) |
| CV_ERROR (CV_StsUnmatchedSizes, |
| "Sample mask should contain as many elements as the total number of samples"); |
| |
| samples_selected = 0; |
| for (i = 0; i < s_len; i++) |
| samples_selected += s_data[i * s_step] != 0; |
| |
| if (samples_selected == 0) |
| CV_ERROR (CV_StsOutOfRange, "No samples is selected!"); |
| } |
| s_len = samples_selected; |
| break; |
| case CV_32SC1: |
| if (s_len > samples_all) |
| CV_ERROR (CV_StsOutOfRange, |
| "sampleIdx array may not contain more elements than the total number of samples"); |
| samples_selected = s_len; |
| break; |
| default: |
| CV_ERROR (CV_StsUnsupportedFormat, "Unsupported sampleIdx array data type " |
| "(it should be 8uC1, 8sC1 or 32sC1)"); |
| } |
| |
| // Alloc additional memory for internal Idx and fill it. |
| /*!!*/ CV_CALL (res_s_data = crVal->sampleIdxAll = |
| (int*)cvAlloc (2 * s_len * sizeof(int))); |
| |
| if (s_type < CV_32SC1) |
| { |
| uchar* s_data = sampleIdx->data.ptr; |
| for (i = 0; i < s_len; i++) |
| if (s_data[i * s_step]) |
| { |
| *res_s_data++ = i; |
| } |
| res_s_data = crVal->sampleIdxAll; |
| } |
| else |
| { |
| int* s_data = sampleIdx->data.i; |
| int out_of_order = 0; |
| |
| for (i = 0; i < s_len; i++) |
| { |
| res_s_data[i] = s_data[i * s_step]; |
| if (i > 0 && res_s_data[i] < res_s_data[i - 1]) |
| out_of_order = 1; |
| } |
| |
| if (out_of_order) |
| qsort (res_s_data, s_len, sizeof(res_s_data[0]), icvCmpIntegers); |
| |
| if (res_s_data[0] < 0 || |
| res_s_data[s_len - 1] >= samples_all) |
| CV_ERROR (CV_StsBadArg, "There are out-of-range sample indices"); |
| for (i = 1; i < s_len; i++) |
| if (res_s_data[i] <= res_s_data[i - 1]) |
| CV_ERROR (CV_StsBadArg, "There are duplicated"); |
| } |
| } |
| else // if (sampleIdx) |
| { |
| // Alloc additional memory for internal Idx and fill it. |
| s_len = samples_all; |
| CV_CALL (res_s_data = crVal->sampleIdxAll = (int*)cvAlloc (2 * s_len * sizeof(int))); |
| for (i = 0; i < s_len; i++) |
| { |
| *res_s_data++ = i; |
| } |
| res_s_data = crVal->sampleIdxAll; |
| } // if (sampleIdx) ... else |
| |
| // Resort internal Idx. |
| te_s_data = res_s_data + s_len; |
| for (i = s_len; i > 1; i--) |
| { |
| j = cvRandInt (prng) % i; |
| k = *(--te_s_data); |
| *te_s_data = res_s_data[j]; |
| res_s_data[j] = k; |
| } |
| |
| // Duplicate resorted internal Idx. |
| // It will be used to simplify operation of getting trainIdx. |
| te_s_data = res_s_data + s_len; |
| for (i = 0; i < s_len; i++) |
| { |
| *te_s_data++ = *res_s_data++; |
| } |
| |
| // Cut sampleIdxAll to parts. |
| if (k_fold > 0) |
| { |
| if (k_fold > s_len) |
| { |
| CV_ERROR (CV_StsBadArg, |
| "Error in parameters of cross-validation ('k_fold' > #samples)!"); |
| } |
| folds = crVal->folds = (int*) cvAlloc ((k_fold + 1) * sizeof (int)); |
| *folds++ = 0; |
| for (i = 1; i < k_fold; i++) |
| { |
| *folds++ = cvRound (i * s_len * 1. / k_fold); |
| } |
| *folds = s_len; |
| folds = crVal->folds; |
| |
| crVal->max_fold_size = (s_len - 1) / k_fold + 1; |
| } |
| else |
| { |
| k = -k_fold; |
| crVal->max_fold_size = k; |
| if (k >= s_len) |
| { |
| CV_ERROR (CV_StsBadArg, |
| "Error in parameters of cross-validation (-'k_fold' > #samples)!"); |
| } |
| crVal->folds_all = k = (s_len - 1) / k + 1; |
| |
| folds = crVal->folds = (int*) cvAlloc ((k + 1) * sizeof (int)); |
| for (i = 0; i < k; i++) |
| { |
| *folds++ = -i * k_fold; |
| } |
| *folds = s_len; |
| folds = crVal->folds; |
| } |
| |
| // Prepare other internal fields to working. |
| CV_CALL (crVal->predict_results = cvCreateMat (1, samples_all, CV_32FC1)); |
| CV_CALL (crVal->sampleIdxEval = cvCreateMatHeader (1, 1, CV_32SC1)); |
| CV_CALL (crVal->sampleIdxTrain = cvCreateMatHeader (1, 1, CV_32SC1)); |
| crVal->sampleIdxEval->cols = 0; |
| crVal->sampleIdxTrain->cols = 0; |
| crVal->samples_all = s_len; |
| crVal->is_checked = 1; |
| |
| crVal->getTrainIdxMat = cvCrossValGetTrainIdxMatrix; |
| crVal->getCheckIdxMat = cvCrossValGetCheckIdxMatrix; |
| crVal->nextStep = cvCrossValNextStep; |
| crVal->check = cvCrossValCheckClassifier; |
| crVal->getResult = cvCrossValGetResult; |
| crVal->reset = cvCrossValReset; |
| |
| model = (CvStatModel*)crVal; |
| |
| __END__ |
| |
| if (!model) |
| { |
| cvReleaseCrossValidationModel ((CvStatModel**)&crVal); |
| } |
| |
| return model; |
| } // End of cvCreateCrossValidationEstimateModel |
| |
| |
| /****************************************************************************************\ |
| * Extended interface with backcalls for models * |
| \****************************************************************************************/ |
| ML_IMPL float |
| cvCrossValidation (const CvMat* trueData, |
| int tflag, |
| const CvMat* trueClasses, |
| CvStatModel* (*createClassifier) (const CvMat*, |
| int, |
| const CvMat*, |
| const CvClassifierTrainParams*, |
| const CvMat*, |
| const CvMat*, |
| const CvMat*, |
| const CvMat*), |
| const CvClassifierTrainParams* estimateParams, |
| const CvClassifierTrainParams* trainParams, |
| const CvMat* compIdx, |
| const CvMat* sampleIdx, |
| CvStatModel** pCrValModel, |
| const CvMat* typeMask, |
| const CvMat* missedMeasurementMask) |
| { |
| CvCrossValidationModel* crVal = NULL; |
| float result = 0; |
| CvStatModel* pClassifier = NULL; |
| |
| CV_FUNCNAME ("cvCrossValidation"); |
| __BEGIN__ |
| |
| const CvMat* trainDataIdx; |
| int samples_all; |
| |
| // checking input data |
| if ((createClassifier) == NULL) |
| { |
| CV_ERROR (CV_StsNullPtr, "Null pointer to functiion which create classifier"); |
| } |
| if (pCrValModel && *pCrValModel && !CV_IS_CROSSVAL(*pCrValModel)) |
| { |
| CV_ERROR (CV_StsBadArg, |
| "<pCrValModel> point to not cross-validation model"); |
| } |
| |
| // initialization |
| if (pCrValModel && *pCrValModel) |
| { |
| crVal = (CvCrossValidationModel*)*pCrValModel; |
| crVal->reset ((CvStatModel*)crVal); |
| } |
| else |
| { |
| samples_all = ((tflag) ? trueData->rows : trueData->cols); |
| CV_CALL (crVal = (CvCrossValidationModel*) |
| cvCreateCrossValidationEstimateModel (samples_all, estimateParams, sampleIdx)); |
| } |
| |
| CV_CALL (trainDataIdx = crVal->getTrainIdxMat ((CvStatModel*)crVal)); |
| |
| // operation loop |
| for (; crVal->nextStep((CvStatModel*)crVal) != 0; ) |
| { |
| CV_CALL (pClassifier = createClassifier (trueData, tflag, trueClasses, |
| trainParams, compIdx, trainDataIdx, typeMask, missedMeasurementMask)); |
| CV_CALL (crVal->check ((CvStatModel*)crVal, pClassifier, |
| trueData, tflag, trueClasses)); |
| |
| pClassifier->release (&pClassifier); |
| } |
| |
| // Get result and fill output field. |
| CV_CALL (result = crVal->getResult ((CvStatModel*)crVal, 0)); |
| |
| if (pCrValModel && !*pCrValModel) |
| *pCrValModel = (CvStatModel*)crVal; |
| |
| __END__ |
| |
| // Free all memory that should be freed. |
| if (pClassifier) |
| pClassifier->release (&pClassifier); |
| if (crVal && (!pCrValModel || !*pCrValModel)) |
| crVal->release ((CvStatModel**)&crVal); |
| |
| return result; |
| } // End of cvCrossValidation |
| |
| #endif |
| |
| /* End of file */ |