diff --git a/Demo.cpp b/Demo.cpp index b676ffffb9f25f78f67e0e587b44de583adf196a..152a01458862e77ce8628dc162676eefefcde86b 100644 --- a/Demo.cpp +++ b/Demo.cpp @@ -53,11 +53,7 @@ along with BGSLibrary. If not, see <http://www.gnu.org/licenses/>. #include "package_bgs/lb/LBAdaptiveSOM.h" #include "package_bgs/lb/LBFuzzyAdaptiveSOM.h" -#if !defined(_WIN32) -// Currently this method works only on Linux platform. #include "package_bgs/ck/LbpMrf.h" -#endif - #include "package_bgs/jmo/MultiLayerBGS.h" // The PBAS algorithm was removed from BGSLibrary because it is // based on patented algorithm ViBE diff --git a/Demo.exe b/Demo.exe index 7373b7b91ab8475c7072210665ed3a2878827bd8..c4e647d6e41d00bb323f611e562d986e0f31090f 100644 Binary files a/Demo.exe and b/Demo.exe differ diff --git a/Demo2.cpp b/Demo2.cpp index 2708be93fc49ac69d3ad6fa00053daf788efd34b..1f9a1b4ad37e1ee99e7e5b8ce8dcfdd17370f61f 100644 --- a/Demo2.cpp +++ b/Demo2.cpp @@ -53,11 +53,7 @@ along with BGSLibrary. If not, see <http://www.gnu.org/licenses/>. #include "package_bgs/lb/LBAdaptiveSOM.h" #include "package_bgs/lb/LBFuzzyAdaptiveSOM.h" -#if !defined(_WIN32) -// Currently this method works only on Linux platform. #include "package_bgs/ck/LbpMrf.h" -#endif - #include "package_bgs/jmo/MultiLayerBGS.h" // The PBAS algorithm was removed from BGSLibrary because it is // based on patented algorithm ViBE diff --git a/Demo2.exe b/Demo2.exe index dbaa1041f0fbbe1cd0f9780dd77fff4ad15592f3..c05e99cbe77bccf501c254ef4a77b92b15c51eef 100644 Binary files a/Demo2.exe and b/Demo2.exe differ diff --git a/bgslibrary.exe b/bgslibrary.exe index 9067a0e3b1e369a4e9971fd59c4fcac7ed714a3b..3f28b286e762c6c49cb3354aee3dfe492232643c 100644 Binary files a/bgslibrary.exe and b/bgslibrary.exe differ diff --git a/package_bgs/ck/MotionDetection.cpp b/package_bgs/ck/MotionDetection.cpp index e22648a0b4f7f930d1322cee1c2824b4c983d6ee..5ac096afd18e51ec238fd9deae1ad60bad452ae2 100644 --- a/package_bgs/ck/MotionDetection.cpp +++ b/package_bgs/ck/MotionDetection.cpp @@ -1,31 +1,36 @@ /* - * This file is part of the AiBO+ project - * - * Copyright (C) 2005-2013 Csaba Kertész (csaba.kertesz@gmail.com) - * - * AiBO+ is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * AiBO+ is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. - * - * Paper: Csaba, Kertész: Texture-Based Foreground Detection, International Journal of Signal Processing, - * Image Processing and Pattern Recognition (IJSIP), Vol. 4, No. 4, 2011. - */ +* This file is part of the AiBO+ project +* +* Copyright (C) 2005-2013 Csaba Kertész (csaba.kertesz@gmail.com) +* +* AiBO+ is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* AiBO+ is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. +* +* Paper: Csaba, Kertész: Texture-Based Foreground Detection, International Journal of Signal Processing, +* Image Processing and Pattern Recognition (IJSIP), Vol. 4, No. 4, 2011. +*/ #include "MotionDetection.hpp" #include "graph.h" +using namespace ck; -#include <opencv2/opencv.hpp> +#if defined(__MINGW32__) || defined(__MINGW64__) +#include <cvaux.h> +#else +#include <opencv/cvaux.h> +#endif #include "MEHistogram.hpp" #include "MEImage.hpp" @@ -47,15 +52,15 @@ struct MEPixelDataType }; MotionDetection::MotionDetection(DetectorType mode) : - MDMode(md_NotDefined), MDDataState(ps_Uninitialized), Frames(0), ReadyMask(false), - HUColorSpace(MEImage::csc_RGBtoCIELuv), HULBPMode(MEImage::lbp_Special), - HUHistogramsPerPixel(3), HUHistogramArea(5), HUHistogramBins(8), - HUImageWidth(-1), HUImageHeight(-1), HULBPPixelData(NULL), - HUPrThres(0.75), HUBackgrThres(0.95), HUHistLRate(0.01), HUWeightsLRate(0.01), - HUSamplePixels(-1), HUDesiredSamplePixels(-1), HUMinCutWeight(8.0), - HUOFDataState(ps_Uninitialized), HUOFPointsNumber(-1), - HUOFCamMovementX(0), MaxTrackedPoints(0), HUOFFrames(-1), - HUOFCamMovement(false) +MDMode(md_NotDefined), MDDataState(ps_Uninitialized), Frames(0), ReadyMask(false), +HUColorSpace(MEImage::csc_RGBtoCIELuv), HULBPMode(MEImage::lbp_Special), +HUHistogramsPerPixel(3), HUHistogramArea(5), HUHistogramBins(8), +HUImageWidth(-1), HUImageHeight(-1), HULBPPixelData(NULL), +HUPrThres(0.75), HUBackgrThres(0.95), HUHistLRate(0.01), HUWeightsLRate(0.01), +HUSamplePixels(-1), HUDesiredSamplePixels(-1), HUMinCutWeight(8.0), +HUOFDataState(ps_Uninitialized), HUOFPointsNumber(-1), +HUOFCamMovementX(0), MaxTrackedPoints(0), HUOFFrames(-1), +HUOFCamMovement(false) { HUOFPyramid = NULL; HUOFPrevPyramid = NULL; @@ -88,17 +93,17 @@ void MotionDetection::SetMode(DetectorType newmode) switch (newmode) { - case md_LBPHistograms: - MDMode = md_LBPHistograms; - break; + case md_LBPHistograms: + MDMode = md_LBPHistograms; + break; - case md_DLBPHistograms: - MDMode = md_DLBPHistograms; - break; + case md_DLBPHistograms: + MDMode = md_DLBPHistograms; + break; - default: - MDMode = md_LBPHistograms; - break; + default: + MDMode = md_LBPHistograms; + break; } } @@ -109,52 +114,52 @@ float MotionDetection::GetParameter(ParametersType param) const switch (param) { - case mdp_HUProximityThreshold: - ret = (float)HUPrThres; - break; + case mdp_HUProximityThreshold: + ret = (float)HUPrThres; + break; - case mdp_HUBackgroundThreshold: - ret = (float)HUBackgrThres; - break; + case mdp_HUBackgroundThreshold: + ret = (float)HUBackgrThres; + break; - case mdp_HUHistogramLearningRate: - ret = (float)HUHistLRate; - break; + case mdp_HUHistogramLearningRate: + ret = (float)HUHistLRate; + break; - case mdp_HUWeightsLearningRate: - ret = (float)HUWeightsLRate; - break; + case mdp_HUWeightsLearningRate: + ret = (float)HUWeightsLRate; + break; - case mdp_HUMinCutWeight: - ret = (float)HUMinCutWeight; - break; + case mdp_HUMinCutWeight: + ret = (float)HUMinCutWeight; + break; - case mdp_HUDesiredSamplePixels: - ret = (float)HUDesiredSamplePixels; - break; + case mdp_HUDesiredSamplePixels: + ret = (float)HUDesiredSamplePixels; + break; - case mdp_HUHistogramsPerPixel: - ret = (float)HUHistogramsPerPixel; - break; + case mdp_HUHistogramsPerPixel: + ret = (float)HUHistogramsPerPixel; + break; - case mdp_HUHistogramArea: - ret = (float)HUHistogramArea; - break; + case mdp_HUHistogramArea: + ret = (float)HUHistogramArea; + break; - case mdp_HUHistogramBins: - ret = (float)HUHistogramBins; - break; + case mdp_HUHistogramBins: + ret = (float)HUHistogramBins; + break; - case mdp_HUColorSpace: - ret = (float)HUColorSpace; - break; + case mdp_HUColorSpace: + ret = (float)HUColorSpace; + break; - case mdp_HULBPMode: - ret = (float)HULBPMode; - break; + case mdp_HULBPMode: + ret = (float)HULBPMode; + break; - default: - break; + default: + break; } return ret; } @@ -164,52 +169,52 @@ void MotionDetection::SetParameter(ParametersType param, float value) { switch (param) { - case mdp_HUProximityThreshold: - HUPrThres = (float)value; - break; + case mdp_HUProximityThreshold: + HUPrThres = (float)value; + break; - case mdp_HUBackgroundThreshold: - HUBackgrThres = (float)value; - break; + case mdp_HUBackgroundThreshold: + HUBackgrThres = (float)value; + break; - case mdp_HUHistogramLearningRate: - HUHistLRate = (float)value; - break; + case mdp_HUHistogramLearningRate: + HUHistLRate = (float)value; + break; - case mdp_HUWeightsLearningRate: - HUWeightsLRate = (float)value; - break; + case mdp_HUWeightsLearningRate: + HUWeightsLRate = (float)value; + break; - case mdp_HUMinCutWeight: - HUMinCutWeight = (float)value; - break; + case mdp_HUMinCutWeight: + HUMinCutWeight = (float)value; + break; - case mdp_HUDesiredSamplePixels: - HUDesiredSamplePixels = (int)value; - break; + case mdp_HUDesiredSamplePixels: + HUDesiredSamplePixels = (int)value; + break; - case mdp_HUHistogramsPerPixel: - HUHistogramsPerPixel = (MDDataState == ps_Uninitialized) ? (int)value : HUHistogramsPerPixel; - break; + case mdp_HUHistogramsPerPixel: + HUHistogramsPerPixel = (MDDataState == ps_Uninitialized) ? (int)value : HUHistogramsPerPixel; + break; - case mdp_HUHistogramArea: - HUHistogramArea = (MDDataState == ps_Uninitialized) ? (int)value : HUHistogramArea; - break; + case mdp_HUHistogramArea: + HUHistogramArea = (MDDataState == ps_Uninitialized) ? (int)value : HUHistogramArea; + break; - case mdp_HUHistogramBins: - HUHistogramBins = (MDDataState == ps_Uninitialized) ? (int)value : HUHistogramBins; - break; + case mdp_HUHistogramBins: + HUHistogramBins = (MDDataState == ps_Uninitialized) ? (int)value : HUHistogramBins; + break; - case mdp_HUColorSpace: - HUColorSpace = (MDDataState == ps_Uninitialized) ? (int)value : HUColorSpace; - break; + case mdp_HUColorSpace: + HUColorSpace = (MDDataState == ps_Uninitialized) ? (int)value : HUColorSpace; + break; - case mdp_HULBPMode: - HULBPMode = (MDDataState == ps_Uninitialized) ? (int)value : HULBPMode; - break; + case mdp_HULBPMode: + HULBPMode = (MDDataState == ps_Uninitialized) ? (int)value : HULBPMode; + break; - default: - break; + default: + break; } } @@ -218,13 +223,13 @@ void MotionDetection::DetectMotions(MEImage& image) { switch (MDMode) { - case md_LBPHistograms: - case md_DLBPHistograms: - DetectMotionsHU(image); - break; + case md_LBPHistograms: + case md_DLBPHistograms: + DetectMotionsHU(image); + break; - default: - break; + default: + break; } } @@ -233,18 +238,18 @@ void MotionDetection::GetMotionsMask(MEImage& mask_image) { if (ReadyMask) { - mask_image = MaskImage; + mask_image = MaskImage; } switch (MDMode) { - case md_LBPHistograms: - case md_DLBPHistograms: - GetMotionsMaskHU(MaskImage); - break; + case md_LBPHistograms: + case md_DLBPHistograms: + GetMotionsMaskHU(MaskImage); + break; - default: - break; + default: + break; } ReadyMask = true; @@ -253,7 +258,7 @@ void MotionDetection::GetMotionsMask(MEImage& mask_image) void MotionDetection::CalculateResults(MEImage& referenceimage, int& tnegatives, int& tpositives, - int& ttnegatives, int& ttpositives) + int& ttnegatives, int& ttpositives) { if (MDDataState != ps_Successful) { @@ -271,7 +276,7 @@ void MotionDetection::CalculateResults(MEImage& referenceimage, int& tnegatives, GetMotionsMask(mask_image); if ((mask_image.GetWidth() != referenceimage.GetWidth()) || - (mask_image.GetHeight() != referenceimage.GetHeight())) + (mask_image.GetHeight() != referenceimage.GetHeight())) { printf("Different resolutions of mask<->reference image.\n"); return; @@ -294,18 +299,18 @@ void MotionDetection::CalculateResults(MEImage& referenceimage, int& tnegatives, ImageFrame = HUHistogramArea / 2; } - for (int y = referenceimage.GetHeight()-ImageFrame-1; y >= ImageFrame; --y) + for (int y = referenceimage.GetHeight() - ImageFrame - 1; y >= ImageFrame; --y) { - for (int x = referenceimage.GetWidth()-ImageFrame-1; x >= ImageFrame; --x) + for (int x = referenceimage.GetWidth() - ImageFrame - 1; x >= ImageFrame; --x) { TrueNegatives += - (RefMaskImgData[RowStart+x] == 0) && - (MaskImgData[RowStart+x] == 0); - TotalTrueNegatives += (RefMaskImgData[RowStart+x] == 0); + (RefMaskImgData[RowStart + x] == 0) && + (MaskImgData[RowStart + x] == 0); + TotalTrueNegatives += (RefMaskImgData[RowStart + x] == 0); TruePositives += - (RefMaskImgData[RowStart+x] == 255) && - (MaskImgData[RowStart+x] == 255); - TotalTruePositives += (RefMaskImgData[RowStart+x] == 255); + (RefMaskImgData[RowStart + x] == 255) && + (MaskImgData[RowStart + x] == 255); + TotalTruePositives += (RefMaskImgData[RowStart + x] == 255); } RowStart += RowWidth; } @@ -328,9 +333,9 @@ void MotionDetection::ReleaseData() void MotionDetection::InitHUData(int imagewidth, int imageheight) { - if ((HUImageWidth != imagewidth-HUHistogramArea+1) || - (HUImageHeight != imageheight-HUHistogramArea+1) || - (MDDataState == ps_Uninitialized)) + if ((HUImageWidth != imagewidth - HUHistogramArea + 1) || + (HUImageHeight != imageheight - HUHistogramArea + 1) || + (MDDataState == ps_Uninitialized)) { if (MDDataState != ps_Uninitialized) { @@ -339,8 +344,8 @@ void MotionDetection::InitHUData(int imagewidth, int imageheight) MDDataState = ps_Initialized; - HUImageWidth = imagewidth-HUHistogramArea+1; - HUImageHeight = imageheight-HUHistogramArea+1; + HUImageWidth = imagewidth - HUHistogramArea + 1; + HUImageHeight = imageheight - HUHistogramArea + 1; HULBPPixelData = new MEPixelDataType**[HUImageWidth / 2]; @@ -351,7 +356,7 @@ void MotionDetection::InitHUData(int imagewidth, int imageheight) for (int i = 0; i < HUImageWidth / 2; ++i) for (int i1 = 0; i1 < HUImageHeight; ++i1) - { + { HULBPPixelData[i][i1] = new MEPixelDataType; HULBPPixelData[i][i1]->Weights = new float[HUHistogramsPerPixel]; HULBPPixelData[i][i1]->BackgroundHistogram = new bool[HUHistogramsPerPixel]; @@ -359,7 +364,7 @@ void MotionDetection::InitHUData(int imagewidth, int imageheight) for (int i2 = 0; i2 < HUHistogramsPerPixel; ++i2) HULBPPixelData[i][i1]->Histograms[i2] = new float[HUHistogramBins]; HULBPPixelData[i][i1]->PreviousHistogram = new float[HUHistogramBins]; - } + } // Allocate auxiliary variables HUMaskColumnAddDel = new int*[HUHistogramArea]; @@ -406,7 +411,7 @@ void MotionDetection::ReleaseHUData() { for (int i = 0; i < HUImageWidth / 2; i++) for (int i1 = 0; i1 < HUImageHeight; i1++) - { + { delete[] HULBPPixelData[i][i1]->PreviousHistogram; for (int i2 = 0; i2 < HUHistogramsPerPixel; ++i2) delete[] HULBPPixelData[i][i1]->Histograms[i2]; @@ -414,7 +419,7 @@ void MotionDetection::ReleaseHUData() delete[] HULBPPixelData[i][i1]->BackgroundHistogram; delete[] HULBPPixelData[i][i1]->Weights; delete HULBPPixelData[i][i1]; - } + } for (int i = 0; i < HUImageWidth / 2; i++) { @@ -456,18 +461,18 @@ void MotionDetection::ReleaseHUOFData() } if (HUOFPrevPyramid) { - cvReleaseImage(&HUOFPrevPyramid); - HUOFPrevPyramid = NULL; + cvReleaseImage(&HUOFPrevPyramid); + HUOFPrevPyramid = NULL; } if (HUOFPoints[0]) { - cvFree(&HUOFPoints[0]); - HUOFPoints[0] = NULL; + cvFree(&HUOFPoints[0]); + HUOFPoints[0] = NULL; } if (HUOFPoints[1]) { - cvFree(&HUOFPoints[1]); - HUOFPoints[1] = NULL; + cvFree(&HUOFPoints[1]); + HUOFPoints[1] = NULL; } HUOFDataState = ps_Uninitialized; } @@ -478,19 +483,19 @@ void MotionDetection::ClearHUData() { if (MDDataState != ps_Uninitialized) { - for (int i = (HUImageWidth / 2)-1; i >= 0; --i) - for (int i1 = HUImageHeight-1; i1 >= 0; --i1) - { - for (int i2 = HUHistogramsPerPixel-1; i2 >= 0; --i2) + for (int i = (HUImageWidth / 2) - 1; i >= 0; --i) + for (int i1 = HUImageHeight - 1; i1 >= 0; --i1) + { + for (int i2 = HUHistogramsPerPixel - 1; i2 >= 0; --i2) { memset(HULBPPixelData[i][i1]->Histograms[i2], 0, - HUHistogramBins*sizeof(float)); + HUHistogramBins*sizeof(float)); HULBPPixelData[i][i1]->Weights[i2] = 1.0 / HUHistogramsPerPixel; HULBPPixelData[i][i1]->BackgroundHistogram[i2] = true; } HULBPPixelData[i][i1]->BackgroundRate = 1.0; HULBPPixelData[i][i1]->LifeCycle = 0; - } + } MDDataState = ps_Initialized; } } @@ -504,8 +509,8 @@ void MotionDetection::DetectMotionsHU(MEImage& image) // Init the histogram update data structures if needs be if ((MDDataState == ps_Uninitialized) || - (HUImageWidth != newimage.GetWidth()-HUHistogramArea+1) || - (HUImageHeight != newimage.GetHeight()-HUHistogramArea+1)) + (HUImageWidth != newimage.GetWidth() - HUHistogramArea + 1) || + (HUImageHeight != newimage.GetHeight() - HUHistogramArea + 1)) { InitHUData(newimage.GetWidth(), newimage.GetHeight()); } @@ -554,9 +559,10 @@ void MotionDetection::DetectMotionsHU(MEImage& image) { CurrentImage = image; PreviousImage = CurrentImage; - } else - if (Frames > 1) - { + } + else + if (Frames > 1) + { PreviousImage = CurrentImage; CurrentImage = image; // Optical flow correction of the camera movements @@ -564,7 +570,7 @@ void MotionDetection::DetectMotionsHU(MEImage& image) { OpticalFlowCorrection(); } - } + } newimage.ConvertToGrayscale(MEImage::g_OpenCV); @@ -575,10 +581,10 @@ void MotionDetection::DetectMotionsHU(MEImage& image) // Set some auxiliary variables ImgData = newimage.GetImageData(); - int DivisionOperator = (int)(log(256 / HUHistogramBins) / log(2))+1; + int DivisionOperator = (int)(log((double)256 / HUHistogramBins) / log((double) 2.)) + 1; // Downscale the image - for (int i = newimage.GetRowWidth()*newimage.GetHeight()-1; i >= 0; --i) + for (int i = newimage.GetRowWidth()*newimage.GetHeight() - 1; i >= 0; --i) { ImgData[i] >>= DivisionOperator; } @@ -597,44 +603,45 @@ void MotionDetection::DetectMotionsHU(MEImage& image) void MotionDetection::UpdateModelHU(MEImage& image, MEPixelDataType*** model) { - float CurrentHistogram[HUHistogramBins], CurrentHistogram2[HUHistogramBins]; + float *CurrentHistogram = new float[HUHistogramBins]; + float *CurrentHistogram2 = new float[HUHistogramBins]; unsigned char *ImgData = image.GetImageData(); int RowWidth = image.GetRowWidth(); - int RowStart = (HUImageHeight-1)*RowWidth; + int RowStart = (HUImageHeight - 1)*RowWidth; - memset(CurrentHistogram, 0, sizeof(CurrentHistogram)); + memset(CurrentHistogram, 0, HUHistogramBins * sizeof(float)); // Calculate the first histogram - for (int y = HUHistogramArea-1; y >= 0; --y) + for (int y = HUHistogramArea - 1; y >= 0; --y) { - for (int x = HUHistogramArea-1; x >= 0; --x) + for (int x = HUHistogramArea - 1; x >= 0; --x) { if ((HUMaskRowAddDel[y][1] > x) && (HUMaskRowAddDel[y][0] <= x) && - (HUMaskColumnAddDel[x][1] > y) && (HUMaskColumnAddDel[x][0] <= y)) + (HUMaskColumnAddDel[x][1] > y) && (HUMaskColumnAddDel[x][0] <= y)) { - CurrentHistogram[ImgData[RowStart+HUImageWidth-1+x]]++; + CurrentHistogram[ImgData[RowStart + HUImageWidth - 1 + x]]++; } } RowStart += RowWidth; } // This cycle generates the last row of histograms - for (int y = HUImageHeight-1; y >= 0; --y) + for (int y = HUImageHeight - 1; y >= 0; --y) { - if (HUImageHeight-1 > y) + if (HUImageHeight - 1 > y) { // Delete and add a pixel column from the histogram data - for (int i = HUHistogramArea-1; i >= 0; --i) + for (int i = HUHistogramArea - 1; i >= 0; --i) { if (HUMaskColumnAddDel[i][0] != -1) - CurrentHistogram[ImgData[RowWidth*(y+HUMaskColumnAddDel[i][0])+HUImageWidth-1+i]]++; + CurrentHistogram[ImgData[RowWidth*(y + HUMaskColumnAddDel[i][0]) + HUImageWidth - 1 + i]]++; if (HUMaskColumnAddDel[i][1] != -1) - CurrentHistogram[ImgData[RowWidth*(y+HUMaskColumnAddDel[i][1])+HUImageWidth-1+i]]--; + CurrentHistogram[ImgData[RowWidth*(y + HUMaskColumnAddDel[i][1]) + HUImageWidth - 1 + i]]--; } } if (y % 2 == HUImageWidth % 2) { - MEPixelDataType* PixelData = model[(HUImageWidth-1) / 2][y]; + MEPixelDataType* PixelData = model[(HUImageWidth - 1) / 2][y]; // Allocate and initialize the pixel data if needs be if (!PixelData) @@ -648,28 +655,29 @@ void MotionDetection::UpdateModelHU(MEImage& image, MEPixelDataType*** model) PixelData->Histograms[i2] = new float[HUHistogramBins]; PixelData->PreviousHistogram = new float[HUHistogramBins]; - for (int i = HUHistogramsPerPixel-1; i >= 0; --i) + for (int i = HUHistogramsPerPixel - 1; i >= 0; --i) { - memcpy(PixelData->Histograms[i], CurrentHistogram, sizeof(CurrentHistogram)); + memcpy(PixelData->Histograms[i], CurrentHistogram, HUHistogramBins * sizeof(float)); PixelData->Weights[i] = 1.0 / HUHistogramsPerPixel; PixelData->BackgroundHistogram[i] = true; } PixelData->BackgroundRate = 1.0; PixelData->LifeCycle = 0; - memcpy(PixelData->PreviousHistogram, CurrentHistogram, sizeof(CurrentHistogram)); + memcpy(PixelData->PreviousHistogram, CurrentHistogram, HUHistogramBins * sizeof(float)); - model[(HUImageWidth-1) / 2][y] = PixelData; - } else { + model[(HUImageWidth - 1) / 2][y] = PixelData; + } + else { bool InitHistograms = (MDDataState == ps_Initialized); if (MDDataState != ps_Initialized && HUOFCamMovement) { // Histogram intersection between the previous and the current histogram float Difference = 0.0; - for (int i1 = HUHistogramBins-1; i1 >= 0; --i1) + for (int i1 = HUHistogramBins - 1; i1 >= 0; --i1) { Difference += (float)(CurrentHistogram[i1] < PixelData->PreviousHistogram[i1] ? - CurrentHistogram[i1] : PixelData->PreviousHistogram[i1]); + CurrentHistogram[i1] : PixelData->PreviousHistogram[i1]); } Difference /= HUSamplePixels; @@ -679,42 +687,43 @@ void MotionDetection::UpdateModelHU(MEImage& image, MEPixelDataType*** model) if (InitHistograms) { // Copy the histogram data to the HU data structures - for (int i = HUHistogramsPerPixel-1; i >= 0; --i) + for (int i = HUHistogramsPerPixel - 1; i >= 0; --i) { - memcpy(PixelData->Histograms[i], CurrentHistogram, sizeof(CurrentHistogram)); + memcpy(PixelData->Histograms[i], CurrentHistogram, HUHistogramBins * sizeof(float)); PixelData->Weights[i] = 1.0 / HUHistogramsPerPixel; PixelData->BackgroundHistogram[i] = true; } - memcpy(PixelData->PreviousHistogram, CurrentHistogram, sizeof(CurrentHistogram)); + memcpy(PixelData->PreviousHistogram, CurrentHistogram, HUHistogramBins * sizeof(float)); PixelData->BackgroundRate = 1.0; PixelData->LifeCycle = 0; - } else { + } + else { // Update the HU data structures UpdateHUPixelData(PixelData, CurrentHistogram); if (MDMode == md_DLBPHistograms) { - memcpy(PixelData->PreviousHistogram, CurrentHistogram, sizeof(CurrentHistogram)); + memcpy(PixelData->PreviousHistogram, CurrentHistogram, HUHistogramBins * sizeof(float)); } } } } // Copy the histogram - memcpy(CurrentHistogram2, CurrentHistogram, sizeof(CurrentHistogram)); + memcpy(CurrentHistogram2, CurrentHistogram, HUHistogramBins * sizeof(float)); // This cycle generates a column of histograms - for (int x = HUImageWidth-2; x >= 0; --x) + for (int x = HUImageWidth - 2; x >= 0; --x) { RowStart = RowWidth*y; // Delete and add a pixel column from the histogram data - for (int i = HUHistogramArea-1; i >= 0; --i) + for (int i = HUHistogramArea - 1; i >= 0; --i) { if (HUMaskRowAddDel[i][0] != -1) - CurrentHistogram2[ImgData[RowStart+x+HUMaskRowAddDel[i][0]]]++; + CurrentHistogram2[ImgData[RowStart + x + HUMaskRowAddDel[i][0]]]++; if (HUMaskRowAddDel[i][1] != -1) - CurrentHistogram2[ImgData[RowStart+x+HUMaskRowAddDel[i][1]]]--; + CurrentHistogram2[ImgData[RowStart + x + HUMaskRowAddDel[i][1]]]--; RowStart += RowWidth; } @@ -734,7 +743,7 @@ void MotionDetection::UpdateModelHU(MEImage& image, MEPixelDataType*** model) PixelData->Histograms[i2] = new float[HUHistogramBins]; PixelData->PreviousHistogram = new float[HUHistogramBins]; - for (int i = HUHistogramsPerPixel-1; i >= 0; --i) + for (int i = HUHistogramsPerPixel - 1; i >= 0; --i) { memcpy(PixelData->Histograms[i], CurrentHistogram2, sizeof(CurrentHistogram2)); PixelData->Weights[i] = 1.0 / HUHistogramsPerPixel; @@ -744,17 +753,18 @@ void MotionDetection::UpdateModelHU(MEImage& image, MEPixelDataType*** model) PixelData->LifeCycle = 0; model[x / 2][y] = PixelData; memcpy(PixelData->PreviousHistogram, CurrentHistogram2, sizeof(CurrentHistogram2)); - } else { + } + else { bool InitHistograms = (MDDataState == ps_Initialized); if (MDDataState != ps_Initialized && HUOFCamMovement) { // Histogram intersection between the previous and the current histogram float Difference = 0.0; - for (int i1 = HUHistogramBins-1; i1 >= 0; --i1) + for (int i1 = HUHistogramBins - 1; i1 >= 0; --i1) { Difference += (float)(CurrentHistogram2[i1] < PixelData->PreviousHistogram[i1] ? - CurrentHistogram2[i1] : PixelData->PreviousHistogram[i1]); + CurrentHistogram2[i1] : PixelData->PreviousHistogram[i1]); } Difference /= HUSamplePixels; @@ -764,7 +774,7 @@ void MotionDetection::UpdateModelHU(MEImage& image, MEPixelDataType*** model) if (InitHistograms) { // Copy the histogram data to the HU data structures - for (int i = HUHistogramsPerPixel-1; i >= 0; --i) + for (int i = HUHistogramsPerPixel - 1; i >= 0; --i) { memcpy(PixelData->Histograms[i], CurrentHistogram2, sizeof(CurrentHistogram2)); PixelData->Weights[i] = 1.0 / HUHistogramsPerPixel; @@ -773,7 +783,8 @@ void MotionDetection::UpdateModelHU(MEImage& image, MEPixelDataType*** model) memcpy(PixelData->PreviousHistogram, CurrentHistogram2, sizeof(CurrentHistogram2)); PixelData->BackgroundRate = 1.0; PixelData->LifeCycle = 0; - } else { + } + else { // Update the HU data structures UpdateHUPixelData(PixelData, CurrentHistogram2); @@ -787,6 +798,8 @@ void MotionDetection::UpdateModelHU(MEImage& image, MEPixelDataType*** model) } } + delete[] CurrentHistogram; + delete[] CurrentHistogram2; } @@ -795,26 +808,26 @@ void MotionDetection::UpdateHUPixelData(MEPixelDataType* PixelData, const float int MaxIndex = 0; float MaxValue = -1; bool Replace = true; - float IntersectionResults[HUHistogramsPerPixel]; + float *IntersectionResults = new float[HUHistogramsPerPixel]; PixelData->LifeCycle++; PixelData->BackgroundRate = 0.0; // Compute intersection between the currect and older histograms - for (int i = HUHistogramsPerPixel-1; i >= 0; --i) + for (int i = HUHistogramsPerPixel - 1; i >= 0; --i) { // Histogram intersection float Difference = 0.0; - for (int i1 = HUHistogramBins-1; i1 >= 0; --i1) + for (int i1 = HUHistogramBins - 1; i1 >= 0; --i1) { Difference += (float)histogram[i1] < PixelData->Histograms[i][i1] ? - (float)histogram[i1] : PixelData->Histograms[i][i1]; + (float)histogram[i1] : PixelData->Histograms[i][i1]; } IntersectionResults[i] = (float)Difference / (float)(HUSamplePixels); if (PixelData->BackgroundHistogram[i] && - IntersectionResults[i] > PixelData->BackgroundRate) + IntersectionResults[i] > PixelData->BackgroundRate) { PixelData->BackgroundRate = IntersectionResults[i]; } @@ -834,7 +847,7 @@ void MotionDetection::UpdateHUPixelData(MEPixelDataType* PixelData, const float // Find the histogram with minimal weight int MinIndex = 0; float MinValue = PixelData->Weights[0]; - for (int i1 = HUHistogramsPerPixel-1; i1 > 0; --i1) + for (int i1 = HUHistogramsPerPixel - 1; i1 > 0; --i1) { if (MinValue > PixelData->Weights[i1]) { @@ -844,16 +857,16 @@ void MotionDetection::UpdateHUPixelData(MEPixelDataType* PixelData, const float } PixelData->Weights[MinIndex] = 0.01; - for (int i1 = HUHistogramBins-1; i1 >= 0; --i1) + for (int i1 = HUHistogramBins - 1; i1 >= 0; --i1) PixelData->Histograms[MinIndex][i1] = (float)histogram[i1]; PixelData->BackgroundHistogram[MinIndex] = 0; // Normalize the weights float sum = 0; - for (int i1 = HUHistogramsPerPixel-1; i1 >= 0; --i1) + for (int i1 = HUHistogramsPerPixel - 1; i1 >= 0; --i1) sum += PixelData->Weights[i1]; - for (int i1 = HUHistogramsPerPixel-1; i1 >= 0; --i1) + for (int i1 = HUHistogramsPerPixel - 1; i1 >= 0; --i1) PixelData->Weights[i1] = PixelData->Weights[i1] / sum; return; @@ -862,61 +875,63 @@ void MotionDetection::UpdateHUPixelData(MEPixelDataType* PixelData, const float float LearningRate = HUHistLRate; if (PixelData->LifeCycle < 100) - LearningRate += (float)(100-PixelData->LifeCycle) / 100; + LearningRate += (float)(100 - PixelData->LifeCycle) / 100; else - if (MDMode == md_DLBPHistograms && HUOFFrames != -1 && HUOFFrames < 40) - LearningRate += (HUOFFrames < 80 ? 0.05 : 0); + if (MDMode == md_DLBPHistograms && HUOFFrames != -1 && HUOFFrames < 40) + LearningRate += (HUOFFrames < 80 ? 0.05 : 0); // Match was found -> Update the histogram of the best match - for (int i = HUHistogramBins-1; i >= 0; --i) + for (int i = HUHistogramBins - 1; i >= 0; --i) { - PixelData->Histograms[MaxIndex][i] *= (1.0-LearningRate); + PixelData->Histograms[MaxIndex][i] *= (1.0 - LearningRate); PixelData->Histograms[MaxIndex][i] += LearningRate*(float)histogram[i]; } LearningRate = HUWeightsLRate; if (PixelData->LifeCycle < 100) - LearningRate += (float)(100-PixelData->LifeCycle) / 100; + LearningRate += (float)(100 - PixelData->LifeCycle) / 100; else - if (MDMode == md_DLBPHistograms && HUOFFrames != -1 && HUOFFrames < 40) - LearningRate += (HUOFFrames < 80 ? 0.05 : 0); + if (MDMode == md_DLBPHistograms && HUOFFrames != -1 && HUOFFrames < 40) + LearningRate += (HUOFFrames < 80 ? 0.05 : 0); // Update the weights of the histograms - for (int i = HUHistogramsPerPixel-1; i >= 0; --i) + for (int i = HUHistogramsPerPixel - 1; i >= 0; --i) { PixelData->Weights[i] = - (LearningRate*(i == MaxIndex)+(1.0-LearningRate)*PixelData->Weights[i]); + (LearningRate*(i == MaxIndex) + (1.0 - LearningRate)*PixelData->Weights[i]); } // Order and select the background histograms - float Weights[HUHistogramsPerPixel][2]; + float **Weights = new float*[HUHistogramsPerPixel]; + for (int i = 0; i < HUHistogramsPerPixel; ++i) + Weights[i] = new float[2]; - for (int i = HUHistogramsPerPixel-1; i >= 0; --i) + for (int i = HUHistogramsPerPixel - 1; i >= 0; --i) { Weights[i][0] = (float)i; Weights[i][1] = PixelData->Weights[i]; } - for (int i1 = HUHistogramsPerPixel-1; i1 >= 2; --i1) + for (int i1 = HUHistogramsPerPixel - 1; i1 >= 2; --i1) for (int i = i1; i >= 1; --i) - { - if (Weights[i][1] <= Weights[i-1][1]) + { + if (Weights[i][1] <= Weights[i - 1][1]) { float tmp = Weights[i][0]; float tmp2 = Weights[i][1]; - Weights[i][0] = Weights[i-1][0]; - Weights[i][1] = Weights[i-1][1]; + Weights[i][0] = Weights[i - 1][0]; + Weights[i][1] = Weights[i - 1][1]; - Weights[i-1][0] = tmp; - Weights[i-1][1] = tmp2; + Weights[i - 1][0] = tmp; + Weights[i - 1][1] = tmp2; + } } - } float Sum = 0; int i = 0; - for (i = HUHistogramsPerPixel-1; i >= 0; --i) + for (i = HUHistogramsPerPixel - 1; i >= 0; --i) { Sum += Weights[i][1]; PixelData->BackgroundHistogram[(int)Weights[i][0]] = true; @@ -924,10 +939,14 @@ void MotionDetection::UpdateHUPixelData(MEPixelDataType* PixelData, const float if (Sum > HUBackgrThres) break; } - for (int i1 = i-1; i1 >= 0; --i1) + for (int i1 = i - 1; i1 >= 0; --i1) { PixelData->BackgroundHistogram[(int)Weights[i1][0]] = false; } + delete[] IntersectionResults; + for (int i = 0; i < HUHistogramsPerPixel; ++i) + delete[] Weights[i]; + delete[] Weights; } @@ -945,27 +964,29 @@ void MotionDetection::OpticalFlowCorrection() { CurrentGray = cvCreateImage(cvGetSize(CurrentImage.GetIplImage()), IPL_DEPTH_8U, 1); cvCvtColor(CurrentImage.GetIplImage(), CurrentGray, CV_BGR2GRAY); - } else + } + else CurrentGray = (IplImage*)CurrentImage.GetIplImage(); if (PreviousImage.GetLayers() > 1) { PreviousGray = cvCreateImage(cvGetSize(CurrentImage.GetIplImage()), IPL_DEPTH_8U, 1); cvCvtColor(PreviousImage.GetIplImage(), PreviousGray, CV_BGR2GRAY); - } else + } + else PreviousGray = (IplImage*)PreviousImage.GetIplImage(); if (HUOFDataState != ps_Successful) { printf("Search new corners\n"); - IplImage* TempEig = cvCreateImage(cvGetSize(CurrentGray), 32, 1 ); - IplImage* Temp = cvCreateImage(cvGetSize(CurrentGray), 32, 1 ); - double MinDistance = (CurrentImage.GetWidth()+CurrentImage.GetHeight()) / 20; + IplImage* TempEig = cvCreateImage(cvGetSize(CurrentGray), 32, 1); + IplImage* Temp = cvCreateImage(cvGetSize(CurrentGray), 32, 1); + double MinDistance = (CurrentImage.GetWidth() + CurrentImage.GetHeight()) / 20; HUOFPointsNumber = MaxTrackedPoints = CurrentImage.GetWidth()*CurrentImage.GetHeight() / 1000; // Search good trackable points cvGoodFeaturesToTrack(PreviousGray, TempEig, Temp, - HUOFPoints[0], &HUOFPointsNumber, - 0.01, MinDistance, NULL, 3); + HUOFPoints[0], &HUOFPointsNumber, + 0.01, MinDistance, NULL, 3); MaxTrackedPoints = HUOFPointsNumber; // Release temporary images cvReleaseImage(&TempEig); @@ -982,23 +1003,27 @@ void MotionDetection::OpticalFlowCorrection() HUOFDataState = ps_Initialized; HUOFPointsNumber = CurrentImage.GetWidth()*CurrentImage.GetHeight() / 1000; return; - } else + } + else HUOFDataState = ps_Successful; - PointsStatus = (char*)cvAlloc(HUOFPointsNumber); + PointsStatus = (char*)cvAlloc(HUOFPointsNumber); } cvCalcOpticalFlowPyrLK(PreviousGray, CurrentGray, HUOFPrevPyramid, HUOFPyramid, - HUOFPoints[0], HUOFPoints[1], HUOFPointsNumber, - cvSize(10, 10), 3, PointsStatus, NULL, - cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS, 5, 1), 0); + HUOFPoints[0], HUOFPoints[1], HUOFPointsNumber, + cvSize(10, 10), 3, PointsStatus, NULL, + cvTermCriteria(CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 5, 1), 0); // Count the distances of the tracked points - int Distances[HUOFPointsNumber][3]; + int **Distances = new int*[HUOFPointsNumber]; + for (int i = 0; i < HUOFPointsNumber; ++i) + Distances[i] = new int[3]; + int DistanceMax = 0; for (i = 0; i < HUOFPointsNumber; ++i) { - int DiffX = (int)MERound(HUOFPoints[1][i].x-HUOFPoints[0][i].x); - int DiffY = (int)MERound(HUOFPoints[1][i].y-HUOFPoints[0][i].y); + int DiffX = (int)MERound(HUOFPoints[1][i].x - HUOFPoints[0][i].x); + int DiffY = (int)MERound(HUOFPoints[1][i].y - HUOFPoints[0][i].y); if ((PointsStatus[i] == 1) && !((DiffX == 0) && (DiffY == 0))) { bool found = false; @@ -1006,7 +1031,7 @@ void MotionDetection::OpticalFlowCorrection() for (i1 = 0; i1 < DistanceMax; ++i1) { if ((Distances[i1][0] == DiffX) && - (Distances[i1][1] == DiffY)) + (Distances[i1][1] == DiffY)) { Distances[i1][2]++; found = true; @@ -1015,8 +1040,8 @@ void MotionDetection::OpticalFlowCorrection() } if ((!found) && !((DiffX == 0) && (DiffY == 0))) { - Distances[DistanceMax][0] = (int)MERound(HUOFPoints[1][i].x-HUOFPoints[0][i].x); - Distances[DistanceMax][1] = (int)MERound(HUOFPoints[1][i].y-HUOFPoints[0][i].y); + Distances[DistanceMax][0] = (int)MERound(HUOFPoints[1][i].x - HUOFPoints[0][i].x); + Distances[DistanceMax][1] = (int)MERound(HUOFPoints[1][i].y - HUOFPoints[0][i].y); Distances[DistanceMax][2] = 1; DistanceMax++; } @@ -1024,25 +1049,27 @@ void MotionDetection::OpticalFlowCorrection() } // Sort the results - for (int i1 = DistanceMax-1; i1 >= 2; --i1) - for (int i = i1; i >= 1; --i) + for (int i1 = DistanceMax - 1; i1 >= 2; --i1) { - if ((Distances[i][2] > Distances[i-1][2]) || - ((Distances[i][2] == Distances[i-1][2]) && - (abs(Distances[i][0])+abs(Distances[i][1]) < - abs(Distances[i-1][0])+abs(Distances[i-1][1])))) + for (int i = i1; i >= 1; --i) { - int tmp = Distances[i][0]; - int tmp2 = Distances[i][1]; - int tmp3 = Distances[i][2]; + if ((Distances[i][2] > Distances[i - 1][2]) || + ((Distances[i][2] == Distances[i - 1][2]) && + (abs(Distances[i][0]) + abs(Distances[i][1]) < + abs(Distances[i - 1][0]) + abs(Distances[i - 1][1])))) + { + int tmp = Distances[i][0]; + int tmp2 = Distances[i][1]; + int tmp3 = Distances[i][2]; - Distances[i][0] = Distances[i-1][0]; - Distances[i][1] = Distances[i-1][1]; - Distances[i][2] = Distances[i-1][2]; + Distances[i][0] = Distances[i - 1][0]; + Distances[i][1] = Distances[i - 1][1]; + Distances[i][2] = Distances[i - 1][2]; - Distances[i-1][0] = tmp; - Distances[i-1][1] = tmp2; - Distances[i-1][2] = tmp3; + Distances[i - 1][0] = tmp; + Distances[i - 1][1] = tmp2; + Distances[i - 1][2] = tmp3; + } } } @@ -1059,12 +1086,12 @@ void MotionDetection::OpticalFlowCorrection() if (i > 0) { - DistanceMeasure += (Distances[i][0]-Distances[i-1][0])*(Distances[i][0]-Distances[i-1][0]); - DistanceMeasure += (Distances[i][1]-Distances[i-1][1])*(Distances[i][1]-Distances[i-1][1]); + DistanceMeasure += (Distances[i][0] - Distances[i - 1][0])*(Distances[i][0] - Distances[i - 1][0]); + DistanceMeasure += (Distances[i][1] - Distances[i - 1][1])*(Distances[i][1] - Distances[i - 1][1]); } - MoveX += Distances[i][0]*Distances[i][2]; - MoveY += Distances[i][1]*Distances[i][2]; + MoveX += Distances[i][0] * Distances[i][2]; + MoveY += Distances[i][1] * Distances[i][2]; SampleNums += Distances[i][2]; } @@ -1075,100 +1102,123 @@ void MotionDetection::OpticalFlowCorrection() } if (!((MoveX == 0) && (MoveY == 0)) && - (SampleNums > MaxTrackedPoints / 2)) + (SampleNums > MaxTrackedPoints / 2)) { HUOFCamMovementX += (int)MoveX; int HUOFCamMovementY = (int)MoveY; - int MaxX = (HUImageWidth / 2)-1; - int MaxY = HUImageHeight-1; -/* + int MaxX = (HUImageWidth / 2) - 1; + int MaxY = HUImageHeight - 1; + /* printf("-----------\n"); for (i = 0; i < DistanceMax; ++i) - printf("%d: %d,%d\n", Distances[i][2], Distances[i][0], Distances[i][1]); + printf("%d: %d,%d\n", Distances[i][2], Distances[i][0], Distances[i][1]); printf("FINAL: %d,%d,%1.2f\n", (int)MoveX, (int)MoveY, DistanceMeasure); printf("-----------\n"); printf("Camera movement: %d,%d,%d (max: %d, current: %d)\n", - SampleNums, HUOFCamMovementX, HUOFCamMovementY, MaxTrackedPoints, HUOFPointsNumber); -*/ + SampleNums, HUOFCamMovementX, HUOFCamMovementY, MaxTrackedPoints, HUOFPointsNumber); + */ HUOFFrames = 0; HUOFCamMovement = true; if (!(HUOFCamMovementY == 0 && HUOFCamMovementX >= -1 && HUOFCamMovementX <= 1)) { - MEPixelDataType* PreviousData[MaxX+1][MaxY+1]; + MEPixelDataType ***PreviousData = new MEPixelDataType**[MaxX + 1]; + + for (int i = 0; i < MaxX + 1; ++i) + PreviousData[i] = new MEPixelDataType*[MaxY + 1]; // Camera movement being happened for (int y = MaxY; y >= 0; --y) - for (int x = MaxX; x >= 0; --x) { - PreviousData[x][y] = NULL; + for (int x = MaxX; x >= 0; --x) + { + PreviousData[x][y] = NULL; + } } // Move the LBP data to new locations for (int y = MaxY; y >= 0; --y) - for (int x = MaxX; x >= 0; --x) { - int NewX = x+(HUOFCamMovementX / 2); - int NewY = y+HUOFCamMovementY; - - if (NewX >= 0 && NewX <= MaxX && - NewY >= 0 && NewY <= MaxY) + for (int x = MaxX; x >= 0; --x) { - if (HULBPPixelData[NewX][NewY]) + int NewX = x + (HUOFCamMovementX / 2); + int NewY = y + HUOFCamMovementY; + + if (NewX >= 0 && NewX <= MaxX && + NewY >= 0 && NewY <= MaxY) { - PreviousData[NewX][NewY] = HULBPPixelData[NewX][NewY]; - HULBPPixelData[NewX][NewY] = NULL; - if (PreviousData[x][y]) + if (HULBPPixelData[NewX][NewY]) { - HULBPPixelData[NewX][NewY] = PreviousData[x][y]; - PreviousData[x][y] = NULL; - } else { - HULBPPixelData[NewX][NewY] = HULBPPixelData[x][y]; - HULBPPixelData[x][y] = NULL; + PreviousData[NewX][NewY] = HULBPPixelData[NewX][NewY]; + HULBPPixelData[NewX][NewY] = NULL; + if (PreviousData[x][y]) + { + HULBPPixelData[NewX][NewY] = PreviousData[x][y]; + PreviousData[x][y] = NULL; + } + else + { + HULBPPixelData[NewX][NewY] = HULBPPixelData[x][y]; + HULBPPixelData[x][y] = NULL; + } } - } else { - if (PreviousData[x][y]) + else { - HULBPPixelData[NewX][NewY] = PreviousData[x][y]; - PreviousData[x][y] = NULL; - } else { - HULBPPixelData[NewX][NewY] = HULBPPixelData[x][y]; - HULBPPixelData[x][y] = NULL; + if (PreviousData[x][y]) + { + HULBPPixelData[NewX][NewY] = PreviousData[x][y]; + PreviousData[x][y] = NULL; + } + else + { + HULBPPixelData[NewX][NewY] = HULBPPixelData[x][y]; + HULBPPixelData[x][y] = NULL; + } } } - } else { - if (HULBPPixelData[x][y]) + else { - delete[] HULBPPixelData[x][y]->PreviousHistogram; - for (int i2 = 0; i2 < HUHistogramsPerPixel; ++i2) - delete[] HULBPPixelData[x][y]->Histograms[i2]; - delete[] HULBPPixelData[x][y]->Histograms; - delete[] HULBPPixelData[x][y]->BackgroundHistogram; - delete[] HULBPPixelData[x][y]->Weights; - delete HULBPPixelData[x][y]; - HULBPPixelData[x][y] = NULL; + if (HULBPPixelData[x][y]) + { + delete[] HULBPPixelData[x][y]->PreviousHistogram; + for (int i2 = 0; i2 < HUHistogramsPerPixel; ++i2) + delete[] HULBPPixelData[x][y]->Histograms[i2]; + delete[] HULBPPixelData[x][y]->Histograms; + delete[] HULBPPixelData[x][y]->BackgroundHistogram; + delete[] HULBPPixelData[x][y]->Weights; + delete HULBPPixelData[x][y]; + HULBPPixelData[x][y] = NULL; + } } } } + // Release unused data for (int y = MaxY; y >= 0; --y) - for (int x = MaxX; x >= 0; --x) { - if (PreviousData[x][y]) + for (int x = MaxX; x >= 0; --x) { - delete[] PreviousData[x][y]->PreviousHistogram; - for (int i2 = 0; i2 < HUHistogramsPerPixel; ++i2) - delete[] PreviousData[x][y]->Histograms[i2]; - delete[] PreviousData[x][y]->Histograms; - delete[] PreviousData[x][y]->BackgroundHistogram; - delete[] PreviousData[x][y]->Weights; - delete PreviousData[x][y]; - PreviousData[x][y] = NULL; + if (PreviousData[x][y]) + { + delete[] PreviousData[x][y]->PreviousHistogram; + for (int i2 = 0; i2 < HUHistogramsPerPixel; ++i2) + delete[] PreviousData[x][y]->Histograms[i2]; + delete[] PreviousData[x][y]->Histograms; + delete[] PreviousData[x][y]->BackgroundHistogram; + delete[] PreviousData[x][y]->Weights; + delete PreviousData[x][y]; + PreviousData[x][y] = NULL; + } } } + HUOFCamMovementX = HUOFCamMovementX % 1; + + for (int i = 0; i < MaxX + 1; ++i) + delete[] PreviousData[i]; + delete[] PreviousData; } } @@ -1182,7 +1232,7 @@ void MotionDetection::OpticalFlowCorrection() i1++; } } - HUOFPointsNumber -= i+1-i1; + HUOFPointsNumber -= i + 1 - i1; if (HUOFPointsNumber < MaxTrackedPoints / 2) { @@ -1196,6 +1246,10 @@ void MotionDetection::OpticalFlowCorrection() if (CurrentGray != CurrentImage.GetIplImage()) cvReleaseImage(&CurrentGray); cvFree(&PointsStatus); + + for (int i = 0; i < HUOFPointsNumber; ++i) + delete[] Distances[i]; + delete[] Distances; } @@ -1208,91 +1262,107 @@ void MotionDetection::GetMotionsMaskHU(MEImage& mask_image) } // Reallocate the mask image if needs be - if ((HUImageWidth+HUHistogramArea-1 != mask_image.GetWidth()) || - (HUImageHeight+HUHistogramArea-1 != mask_image.GetHeight()) || - (mask_image.GetLayers() != 1)) + if ((HUImageWidth + HUHistogramArea - 1 != mask_image.GetWidth()) || + (HUImageHeight + HUHistogramArea - 1 != mask_image.GetHeight()) || + (mask_image.GetLayers() != 1)) { - mask_image.Realloc(HUImageWidth+HUHistogramArea-1, - HUImageHeight+HUHistogramArea-1, 1); + mask_image.Realloc(HUImageWidth + HUHistogramArea - 1, + HUImageHeight + HUHistogramArea - 1, 1); } mask_image.Clear(); // Generate the mask image unsigned char* MaskImgData = mask_image.GetImageData(); - int RowStart = (mask_image.GetHeight()-HUHistogramArea / 2)*mask_image.GetRowWidth(); + int RowStart = (mask_image.GetHeight() - HUHistogramArea / 2)*mask_image.GetRowWidth(); int RowWidth = mask_image.GetRowWidth(); // Generate a graph about the histogram data - Graph::node_id Nodes[HUImageWidth / 2][HUImageHeight]; + Graph::node_id **Nodes = new Graph::node_id*[HUImageWidth / 2]; + for (int i = 0; i < HUImageWidth / 2; ++i) + Nodes[i] = new Graph::node_id[HUImageHeight]; Graph *LBPGraph = new Graph(); - for (int x = (HUImageWidth / 2)-1; x >= 0; --x) - for (int y = HUImageHeight-1; y >= 0; --y) + for (int x = (HUImageWidth / 2) - 1; x >= 0; --x) + { + for (int y = HUImageHeight - 1; y >= 0; --y) { Nodes[x][y] = LBPGraph->add_node(); } + } - for (int x = (HUImageWidth / 2)-1; x >= 0; --x) - for (int y = HUImageHeight-1; y >= 0; --y) + for (int x = (HUImageWidth / 2) - 1; x >= 0; --x) + { + for (int y = HUImageHeight - 1; y >= 0; --y) { LBPGraph->set_tweights(Nodes[x][y], 1, - (short int)(HUMinCutWeight*(1-HULBPPixelData[x][y]->BackgroundRate))); + (short int)(HUMinCutWeight*(1 - HULBPPixelData[x][y]->BackgroundRate))); if (x > 0 && y > 0) { - LBPGraph->add_edge(Nodes[x][y], Nodes[x-1][y], 1, 1); - LBPGraph->add_edge(Nodes[x][y], Nodes[x][y-1], 1, 1); + LBPGraph->add_edge(Nodes[x][y], Nodes[x - 1][y], 1, 1); + LBPGraph->add_edge(Nodes[x][y], Nodes[x][y - 1], 1, 1); } } + } LBPGraph->maxflow(); - for (int x = (HUImageWidth / 2)-1; x >= 0; --x) - for (int y = HUImageHeight-1; y >= 0; --y) + for (int x = (HUImageWidth / 2) - 1; x >= 0; --x) + { + for (int y = HUImageHeight - 1; y >= 0; --y) { if (LBPGraph->what_segment(Nodes[x][y]) == Graph::SINK) HULBPPixelData[x][y]->BackgroundRate = 0.0; else HULBPPixelData[x][y]->BackgroundRate = 1.0; } + } delete LBPGraph; LBPGraph = NULL; - for (int y = HUImageHeight-1; y >= 0; --y) + for (int y = HUImageHeight - 1; y >= 0; --y) { - for (int x = HUImageWidth-1; x >= 0; --x) + for (int x = HUImageWidth - 1; x >= 0; --x) { - if (y % 2 == (x+1) % 2) - MaskImgData[RowStart+x+(HUHistogramArea / 2)] = - (HULBPPixelData[x / 2][y]->BackgroundRate == 0.0) ? 255 : 0; - else { - MaskImgData[RowStart+x+(HUHistogramArea / 2)] = - ((int)(x > 1 && HULBPPixelData[(x / 2)-1][y]->BackgroundRate == 0.0)+ - (int)(x < mask_image.GetWidth()-HUHistogramArea-1 && - HULBPPixelData[(x / 2)+1][y]->BackgroundRate == 0.0)+ - (int)(y > 0 && HULBPPixelData[x / 2][y-1]->BackgroundRate == 0.0)+ - (int)(y < mask_image.GetHeight()-HUHistogramArea && - HULBPPixelData[x / 2][y+1]->BackgroundRate == 0.0) > 1) - ? 255 : 0; + if (y % 2 == (x + 1) % 2) + MaskImgData[RowStart + x + (HUHistogramArea / 2)] = + (HULBPPixelData[x / 2][y]->BackgroundRate == 0.0) ? 255 : 0; + else + { + MaskImgData[RowStart + x + (HUHistogramArea / 2)] = + ((int)(x > 1 && HULBPPixelData[(x / 2) - 1][y]->BackgroundRate == 0.0) + + (int)(x < mask_image.GetWidth() - HUHistogramArea - 1 && + HULBPPixelData[(x / 2) + 1][y]->BackgroundRate == 0.0) + + (int)(y > 0 && HULBPPixelData[x / 2][y - 1]->BackgroundRate == 0.0) + + (int)(y < mask_image.GetHeight() - HUHistogramArea && + HULBPPixelData[x / 2][y + 1]->BackgroundRate == 0.0) > 1) + ? 255 : 0; } } RowStart -= RowWidth; } cvFloodFill(mask_image.GetIplImage(), cvPoint(0, 0), cvScalar(128, 128, 128, 128), - cvScalar(0, 0, 0, 0), cvScalar(0, 0, 0, 0)); - for (int i = ((IplImage*)mask_image.GetIplImage())->widthStep*((IplImage*)mask_image.GetIplImage())->height-1; i >= 0; --i) + cvScalar(0, 0, 0, 0), cvScalar(0, 0, 0, 0)); + for (int i = ((IplImage*)mask_image.GetIplImage())->widthStep*((IplImage*)mask_image.GetIplImage())->height - 1; i >= 0; --i) { if (MaskImgData[i] == 128) { MaskImgData[i] = 0; - } else - if (MaskImgData[i] == 0) + } + else { - MaskImgData[i] = 255; + if (MaskImgData[i] == 0) + { + MaskImgData[i] = 255; + } } } // Apply an erode operator mask_image.Erode(1); + + for (int i = 0; i < HUImageWidth / 2; ++i) + delete[] Nodes[i]; + delete[] Nodes; } @@ -1306,68 +1376,75 @@ void MotionDetection::SetSampleMaskHU(SampleMaskType mask_type, int desiredarea) // Generate a mask for computing the histograms IplImage *MaskImage = cvCreateImage(cvSize(HUHistogramArea, HUHistogramArea), 8, 1); - int DesiredArea = desiredarea <= 0 ? HUHistogramBins*2 : desiredarea; - int CalculationMask[HUHistogramArea][HUHistogramArea]; - int SquareSide = (int)MERound(sqrtf(DesiredArea)); + int DesiredArea = desiredarea <= 0 ? HUHistogramBins * 2 : desiredarea; + + int **CalculationMask = new int*[HUHistogramArea]; + for (int i = 0; i < HUHistogramArea; ++i) + CalculationMask[i] = new int[HUHistogramArea]; + + int SquareSide = (int)MERound(sqrt((float)DesiredArea)); int CircleRadius = (int)MERound(sqrt((float)DesiredArea / ME_PI_VALUE)); - int EllipseA = (int)MERound(HUHistogramArea / 2+1); + int EllipseA = (int)MERound(HUHistogramArea / 2 + 1); int EllipseB = (int)MERound(DesiredArea / (EllipseA*1.2*ME_PI_VALUE)); cvSetZero(MaskImage); switch (mask_type) { - case sm_Circle: - cvCircle(MaskImage, cvPoint(HUHistogramArea / 2, HUHistogramArea / 2), - CircleRadius, CV_RGB(1, 1, 1), -1); - break; - - case sm_Square: - cvRectangle(MaskImage, - cvPoint(HUHistogramArea / 2-SquareSide / 2, HUHistogramArea / 2-SquareSide / 2), - cvPoint(HUHistogramArea / 2+SquareSide / 2, HUHistogramArea / 2+SquareSide / 2), - CV_RGB(1, 1, 1), -1); - break; - - case sm_Ellipse: - cvEllipse(MaskImage, cvPoint(HUHistogramArea / 2, HUHistogramArea / 2), - cvSize(EllipseA, EllipseB), 45, 0, 360, - CV_RGB(1, 1, 1), -1); - break; + case sm_Circle: + cvCircle(MaskImage, cvPoint(HUHistogramArea / 2, HUHistogramArea / 2), + CircleRadius, CV_RGB(1, 1, 1), -1); + break; + + case sm_Square: + cvRectangle(MaskImage, + cvPoint(HUHistogramArea / 2 - SquareSide / 2, HUHistogramArea / 2 - SquareSide / 2), + cvPoint(HUHistogramArea / 2 + SquareSide / 2, HUHistogramArea / 2 + SquareSide / 2), + CV_RGB(1, 1, 1), -1); + break; + + case sm_Ellipse: + cvEllipse(MaskImage, cvPoint(HUHistogramArea / 2, HUHistogramArea / 2), + cvSize(EllipseA, EllipseB), 45, 0, 360, + CV_RGB(1, 1, 1), -1); + break; + + case sm_RandomPixels: + HUSamplePixels = 0; + while (HUSamplePixels != DesiredArea) + { + int i = rand() % HUHistogramArea; + int j = rand() % HUHistogramArea; - case sm_RandomPixels: - HUSamplePixels = 0; - while (HUSamplePixels != DesiredArea) + if (MaskImage->imageData[i*MaskImage->widthStep + j] == 0) { - int i = rand() % HUHistogramArea; - int j = rand() % HUHistogramArea; - - if (MaskImage->imageData[i*MaskImage->widthStep+j] == 0) - { - MaskImage->imageData[i*MaskImage->widthStep+j] = 1; - HUSamplePixels++; - } + MaskImage->imageData[i*MaskImage->widthStep + j] = 1; + HUSamplePixels++; } - break; + } + break; - default: - cvCircle(MaskImage, cvPoint(HUHistogramArea / 2, HUHistogramArea / 2), - (int)MERound(sqrt((float)DesiredArea / ME_PI_VALUE)), CV_RGB(1, 1, 1), -1); - break; + default: + cvCircle(MaskImage, cvPoint(HUHistogramArea / 2, HUHistogramArea / 2), + (int)MERound(sqrt((float)DesiredArea / ME_PI_VALUE)), CV_RGB(1, 1, 1), -1); + break; } HUSamplePixels = 0; - memset(CalculationMask, 0, sizeof(CalculationMask)); + //memset(CalculationMask, 0, sizeof(CalculationMask)); for (int i = 0; i < HUHistogramArea; ++i) - for (int i1 = 0; i1 < HUHistogramArea; ++i1) { - if (MaskImage->imageData[i*MaskImage->widthStep+i1] != 0) + for (int i1 = 0; i1 < HUHistogramArea; ++i1) { - HUSamplePixels++; - CalculationMask[i][i1] = 1; - } else { - CalculationMask[i][i1] = 0; + if (MaskImage->imageData[i*MaskImage->widthStep + i1] != 0) + { + HUSamplePixels++; + CalculationMask[i][i1] = 1; + } + else { + CalculationMask[i][i1] = 0; + } } } @@ -1384,15 +1461,16 @@ void MotionDetection::SetSampleMaskHU(SampleMaskType mask_type, int desiredarea) } } HUMaskColumnAddDel[i][1] = -1; - for (int i1 = HUHistogramArea-1; i1 >= 0; --i1) + for (int i1 = HUHistogramArea - 1; i1 >= 0; --i1) { if (CalculationMask[i][i1] != 0) { - HUMaskColumnAddDel[i][1] = i1+1; + HUMaskColumnAddDel[i][1] = i1 + 1; break; } } } + // Fill an auxiliary variable for fast computing with data for (int i = 0; i < HUHistogramArea; ++i) { @@ -1406,16 +1484,20 @@ void MotionDetection::SetSampleMaskHU(SampleMaskType mask_type, int desiredarea) } } HUMaskRowAddDel[i][1] = -1; - for (int i1 = HUHistogramArea-1; i1 >= 0; --i1) + for (int i1 = HUHistogramArea - 1; i1 >= 0; --i1) { if (CalculationMask[i1][i] != 0) { - HUMaskRowAddDel[i][1] = i1+1; + HUMaskRowAddDel[i][1] = i1 + 1; break; } } } + // Freeing memory cvReleaseImage(&MaskImage); -} + for (int i = 0; i < HUHistogramArea; ++i) + delete[] CalculationMask[i]; + delete[] CalculationMask; +} diff --git a/package_bgs/ck/block.h b/package_bgs/ck/block.h index a243ed1da41b47512afa8ddf9912a275b04cf76a..98b1201fc0c0f506c924c688b51e43923ea649fe 100644 --- a/package_bgs/ck/block.h +++ b/package_bgs/ck/block.h @@ -15,96 +15,96 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ + */ /* - Template classes Block and DBlock - Implement adding and deleting items of the same type in blocks. - - If there there are many items then using Block or DBlock - is more efficient than using 'new' and 'delete' both in terms - of memory and time since - (1) On some systems there is some minimum amount of memory - that 'new' can allocate (e.g., 64), so if items are - small that a lot of memory is wasted. - (2) 'new' and 'delete' are designed for items of varying size. - If all items has the same size, then an algorithm for - adding and deleting can be made more efficient. - (3) All Block and DBlock functions are inline, so there are - no extra function calls. - - Differences between Block and DBlock: - (1) DBlock allows both adding and deleting items, - whereas Block allows only adding items. - (2) Block has an additional operation of scanning - items added so far (in the order in which they were added). - (3) Block allows to allocate several consecutive - items at a time, whereas DBlock can add only a single item. - - Note that no constructors or destructors are called for items. - - Example usage for items of type 'MyType': - - /////////////////////////////////////////////////// - #include "block.h" - #define BLOCK_SIZE 1024 - typedef struct { int a, b; } MyType; - MyType *ptr, *array[10000]; - - ... - - Block<MyType> *block = new Block<MyType>(BLOCK_SIZE); - - // adding items - for (int i=0; i<sizeof(array); i++) - { - ptr = block -> New(); - ptr -> a = ptr -> b = rand(); - } - - // reading items - for (ptr=block->ScanFirst(); ptr; ptr=block->ScanNext()) - { - printf("%d %d\n", ptr->a, ptr->b); - } - - delete block; - - ... - - DBlock<MyType> *dblock = new DBlock<MyType>(BLOCK_SIZE); - - // adding items - for (int i=0; i<sizeof(array); i++) - { - array[i] = dblock -> New(); - } - - // deleting items - for (int i=0; i<sizeof(array); i+=2) - { - dblock -> Delete(array[i]); - } - - // adding items - for (int i=0; i<sizeof(array); i++) - { - array[i] = dblock -> New(); - } - - delete dblock; - - /////////////////////////////////////////////////// - - Note that DBlock deletes items by marking them as - empty (i.e., by adding them to the list of free items), - so that this memory could be used for subsequently - added items. Thus, at each moment the memory allocated - is determined by the maximum number of items allocated - simultaneously at earlier moments. All memory is - deallocated only when the destructor is called. -*/ + Template classes Block and DBlock + Implement adding and deleting items of the same type in blocks. + + If there there are many items then using Block or DBlock + is more efficient than using 'new' and 'delete' both in terms + of memory and time since + (1) On some systems there is some minimum amount of memory + that 'new' can allocate (e.g., 64), so if items are + small that a lot of memory is wasted. + (2) 'new' and 'delete' are designed for items of varying size. + If all items has the same size, then an algorithm for + adding and deleting can be made more efficient. + (3) All Block and DBlock functions are inline, so there are + no extra function calls. + + Differences between Block and DBlock: + (1) DBlock allows both adding and deleting items, + whereas Block allows only adding items. + (2) Block has an additional operation of scanning + items added so far (in the order in which they were added). + (3) Block allows to allocate several consecutive + items at a time, whereas DBlock can add only a single item. + + Note that no constructors or destructors are called for items. + + Example usage for items of type 'MyType': + + /////////////////////////////////////////////////// + #include "block.h" + #define BLOCK_SIZE 1024 + typedef struct { int a, b; } MyType; + MyType *ptr, *array[10000]; + + ... + + Block<MyType> *block = new Block<MyType>(BLOCK_SIZE); + + // adding items + for (int i=0; i<sizeof(array); i++) + { + ptr = block -> New(); + ptr -> a = ptr -> b = rand(); + } + + // reading items + for (ptr=block->ScanFirst(); ptr; ptr=block->ScanNext()) + { + printf("%d %d\n", ptr->a, ptr->b); + } + + delete block; + + ... + + DBlock<MyType> *dblock = new DBlock<MyType>(BLOCK_SIZE); + + // adding items + for (int i=0; i<sizeof(array); i++) + { + array[i] = dblock -> New(); + } + + // deleting items + for (int i=0; i<sizeof(array); i+=2) + { + dblock -> Delete(array[i]); + } + + // adding items + for (int i=0; i<sizeof(array); i++) + { + array[i] = dblock -> New(); + } + + delete dblock; + + /////////////////////////////////////////////////// + + Note that DBlock deletes items by marking them as + empty (i.e., by adding them to the list of free items), + so that this memory could be used for subsequently + added items. Thus, at each moment the memory allocated + is determined by the maximum number of items allocated + simultaneously at earlier moments. All memory is + deallocated only when the destructor is called. + */ #ifndef __BLOCK_H__ #define __BLOCK_H__ @@ -116,171 +116,172 @@ /***********************************************************************/ /***********************************************************************/ -template <class Type> class Block +namespace ck { -public: - /* Constructor. Arguments are the block size and - (optionally) the pointer to the function which - will be called if allocation failed; the message - passed to this function is "Not enough memory!" */ - Block(int size, void (*err_function)(char *) = NULL) { first = last = NULL; block_size = size; error_function = err_function; } - - /* Destructor. Deallocates all items added so far */ - ~Block() { while (first) { block *next = first -> next; delete first; first = next; } } - - /* Allocates 'num' consecutive items; returns pointer - to the first item. 'num' cannot be greater than the - block size since items must fit in one block */ - Type *New(int num = 1) - { - Type *t; - - if (!last || last->current + num > last->last) - { - if (last && last->next) last = last -> next; - else - { - block *next = (block *) new char [sizeof(block) + (block_size-1)*sizeof(Type)]; - if (!next) { fprintf(stderr, "Not enough memory!"); exit(1); } - if (last) last -> next = next; - else first = next; - last = next; - last -> current = & ( last -> data[0] ); - last -> last = last -> current + block_size; - last -> next = NULL; - } - } - - t = last -> current; - last -> current += num; - return t; - } - - /* Returns the first item (or NULL, if no items were added) */ - Type *ScanFirst() - { - scan_current_block = first; - if (!scan_current_block) return NULL; - scan_current_data = & ( scan_current_block -> data[0] ); - return scan_current_data ++; - } - - /* Returns the next item (or NULL, if all items have been read) - Can be called only if previous ScanFirst() or ScanNext() - call returned not NULL. */ - Type *ScanNext() - { - if (scan_current_data >= scan_current_block -> current) - { - scan_current_block = scan_current_block -> next; - if (!scan_current_block) return NULL; - scan_current_data = & ( scan_current_block -> data[0] ); - } - return scan_current_data ++; - } - - /* Marks all elements as empty */ - void Reset() - { - block *b; - if (!first) return; - for (b=first; ; b=b->next) - { - b -> current = & ( b -> data[0] ); - if (b == last) break; - } - last = first; - } - -/***********************************************************************/ - -private: - - typedef struct block_st - { - Type *current, *last; - struct block_st *next; - Type data[1]; - } block; - - int block_size; - block *first; - block *last; - - block *scan_current_block; - Type *scan_current_data; - - void (*error_function)(char *); -}; - -/***********************************************************************/ -/***********************************************************************/ -/***********************************************************************/ - -template <class Type> class DBlock -{ -public: - /* Constructor. Arguments are the block size and - (optionally) the pointer to the function which - will be called if allocation failed; the message - passed to this function is "Not enough memory!" */ - DBlock(int size, void (*err_function)(char *) = NULL) { first = NULL; first_free = NULL; block_size = size; error_function = err_function; } - - /* Destructor. Deallocates all items added so far */ - ~DBlock() { while (first) { block *next = first -> next; delete first; first = next; } } - - /* Allocates one item */ - Type *New() - { - block_item *item; - - if (!first_free) - { - block *next = first; - first = (block *) new char [sizeof(block) + (block_size-1)*sizeof(block_item)]; - if (!first) { fprintf(stderr, "Not enough memory!"); exit(1); } - first_free = & (first -> data[0] ); - for (item=first_free; item<first_free+block_size-1; item++) - item -> next_free = item + 1; - item -> next_free = NULL; - first -> next = next; - } - - item = first_free; - first_free = item -> next_free; - return (Type *) item; - } - - /* Deletes an item allocated previously */ - void Delete(Type *t) - { - ((block_item *) t) -> next_free = first_free; - first_free = (block_item *) t; - } - -/***********************************************************************/ - -private: - - typedef union block_item_st - { - Type t; - block_item_st *next_free; - } block_item; - - typedef struct block_st - { - struct block_st *next; - block_item data[1]; - } block; - - int block_size; - block *first; - block_item *first_free; - - void (*error_function)(char *); -}; - + template <class Type> class Block + { + public: + /* Constructor. Arguments are the block size and + (optionally) the pointer to the function which + will be called if allocation failed; the message + passed to this function is "Not enough memory!" */ + Block(int size, void(*err_function)(char *) = NULL) { first = last = NULL; block_size = size; error_function = err_function; } + + /* Destructor. Deallocates all items added so far */ + ~Block() { while (first) { block *next = first->next; delete first; first = next; } } + + /* Allocates 'num' consecutive items; returns pointer + to the first item. 'num' cannot be greater than the + block size since items must fit in one block */ + Type *New(int num = 1) + { + Type *t; + + if (!last || last->current + num > last->last) + { + if (last && last->next) last = last->next; + else + { + block *next = (block *) new char[sizeof(block) + (block_size - 1)*sizeof(Type)]; + if (!next) { fprintf(stderr, "Not enough memory!"); exit(1); } + if (last) last->next = next; + else first = next; + last = next; + last->current = &(last->data[0]); + last->last = last->current + block_size; + last->next = NULL; + } + } + + t = last->current; + last->current += num; + return t; + } + + /* Returns the first item (or NULL, if no items were added) */ + Type *ScanFirst() + { + scan_current_block = first; + if (!scan_current_block) return NULL; + scan_current_data = &(scan_current_block->data[0]); + return scan_current_data++; + } + + /* Returns the next item (or NULL, if all items have been read) + Can be called only if previous ScanFirst() or ScanNext() + call returned not NULL. */ + Type *ScanNext() + { + if (scan_current_data >= scan_current_block->current) + { + scan_current_block = scan_current_block->next; + if (!scan_current_block) return NULL; + scan_current_data = &(scan_current_block->data[0]); + } + return scan_current_data++; + } + + /* Marks all elements as empty */ + void Reset() + { + block *b; + if (!first) return; + for (b = first;; b = b->next) + { + b->current = &(b->data[0]); + if (b == last) break; + } + last = first; + } + + /***********************************************************************/ + + private: + + typedef struct block_st + { + Type *current, *last; + struct block_st *next; + Type data[1]; + } block; + + int block_size; + block *first; + block *last; + + block *scan_current_block; + Type *scan_current_data; + + void(*error_function)(char *); + }; + + /***********************************************************************/ + /***********************************************************************/ + /***********************************************************************/ + + template <class Type> class DBlock + { + public: + /* Constructor. Arguments are the block size and + (optionally) the pointer to the function which + will be called if allocation failed; the message + passed to this function is "Not enough memory!" */ + DBlock(int size, void(*err_function)(char *) = NULL) { first = NULL; first_free = NULL; block_size = size; error_function = err_function; } + + /* Destructor. Deallocates all items added so far */ + ~DBlock() { while (first) { block *next = first->next; delete first; first = next; } } + + /* Allocates one item */ + Type *New() + { + block_item *item; + + if (!first_free) + { + block *next = first; + first = (block *) new char[sizeof(block) + (block_size - 1)*sizeof(block_item)]; + if (!first) { fprintf(stderr, "Not enough memory!"); exit(1); } + first_free = &(first->data[0]); + for (item = first_free; item < first_free + block_size - 1; item++) + item->next_free = item + 1; + item->next_free = NULL; + first->next = next; + } + + item = first_free; + first_free = item->next_free; + return (Type *)item; + } + + /* Deletes an item allocated previously */ + void Delete(Type *t) + { + ((block_item *)t)->next_free = first_free; + first_free = (block_item *)t; + } + + /***********************************************************************/ + + private: + + typedef union block_item_st + { + Type t; + block_item_st *next_free; + } block_item; + + typedef struct block_st + { + struct block_st *next; + block_item data[1]; + } block; + + int block_size; + block *first; + block_item *first_free; + + void(*error_function)(char *); + }; +} #endif - diff --git a/package_bgs/ck/graph.cpp b/package_bgs/ck/graph.cpp index fb4cf9ff752514a402eedb9acf0ab061347395af..daed395f15c9cfa57d902177bee676ff99e76d4d 100644 --- a/package_bgs/ck/graph.cpp +++ b/package_bgs/ck/graph.cpp @@ -15,66 +15,69 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ + */ #include <stdio.h> #include "graph.h" -Graph::Graph(void (*err_function)(char *)) +namespace ck { - error_function = err_function; - node_block = new Block<node>(NODE_BLOCK_SIZE, error_function); - arc_block = new Block<arc>(NODE_BLOCK_SIZE, error_function); - flow = 0; -} + Graph::Graph(void(*err_function)(char *)) + { + error_function = err_function; + node_block = new Block<node>(NODE_BLOCK_SIZE, error_function); + arc_block = new Block<arc>(NODE_BLOCK_SIZE, error_function); + flow = 0; + } -Graph::~Graph() -{ - delete node_block; - delete arc_block; -} + Graph::~Graph() + { + delete node_block; + delete arc_block; + } -Graph::node_id Graph::add_node() -{ - node *i = node_block -> New(); + Graph::node_id Graph::add_node() + { + node *i = node_block->New(); - i -> first = NULL; - i -> tr_cap = 0; + i->first = NULL; + i->tr_cap = 0; - return (node_id) i; -} + return (node_id)i; + } -void Graph::add_edge(node_id from, node_id to, captype cap, captype rev_cap) -{ - arc *a, *a_rev; + void Graph::add_edge(node_id from, node_id to, captype cap, captype rev_cap) + { + arc *a, *a_rev; - a = arc_block -> New(2); - a_rev = a + 1; + a = arc_block->New(2); + a_rev = a + 1; - a -> sister = a_rev; - a_rev -> sister = a; - a -> next = ((node*)from) -> first; - ((node*)from) -> first = a; - a_rev -> next = ((node*)to) -> first; - ((node*)to) -> first = a_rev; - a -> head = (node*)to; - a_rev -> head = (node*)from; - a -> r_cap = cap; - a_rev -> r_cap = rev_cap; -} + a->sister = a_rev; + a_rev->sister = a; + a->next = ((node*)from)->first; + ((node*)from)->first = a; + a_rev->next = ((node*)to)->first; + ((node*)to)->first = a_rev; + a->head = (node*)to; + a_rev->head = (node*)from; + a->r_cap = cap; + a_rev->r_cap = rev_cap; + } -void Graph::set_tweights(node_id i, captype cap_source, captype cap_sink) -{ - flow += (cap_source < cap_sink) ? cap_source : cap_sink; - ((node*)i) -> tr_cap = cap_source - cap_sink; -} + void Graph::set_tweights(node_id i, captype cap_source, captype cap_sink) + { + flow += (cap_source < cap_sink) ? cap_source : cap_sink; + ((node*)i)->tr_cap = cap_source - cap_sink; + } -void Graph::add_tweights(node_id i, captype cap_source, captype cap_sink) -{ - register captype delta = ((node*)i) -> tr_cap; - if (delta > 0) cap_source += delta; - else cap_sink -= delta; - flow += (cap_source < cap_sink) ? cap_source : cap_sink; - ((node*)i) -> tr_cap = cap_source - cap_sink; -} + void Graph::add_tweights(node_id i, captype cap_source, captype cap_sink) + { + register captype delta = ((node*)i)->tr_cap; + if (delta > 0) cap_source += delta; + else cap_sink -= delta; + flow += (cap_source < cap_sink) ? cap_source : cap_sink; + ((node*)i)->tr_cap = cap_source - cap_sink; + } +} \ No newline at end of file diff --git a/package_bgs/ck/graph.h b/package_bgs/ck/graph.h index fdae5661b6b9a2ea56317a79e6c680503475f015..b6799e40eb07fa24b40288af89daa194c37c26f0 100644 --- a/package_bgs/ck/graph.h +++ b/package_bgs/ck/graph.h @@ -1,45 +1,45 @@ /* graph.h */ /* - This software library implements the maxflow algorithm - described in - - An Experimental Comparison of Min-Cut/Max-Flow Algorithms - for Energy Minimization in Vision. - Yuri Boykov and Vladimir Kolmogorov. - In IEEE Transactions on Pattern Analysis and Machine Intelligence (PAMI), - September 2004 - - This algorithm was developed by Yuri Boykov and Vladimir Kolmogorov - at Siemens Corporate Research. To make it available for public use, - it was later reimplemented by Vladimir Kolmogorov based on open publications. - - If you use this software for research purposes, you should cite - the aforementioned paper in any resulting publication. -*/ - -/* - Copyright 2001 Vladimir Kolmogorov (vnk@cs.cornell.edu), Yuri Boykov (yuri@csd.uwo.ca). - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ + This software library implements the maxflow algorithm + described in + + An Experimental Comparison of Min-Cut/Max-Flow Algorithms + for Energy Minimization in Vision. + Yuri Boykov and Vladimir Kolmogorov. + In IEEE Transactions on Pattern Analysis and Machine Intelligence (PAMI), + September 2004 + + This algorithm was developed by Yuri Boykov and Vladimir Kolmogorov + at Siemens Corporate Research. To make it available for public use, + it was later reimplemented by Vladimir Kolmogorov based on open publications. + + If you use this software for research purposes, you should cite + the aforementioned paper in any resulting publication. + */ + +/* + Copyright 2001 Vladimir Kolmogorov (vnk@cs.cornell.edu), Yuri Boykov (yuri@csd.uwo.ca). + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ /* - For description, example usage, discussion of graph representation - and memory usage see README.TXT. -*/ + For description, example usage, discussion of graph representation + and memory usage see README.TXT. + */ #ifndef __GRAPH_H__ #define __GRAPH_H__ @@ -47,134 +47,137 @@ #include "block.h" /* - Nodes, arcs and pointers to nodes are - added in blocks for memory and time efficiency. - Below are numbers of items in blocks -*/ + Nodes, arcs and pointers to nodes are + added in blocks for memory and time efficiency. + Below are numbers of items in blocks + */ #define NODE_BLOCK_SIZE 512 #define ARC_BLOCK_SIZE 1024 #define NODEPTR_BLOCK_SIZE 128 -class Graph +namespace ck { -public: - typedef enum - { - SOURCE = 0, - SINK = 1 - } termtype; /* terminals */ - - /* Type of edge weights. - Can be changed to char, int, float, double, ... */ - typedef short captype; - /* Type of total flow */ - typedef int flowtype; - - typedef void * node_id; - - /* interface functions */ - - /* Constructor. Optional argument is the pointer to the - function which will be called if an error occurs; - an error message is passed to this function. If this - argument is omitted, exit(1) will be called. */ - Graph(void (*err_function)(char *) = NULL); - - /* Destructor */ - ~Graph(); - - /* Adds a node to the graph */ - node_id add_node(); - - /* Adds a bidirectional edge between 'from' and 'to' - with the weights 'cap' and 'rev_cap' */ - void add_edge(node_id from, node_id to, captype cap, captype rev_cap); - - /* Sets the weights of the edges 'SOURCE->i' and 'i->SINK' - Can be called at most once for each node before any call to 'add_tweights'. - Weights can be negative */ - void set_tweights(node_id i, captype cap_source, captype cap_sink); - - /* Adds new edges 'SOURCE->i' and 'i->SINK' with corresponding weights - Can be called multiple times for each node. - Weights can be negative */ - void add_tweights(node_id i, captype cap_source, captype cap_sink); - - /* After the maxflow is computed, this function returns to which - segment the node 'i' belongs (Graph::SOURCE or Graph::SINK) */ - termtype what_segment(node_id i); - - /* Computes the maxflow. Can be called only once. */ - flowtype maxflow(); - -/***********************************************************************/ -/***********************************************************************/ -/***********************************************************************/ - -private: - /* internal variables and functions */ - - struct arc_st; - - /* node structure */ - typedef struct node_st - { - arc_st *first; /* first outcoming arc */ - - arc_st *parent; /* node's parent */ - node_st *next; /* pointer to the next active node - (or to itself if it is the last node in the list) */ - int TS; /* timestamp showing when DIST was computed */ - int DIST; /* distance to the terminal */ - short is_sink; /* flag showing whether the node is in the source or in the sink tree */ - - captype tr_cap; /* if tr_cap > 0 then tr_cap is residual capacity of the arc SOURCE->node - otherwise -tr_cap is residual capacity of the arc node->SINK */ - } node; - - /* arc structure */ - typedef struct arc_st - { - node_st *head; /* node the arc points to */ - arc_st *next; /* next arc with the same originating node */ - arc_st *sister; /* reverse arc */ - - captype r_cap; /* residual capacity */ - } arc; - - /* 'pointer to node' structure */ - typedef struct nodeptr_st - { - node_st *ptr; - nodeptr_st *next; - } nodeptr; - - Block<node> *node_block; - Block<arc> *arc_block; - DBlock<nodeptr> *nodeptr_block; - - void (*error_function)(char *); /* this function is called if a error occurs, - with a corresponding error message - (or exit(1) is called if it's NULL) */ - - flowtype flow; /* total flow */ - -/***********************************************************************/ - - node *queue_first[2], *queue_last[2]; /* list of active nodes */ - nodeptr *orphan_first, *orphan_last; /* list of pointers to orphans */ - int TIME; /* monotonically increasing global counter */ - -/***********************************************************************/ - - /* functions for processing active list */ - void set_active(node *i); - node *next_active(); - - void maxflow_init(); - void augment(arc *middle_arc); - void process_source_orphan(node *i); - void process_sink_orphan(node *i); -}; + class Graph + { + public: + typedef enum + { + SOURCE = 0, + SINK = 1 + } termtype; /* terminals */ + + /* Type of edge weights. + Can be changed to char, int, float, double, ... */ + typedef short captype; + /* Type of total flow */ + typedef int flowtype; + + typedef void * node_id; + + /* interface functions */ + + /* Constructor. Optional argument is the pointer to the + function which will be called if an error occurs; + an error message is passed to this function. If this + argument is omitted, exit(1) will be called. */ + Graph(void(*err_function)(char *) = NULL); + + /* Destructor */ + ~Graph(); + + /* Adds a node to the graph */ + node_id add_node(); + + /* Adds a bidirectional edge between 'from' and 'to' + with the weights 'cap' and 'rev_cap' */ + void add_edge(node_id from, node_id to, captype cap, captype rev_cap); + + /* Sets the weights of the edges 'SOURCE->i' and 'i->SINK' + Can be called at most once for each node before any call to 'add_tweights'. + Weights can be negative */ + void set_tweights(node_id i, captype cap_source, captype cap_sink); + + /* Adds new edges 'SOURCE->i' and 'i->SINK' with corresponding weights + Can be called multiple times for each node. + Weights can be negative */ + void add_tweights(node_id i, captype cap_source, captype cap_sink); + + /* After the maxflow is computed, this function returns to which + segment the node 'i' belongs (Graph::SOURCE or Graph::SINK) */ + termtype what_segment(node_id i); + + /* Computes the maxflow. Can be called only once. */ + flowtype maxflow(); + + /***********************************************************************/ + /***********************************************************************/ + /***********************************************************************/ + + private: + /* internal variables and functions */ + + struct arc_st; + + /* node structure */ + typedef struct node_st + { + arc_st *first; /* first outcoming arc */ + + arc_st *parent; /* node's parent */ + node_st *next; /* pointer to the next active node + (or to itself if it is the last node in the list) */ + int TS; /* timestamp showing when DIST was computed */ + int DIST; /* distance to the terminal */ + short is_sink; /* flag showing whether the node is in the source or in the sink tree */ + + captype tr_cap; /* if tr_cap > 0 then tr_cap is residual capacity of the arc SOURCE->node + otherwise -tr_cap is residual capacity of the arc node->SINK */ + } node; + + /* arc structure */ + typedef struct arc_st + { + node_st *head; /* node the arc points to */ + arc_st *next; /* next arc with the same originating node */ + arc_st *sister; /* reverse arc */ + + captype r_cap; /* residual capacity */ + } arc; + + /* 'pointer to node' structure */ + typedef struct nodeptr_st + { + node_st *ptr; + nodeptr_st *next; + } nodeptr; + + Block<node> *node_block; + Block<arc> *arc_block; + DBlock<nodeptr> *nodeptr_block; + + void(*error_function)(char *); /* this function is called if a error occurs, + with a corresponding error message + (or exit(1) is called if it's NULL) */ + + flowtype flow; /* total flow */ + + /***********************************************************************/ + + node *queue_first[2], *queue_last[2]; /* list of active nodes */ + nodeptr *orphan_first, *orphan_last; /* list of pointers to orphans */ + int TIME; /* monotonically increasing global counter */ + + /***********************************************************************/ + + /* functions for processing active list */ + void set_active(node *i); + node *next_active(); + + void maxflow_init(); + void augment(arc *middle_arc); + void process_source_orphan(node *i); + void process_sink_orphan(node *i); + }; +} #endif diff --git a/package_bgs/ck/maxflow.cpp b/package_bgs/ck/maxflow.cpp index 8812a4a85d016049b70351c5aca936acca21868f..53d37057057423950921bb6f8184cde88e5b3603 100644 --- a/package_bgs/ck/maxflow.cpp +++ b/package_bgs/ck/maxflow.cpp @@ -15,15 +15,15 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ + */ #include <stdio.h> #include "graph.h" /* - special constants for node->parent -*/ + special constants for node->parent + */ #define TERMINAL ( (arc *) 1 ) /* to terminal */ #define ORPHAN ( (arc *) 2 ) /* orphan */ @@ -32,483 +32,485 @@ /***********************************************************************/ /* - Functions for processing active list. - i->next points to the next node in the list - (or to i, if i is the last node in the list). - If i->next is NULL iff i is not in the list. - - There are two queues. Active nodes are added - to the end of the second queue and read from - the front of the first queue. If the first queue - is empty, it is replaced by the second queue - (and the second queue becomes empty). -*/ - -inline void Graph::set_active(node *i) + Functions for processing active list. + i->next points to the next node in the list + (or to i, if i is the last node in the list). + If i->next is NULL iff i is not in the list. + + There are two queues. Active nodes are added + to the end of the second queue and read from + the front of the first queue. If the first queue + is empty, it is replaced by the second queue + (and the second queue becomes empty). + */ +namespace ck { - if (!i->next) - { - /* it's not in the list yet */ - if (queue_last[1]) queue_last[1] -> next = i; - else queue_first[1] = i; - queue_last[1] = i; - i -> next = i; - } -} - -/* - Returns the next active node. - If it is connected to the sink, it stays in the list, - otherwise it is removed from the list -*/ -inline Graph::node * Graph::next_active() -{ - node *i; - - while ( 1 ) - { - if (!(i=queue_first[0])) - { - queue_first[0] = i = queue_first[1]; - queue_last[0] = queue_last[1]; - queue_first[1] = NULL; - queue_last[1] = NULL; - if (!i) return NULL; - } - - /* remove it from the active list */ - if (i->next == i) queue_first[0] = queue_last[0] = NULL; - else queue_first[0] = i -> next; - i -> next = NULL; - - /* a node in the list is active iff it has a parent */ - if (i->parent) return i; - } -} - -/***********************************************************************/ - -void Graph::maxflow_init() -{ - node *i; - - queue_first[0] = queue_last[0] = NULL; - queue_first[1] = queue_last[1] = NULL; - orphan_first = NULL; - - for (i=node_block->ScanFirst(); i; i=node_block->ScanNext()) - { - i -> next = NULL; - i -> TS = 0; - if (i->tr_cap > 0) - { - /* i is connected to the source */ - i -> is_sink = 0; - i -> parent = TERMINAL; - set_active(i); - i -> TS = 0; - i -> DIST = 1; - } - else if (i->tr_cap < 0) - { - /* i is connected to the sink */ - i -> is_sink = 1; - i -> parent = TERMINAL; - set_active(i); - i -> TS = 0; - i -> DIST = 1; - } - else - { - i -> parent = NULL; - } - } - TIME = 0; -} - -/***********************************************************************/ - -void Graph::augment(arc *middle_arc) -{ - node *i; - arc *a; - captype bottleneck; - nodeptr *np; - - - /* 1. Finding bottleneck capacity */ - /* 1a - the source tree */ - bottleneck = middle_arc -> r_cap; - for (i=middle_arc->sister->head; ; i=a->head) - { - a = i -> parent; - if (a == TERMINAL) break; - if (bottleneck > a->sister->r_cap) bottleneck = a -> sister -> r_cap; - } - if (bottleneck > i->tr_cap) bottleneck = i -> tr_cap; - /* 1b - the sink tree */ - for (i=middle_arc->head; ; i=a->head) - { - a = i -> parent; - if (a == TERMINAL) break; - if (bottleneck > a->r_cap) bottleneck = a -> r_cap; - } - if (bottleneck > - i->tr_cap) bottleneck = - i -> tr_cap; - - - /* 2. Augmenting */ - /* 2a - the source tree */ - middle_arc -> sister -> r_cap += bottleneck; - middle_arc -> r_cap -= bottleneck; - for (i=middle_arc->sister->head; ; i=a->head) - { - a = i -> parent; - if (a == TERMINAL) break; - a -> r_cap += bottleneck; - a -> sister -> r_cap -= bottleneck; - if (!a->sister->r_cap) - { - /* add i to the adoption list */ - i -> parent = ORPHAN; - np = nodeptr_block -> New(); - np -> ptr = i; - np -> next = orphan_first; - orphan_first = np; - } - } - i -> tr_cap -= bottleneck; - if (!i->tr_cap) - { - /* add i to the adoption list */ - i -> parent = ORPHAN; - np = nodeptr_block -> New(); - np -> ptr = i; - np -> next = orphan_first; - orphan_first = np; - } - /* 2b - the sink tree */ - for (i=middle_arc->head; ; i=a->head) - { - a = i -> parent; - if (a == TERMINAL) break; - a -> sister -> r_cap += bottleneck; - a -> r_cap -= bottleneck; - if (!a->r_cap) - { - /* add i to the adoption list */ - i -> parent = ORPHAN; - np = nodeptr_block -> New(); - np -> ptr = i; - np -> next = orphan_first; - orphan_first = np; - } - } - i -> tr_cap += bottleneck; - if (!i->tr_cap) - { - /* add i to the adoption list */ - i -> parent = ORPHAN; - np = nodeptr_block -> New(); - np -> ptr = i; - np -> next = orphan_first; - orphan_first = np; - } - - - flow += bottleneck; -} - -/***********************************************************************/ - -void Graph::process_source_orphan(node *i) -{ - node *j; - arc *a0, *a0_min = NULL, *a; - nodeptr *np; - int d, d_min = INFINITE_D; - - /* trying to find a new parent */ - for (a0=i->first; a0; a0=a0->next) - if (a0->sister->r_cap) - { - j = a0 -> head; - if (!j->is_sink && (a=j->parent)) - { - /* checking the origin of j */ - d = 0; - while ( 1 ) - { - if (j->TS == TIME) - { - d += j -> DIST; - break; - } - a = j -> parent; - d ++; - if (a==TERMINAL) - { - j -> TS = TIME; - j -> DIST = 1; - break; - } - if (a==ORPHAN) { d = INFINITE_D; break; } - j = a -> head; - } - if (d<INFINITE_D) /* j originates from the source - done */ - { - if (d<d_min) - { - a0_min = a0; - d_min = d; - } - /* set marks along the path */ - for (j=a0->head; j->TS!=TIME; j=j->parent->head) - { - j -> TS = TIME; - j -> DIST = d --; - } - } - } - } - - if ((i->parent = a0_min)) - { - i -> TS = TIME; - i -> DIST = d_min + 1; - } - else - { - /* no parent is found */ - i -> TS = 0; - - /* process neighbors */ - for (a0=i->first; a0; a0=a0->next) - { - j = a0 -> head; - if (!j->is_sink && (a=j->parent)) - { - if (a0->sister->r_cap) set_active(j); - if (a!=TERMINAL && a!=ORPHAN && a->head==i) - { - /* add j to the adoption list */ - j -> parent = ORPHAN; - np = nodeptr_block -> New(); - np -> ptr = j; - if (orphan_last) orphan_last -> next = np; - else orphan_first = np; - orphan_last = np; - np -> next = NULL; - } - } - } - } -} - -void Graph::process_sink_orphan(node *i) -{ - node *j; - arc *a0, *a0_min = NULL, *a; - nodeptr *np; - int d, d_min = INFINITE_D; - - /* trying to find a new parent */ - for (a0=i->first; a0; a0=a0->next) - if (a0->r_cap) - { - j = a0 -> head; - if (j->is_sink && (a=j->parent)) - { - /* checking the origin of j */ - d = 0; - while ( 1 ) - { - if (j->TS == TIME) - { - d += j -> DIST; - break; - } - a = j -> parent; - d ++; - if (a==TERMINAL) - { - j -> TS = TIME; - j -> DIST = 1; - break; - } - if (a==ORPHAN) { d = INFINITE_D; break; } - j = a -> head; - } - if (d<INFINITE_D) /* j originates from the sink - done */ - { - if (d<d_min) - { - a0_min = a0; - d_min = d; - } - /* set marks along the path */ - for (j=a0->head; j->TS!=TIME; j=j->parent->head) - { - j -> TS = TIME; - j -> DIST = d --; - } - } - } - } - - if ((i->parent = a0_min)) - { - i -> TS = TIME; - i -> DIST = d_min + 1; - } - else - { - /* no parent is found */ - i -> TS = 0; - - /* process neighbors */ - for (a0=i->first; a0; a0=a0->next) - { - j = a0 -> head; - if (j->is_sink && (a=j->parent)) - { - if (a0->r_cap) set_active(j); - if (a!=TERMINAL && a!=ORPHAN && a->head==i) - { - /* add j to the adoption list */ - j -> parent = ORPHAN; - np = nodeptr_block -> New(); - np -> ptr = j; - if (orphan_last) orphan_last -> next = np; - else orphan_first = np; - orphan_last = np; - np -> next = NULL; - } - } - } - } -} - -/***********************************************************************/ - -Graph::flowtype Graph::maxflow() -{ - node *i, *j, *current_node = NULL; - arc *a; - nodeptr *np, *np_next; - - maxflow_init(); - nodeptr_block = new DBlock<nodeptr>(NODEPTR_BLOCK_SIZE, error_function); - - while ( 1 ) - { - if ((i=current_node)) - { - i -> next = NULL; /* remove active flag */ - if (!i->parent) i = NULL; - } - if (!i) - { - if (!(i = next_active())) break; - } - - /* growth */ - if (!i->is_sink) - { - /* grow source tree */ - for (a=i->first; a; a=a->next) - if (a->r_cap) - { - j = a -> head; - if (!j->parent) - { - j -> is_sink = 0; - j -> parent = a -> sister; - j -> TS = i -> TS; - j -> DIST = i -> DIST + 1; - set_active(j); - } - else if (j->is_sink) break; - else if (j->TS <= i->TS && - j->DIST > i->DIST) - { - /* heuristic - trying to make the distance from j to the source shorter */ - j -> parent = a -> sister; - j -> TS = i -> TS; - j -> DIST = i -> DIST + 1; - } - } - } - else - { - /* grow sink tree */ - for (a=i->first; a; a=a->next) - if (a->sister->r_cap) - { - j = a -> head; - if (!j->parent) - { - j -> is_sink = 1; - j -> parent = a -> sister; - j -> TS = i -> TS; - j -> DIST = i -> DIST + 1; - set_active(j); - } - else if (!j->is_sink) { a = a -> sister; break; } - else if (j->TS <= i->TS && - j->DIST > i->DIST) - { - /* heuristic - trying to make the distance from j to the sink shorter */ - j -> parent = a -> sister; - j -> TS = i -> TS; - j -> DIST = i -> DIST + 1; - } - } - } - - TIME ++; - - if (a) - { - i -> next = i; /* set active flag */ - current_node = i; - - /* augmentation */ - augment(a); - /* augmentation end */ - - /* adoption */ - while ((np=orphan_first)) - { - np_next = np -> next; - np -> next = NULL; - - while ((np=orphan_first)) - { - orphan_first = np -> next; - i = np -> ptr; - nodeptr_block -> Delete(np); - if (!orphan_first) orphan_last = NULL; - if (i->is_sink) process_sink_orphan(i); - else process_source_orphan(i); - } - - orphan_first = np_next; - } - /* adoption end */ - } - else current_node = NULL; - } - - delete nodeptr_block; - - return flow; -} - -/***********************************************************************/ - -Graph::termtype Graph::what_segment(node_id i) -{ - if (((node*)i)->parent && !((node*)i)->is_sink) return SOURCE; - return SINK; -} - + inline void Graph::set_active(node *i) + { + if (!i->next) + { + /* it's not in the list yet */ + if (queue_last[1]) queue_last[1]->next = i; + else queue_first[1] = i; + queue_last[1] = i; + i->next = i; + } + } + + /* + Returns the next active node. + If it is connected to the sink, it stays in the list, + otherwise it is removed from the list + */ + inline Graph::node * Graph::next_active() + { + node *i; + + while (1) + { + if (!(i = queue_first[0])) + { + queue_first[0] = i = queue_first[1]; + queue_last[0] = queue_last[1]; + queue_first[1] = NULL; + queue_last[1] = NULL; + if (!i) return NULL; + } + + /* remove it from the active list */ + if (i->next == i) queue_first[0] = queue_last[0] = NULL; + else queue_first[0] = i->next; + i->next = NULL; + + /* a node in the list is active iff it has a parent */ + if (i->parent) return i; + } + } + + /***********************************************************************/ + + void Graph::maxflow_init() + { + node *i; + + queue_first[0] = queue_last[0] = NULL; + queue_first[1] = queue_last[1] = NULL; + orphan_first = NULL; + + for (i = node_block->ScanFirst(); i; i = node_block->ScanNext()) + { + i->next = NULL; + i->TS = 0; + if (i->tr_cap > 0) + { + /* i is connected to the source */ + i->is_sink = 0; + i->parent = TERMINAL; + set_active(i); + i->TS = 0; + i->DIST = 1; + } + else if (i->tr_cap < 0) + { + /* i is connected to the sink */ + i->is_sink = 1; + i->parent = TERMINAL; + set_active(i); + i->TS = 0; + i->DIST = 1; + } + else + { + i->parent = NULL; + } + } + TIME = 0; + } + + /***********************************************************************/ + + void Graph::augment(arc *middle_arc) + { + node *i; + arc *a; + captype bottleneck; + nodeptr *np; + + + /* 1. Finding bottleneck capacity */ + /* 1a - the source tree */ + bottleneck = middle_arc->r_cap; + for (i = middle_arc->sister->head;; i = a->head) + { + a = i->parent; + if (a == TERMINAL) break; + if (bottleneck > a->sister->r_cap) bottleneck = a->sister->r_cap; + } + if (bottleneck > i->tr_cap) bottleneck = i->tr_cap; + /* 1b - the sink tree */ + for (i = middle_arc->head;; i = a->head) + { + a = i->parent; + if (a == TERMINAL) break; + if (bottleneck > a->r_cap) bottleneck = a->r_cap; + } + if (bottleneck > -i->tr_cap) bottleneck = -i->tr_cap; + + + /* 2. Augmenting */ + /* 2a - the source tree */ + middle_arc->sister->r_cap += bottleneck; + middle_arc->r_cap -= bottleneck; + for (i = middle_arc->sister->head;; i = a->head) + { + a = i->parent; + if (a == TERMINAL) break; + a->r_cap += bottleneck; + a->sister->r_cap -= bottleneck; + if (!a->sister->r_cap) + { + /* add i to the adoption list */ + i->parent = ORPHAN; + np = nodeptr_block->New(); + np->ptr = i; + np->next = orphan_first; + orphan_first = np; + } + } + i->tr_cap -= bottleneck; + if (!i->tr_cap) + { + /* add i to the adoption list */ + i->parent = ORPHAN; + np = nodeptr_block->New(); + np->ptr = i; + np->next = orphan_first; + orphan_first = np; + } + /* 2b - the sink tree */ + for (i = middle_arc->head;; i = a->head) + { + a = i->parent; + if (a == TERMINAL) break; + a->sister->r_cap += bottleneck; + a->r_cap -= bottleneck; + if (!a->r_cap) + { + /* add i to the adoption list */ + i->parent = ORPHAN; + np = nodeptr_block->New(); + np->ptr = i; + np->next = orphan_first; + orphan_first = np; + } + } + i->tr_cap += bottleneck; + if (!i->tr_cap) + { + /* add i to the adoption list */ + i->parent = ORPHAN; + np = nodeptr_block->New(); + np->ptr = i; + np->next = orphan_first; + orphan_first = np; + } + + + flow += bottleneck; + } + + /***********************************************************************/ + + void Graph::process_source_orphan(node *i) + { + node *j; + arc *a0, *a0_min = NULL, *a; + nodeptr *np; + int d, d_min = INFINITE_D; + + /* trying to find a new parent */ + for (a0 = i->first; a0; a0 = a0->next) + if (a0->sister->r_cap) + { + j = a0->head; + if (!j->is_sink && (a = j->parent)) + { + /* checking the origin of j */ + d = 0; + while (1) + { + if (j->TS == TIME) + { + d += j->DIST; + break; + } + a = j->parent; + d++; + if (a == TERMINAL) + { + j->TS = TIME; + j->DIST = 1; + break; + } + if (a == ORPHAN) { d = INFINITE_D; break; } + j = a->head; + } + if (d < INFINITE_D) /* j originates from the source - done */ + { + if (d < d_min) + { + a0_min = a0; + d_min = d; + } + /* set marks along the path */ + for (j = a0->head; j->TS != TIME; j = j->parent->head) + { + j->TS = TIME; + j->DIST = d--; + } + } + } + } + + if ((i->parent = a0_min)) + { + i->TS = TIME; + i->DIST = d_min + 1; + } + else + { + /* no parent is found */ + i->TS = 0; + + /* process neighbors */ + for (a0 = i->first; a0; a0 = a0->next) + { + j = a0->head; + if (!j->is_sink && (a = j->parent)) + { + if (a0->sister->r_cap) set_active(j); + if (a != TERMINAL && a != ORPHAN && a->head == i) + { + /* add j to the adoption list */ + j->parent = ORPHAN; + np = nodeptr_block->New(); + np->ptr = j; + if (orphan_last) orphan_last->next = np; + else orphan_first = np; + orphan_last = np; + np->next = NULL; + } + } + } + } + } + + void Graph::process_sink_orphan(node *i) + { + node *j; + arc *a0, *a0_min = NULL, *a; + nodeptr *np; + int d, d_min = INFINITE_D; + + /* trying to find a new parent */ + for (a0 = i->first; a0; a0 = a0->next) + if (a0->r_cap) + { + j = a0->head; + if (j->is_sink && (a = j->parent)) + { + /* checking the origin of j */ + d = 0; + while (1) + { + if (j->TS == TIME) + { + d += j->DIST; + break; + } + a = j->parent; + d++; + if (a == TERMINAL) + { + j->TS = TIME; + j->DIST = 1; + break; + } + if (a == ORPHAN) { d = INFINITE_D; break; } + j = a->head; + } + if (d < INFINITE_D) /* j originates from the sink - done */ + { + if (d < d_min) + { + a0_min = a0; + d_min = d; + } + /* set marks along the path */ + for (j = a0->head; j->TS != TIME; j = j->parent->head) + { + j->TS = TIME; + j->DIST = d--; + } + } + } + } + + if ((i->parent = a0_min)) + { + i->TS = TIME; + i->DIST = d_min + 1; + } + else + { + /* no parent is found */ + i->TS = 0; + + /* process neighbors */ + for (a0 = i->first; a0; a0 = a0->next) + { + j = a0->head; + if (j->is_sink && (a = j->parent)) + { + if (a0->r_cap) set_active(j); + if (a != TERMINAL && a != ORPHAN && a->head == i) + { + /* add j to the adoption list */ + j->parent = ORPHAN; + np = nodeptr_block->New(); + np->ptr = j; + if (orphan_last) orphan_last->next = np; + else orphan_first = np; + orphan_last = np; + np->next = NULL; + } + } + } + } + } + + /***********************************************************************/ + + Graph::flowtype Graph::maxflow() + { + node *i, *j, *current_node = NULL; + arc *a; + nodeptr *np, *np_next; + + maxflow_init(); + nodeptr_block = new DBlock<nodeptr>(NODEPTR_BLOCK_SIZE, error_function); + + while (1) + { + if ((i = current_node)) + { + i->next = NULL; /* remove active flag */ + if (!i->parent) i = NULL; + } + if (!i) + { + if (!(i = next_active())) break; + } + + /* growth */ + if (!i->is_sink) + { + /* grow source tree */ + for (a = i->first; a; a = a->next) + if (a->r_cap) + { + j = a->head; + if (!j->parent) + { + j->is_sink = 0; + j->parent = a->sister; + j->TS = i->TS; + j->DIST = i->DIST + 1; + set_active(j); + } + else if (j->is_sink) break; + else if (j->TS <= i->TS && + j->DIST > i->DIST) + { + /* heuristic - trying to make the distance from j to the source shorter */ + j->parent = a->sister; + j->TS = i->TS; + j->DIST = i->DIST + 1; + } + } + } + else + { + /* grow sink tree */ + for (a = i->first; a; a = a->next) + if (a->sister->r_cap) + { + j = a->head; + if (!j->parent) + { + j->is_sink = 1; + j->parent = a->sister; + j->TS = i->TS; + j->DIST = i->DIST + 1; + set_active(j); + } + else if (!j->is_sink) { a = a->sister; break; } + else if (j->TS <= i->TS && + j->DIST > i->DIST) + { + /* heuristic - trying to make the distance from j to the sink shorter */ + j->parent = a->sister; + j->TS = i->TS; + j->DIST = i->DIST + 1; + } + } + } + + TIME++; + + if (a) + { + i->next = i; /* set active flag */ + current_node = i; + + /* augmentation */ + augment(a); + /* augmentation end */ + + /* adoption */ + while ((np = orphan_first)) + { + np_next = np->next; + np->next = NULL; + + while ((np = orphan_first)) + { + orphan_first = np->next; + i = np->ptr; + nodeptr_block->Delete(np); + if (!orphan_first) orphan_last = NULL; + if (i->is_sink) process_sink_orphan(i); + else process_source_orphan(i); + } + + orphan_first = np_next; + } + /* adoption end */ + } + else current_node = NULL; + } + + delete nodeptr_block; + + return flow; + } + + /***********************************************************************/ + + Graph::termtype Graph::what_segment(node_id i) + { + if (((node*)i)->parent && !((node*)i)->is_sink) return SOURCE; + return SINK; + } + +} \ No newline at end of file diff --git a/vs2010/bgslibrary.sln b/vs2010/bgslibrary.sln index 06187d0549eb46226ede71906d13e14a2d563691..8574aed9420472129223ff5f386b91ae28d267de 100644 --- a/vs2010/bgslibrary.sln +++ b/vs2010/bgslibrary.sln @@ -1,18 +1,26 @@ -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.30626.0 +MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bgslibrary", "bgslibrary.vcxproj", "{3B6BF763-9CDE-4859-ADD9-8EB7B282659F}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 + ReleaseDemo|Win32 = ReleaseDemo|Win32 + ReleaseDemo2|Win32 = ReleaseDemo2|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {3B6BF763-9CDE-4859-ADD9-8EB7B282659F}.Debug|Win32.ActiveCfg = Debug|Win32 {3B6BF763-9CDE-4859-ADD9-8EB7B282659F}.Debug|Win32.Build.0 = Debug|Win32 {3B6BF763-9CDE-4859-ADD9-8EB7B282659F}.Release|Win32.ActiveCfg = Release|Win32 {3B6BF763-9CDE-4859-ADD9-8EB7B282659F}.Release|Win32.Build.0 = Release|Win32 + {3B6BF763-9CDE-4859-ADD9-8EB7B282659F}.ReleaseDemo|Win32.ActiveCfg = ReleaseDemo|Win32 + {3B6BF763-9CDE-4859-ADD9-8EB7B282659F}.ReleaseDemo|Win32.Build.0 = ReleaseDemo|Win32 + {3B6BF763-9CDE-4859-ADD9-8EB7B282659F}.ReleaseDemo2|Win32.ActiveCfg = ReleaseDemo2|Win32 + {3B6BF763-9CDE-4859-ADD9-8EB7B282659F}.ReleaseDemo2|Win32.Build.0 = ReleaseDemo2|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/vs2010/bgslibrary.vcxproj b/vs2010/bgslibrary.vcxproj index 97a119af6160d66560de4e6acc2da2dae0939193..afc99bcafee37fff210b73a1efd5af66474f42e2 100644 --- a/vs2010/bgslibrary.vcxproj +++ b/vs2010/bgslibrary.vcxproj @@ -5,6 +5,14 @@ <Configuration>Debug</Configuration> <Platform>Win32</Platform> </ProjectConfiguration> + <ProjectConfiguration Include="ReleaseDemo2|Win32"> + <Configuration>ReleaseDemo2</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="ReleaseDemo|Win32"> + <Configuration>ReleaseDemo</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> <ProjectConfiguration Include="Release|Win32"> <Configuration>Release</Configuration> <Platform>Win32</Platform> @@ -27,6 +35,18 @@ <WholeProgramOptimization>true</WholeProgramOptimization> <CharacterSet>Unicode</CharacterSet> </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <ImportGroup Label="ExtensionSettings"> </ImportGroup> @@ -36,6 +56,12 @@ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> <PropertyGroup Label="UserMacros" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <LinkIncremental>true</LinkIncremental> @@ -44,6 +70,16 @@ <LinkIncremental>false</LinkIncremental> <OutDir>..\</OutDir> </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>..\</OutDir> + <TargetName>Demo</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>..\</OutDir> + <TargetName>Demo2</TargetName> + </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ClCompile> <PrecompiledHeader> @@ -77,18 +113,66 @@ <AdditionalDependencies>C:\OpenCV2.4.9\build\x86\vc10\staticlib\*.lib;comctl32.lib;VFW32.lib;%(AdditionalDependencies)</AdditionalDependencies> </Link> </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>C:\OpenCV2.4.9\build\include;C:\OpenCV2.4.9\build\include\opencv;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalDependencies>C:\OpenCV2.4.9\build\x86\vc10\staticlib\*.lib;comctl32.lib;VFW32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>C:\OpenCV2.4.9\build\include;C:\OpenCV2.4.9\build\include\opencv;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalDependencies>C:\OpenCV2.4.9\build\x86\vc10\staticlib\*.lib;comctl32.lib;VFW32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> <ItemGroup> <ClCompile Include="..\Demo.cpp"> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|Win32'">true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\Demo2.cpp"> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|Win32'">false</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\FrameProcessor.cpp"> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|Win32'">false</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\Main.cpp"> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|Win32'">true</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\package_analysis\ForegroundMaskAnalysis.cpp" /> <ClCompile Include="..\package_bgs\AdaptiveBackgroundLearning.cpp" /> @@ -102,6 +186,13 @@ <ClCompile Include="..\package_bgs\av\VuMeter.cpp" /> <ClCompile Include="..\package_bgs\bl\sdLaMa091.cpp" /> <ClCompile Include="..\package_bgs\bl\SigmaDeltaBGS.cpp" /> + <ClCompile Include="..\package_bgs\ck\graph.cpp" /> + <ClCompile Include="..\package_bgs\ck\LbpMrf.cpp" /> + <ClCompile Include="..\package_bgs\ck\maxflow.cpp" /> + <ClCompile Include="..\package_bgs\ck\MEDefs.cpp" /> + <ClCompile Include="..\package_bgs\ck\MEHistogram.cpp" /> + <ClCompile Include="..\package_bgs\ck\MEImage.cpp" /> + <ClCompile Include="..\package_bgs\ck\MotionDetection.cpp" /> <ClCompile Include="..\package_bgs\db\imbs.cpp" /> <ClCompile Include="..\package_bgs\db\IndependentMultimodalBGS.cpp" /> <ClCompile Include="..\package_bgs\dp\AdaptiveMedianBGS.cpp" /> @@ -161,23 +252,35 @@ <ClCompile Include="..\package_bgs\WeightedMovingVarianceBGS.cpp" /> <ClCompile Include="..\PreProcessor.cpp"> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|Win32'">false</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\VideoAnalysis.cpp"> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|Win32'">false</ExcludedFromBuild> </ClCompile> <ClCompile Include="..\VideoCapture.cpp"> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|Win32'">false</ExcludedFromBuild> </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="..\Config.h"> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|Win32'">false</ExcludedFromBuild> </ClInclude> <ClInclude Include="..\FrameProcessor.h"> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|Win32'">false</ExcludedFromBuild> </ClInclude> <ClInclude Include="..\IFrameProcessor.h"> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|Win32'">false</ExcludedFromBuild> </ClInclude> <ClInclude Include="..\package_analysis\ForegroundMaskAnalysis.h" /> <ClInclude Include="..\package_bgs\AdaptiveBackgroundLearning.h" /> @@ -192,6 +295,13 @@ <ClInclude Include="..\package_bgs\bl\sdLaMa091.h" /> <ClInclude Include="..\package_bgs\bl\SigmaDeltaBGS.h" /> <ClInclude Include="..\package_bgs\bl\stdbool.h" /> + <ClInclude Include="..\package_bgs\ck\block.h" /> + <ClInclude Include="..\package_bgs\ck\graph.h" /> + <ClInclude Include="..\package_bgs\ck\LbpMrf.h" /> + <ClInclude Include="..\package_bgs\ck\MEDefs.hpp" /> + <ClInclude Include="..\package_bgs\ck\MEHistogram.hpp" /> + <ClInclude Include="..\package_bgs\ck\MEImage.hpp" /> + <ClInclude Include="..\package_bgs\ck\MotionDetection.hpp" /> <ClInclude Include="..\package_bgs\db\imbs.hpp" /> <ClInclude Include="..\package_bgs\db\IndependentMultimodalBGS.h" /> <ClInclude Include="..\package_bgs\dp\AdaptiveMedianBGS.h" /> @@ -259,12 +369,18 @@ <ClInclude Include="..\package_bgs\WeightedMovingVarianceBGS.h" /> <ClInclude Include="..\PreProcessor.h"> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|Win32'">false</ExcludedFromBuild> </ClInclude> <ClInclude Include="..\VideoAnalysis.h"> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|Win32'">false</ExcludedFromBuild> </ClInclude> <ClInclude Include="..\VideoCapture.h"> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|Win32'">false</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|Win32'">false</ExcludedFromBuild> </ClInclude> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> diff --git a/vs2010/bgslibrary.vcxproj.filters b/vs2010/bgslibrary.vcxproj.filters index b2401b0287ac39c646420bc8e9b1b406d1e6a26c..7f29c49dc044e826894b6decbdbac2d5981e7093 100644 --- a/vs2010/bgslibrary.vcxproj.filters +++ b/vs2010/bgslibrary.vcxproj.filters @@ -52,6 +52,9 @@ <Filter Include="Header Files\package_bgs\bl"> <UniqueIdentifier>{0494c5d4-b4bb-421c-b032-176903ba8e1b}</UniqueIdentifier> </Filter> + <Filter Include="Header Files\package_bgs\ck"> + <UniqueIdentifier>{87961eee-b843-45bd-b642-9dcd9d78b661}</UniqueIdentifier> + </Filter> </ItemGroup> <ItemGroup> <ClCompile Include="..\package_bgs\AdaptiveBackgroundLearning.cpp"> @@ -282,6 +285,27 @@ <ClCompile Include="..\package_bgs\bl\sdLaMa091.cpp"> <Filter>Header Files\package_bgs\bl</Filter> </ClCompile> + <ClCompile Include="..\package_bgs\ck\graph.cpp"> + <Filter>Header Files\package_bgs\ck</Filter> + </ClCompile> + <ClCompile Include="..\package_bgs\ck\LbpMrf.cpp"> + <Filter>Header Files\package_bgs\ck</Filter> + </ClCompile> + <ClCompile Include="..\package_bgs\ck\maxflow.cpp"> + <Filter>Header Files\package_bgs\ck</Filter> + </ClCompile> + <ClCompile Include="..\package_bgs\ck\MEDefs.cpp"> + <Filter>Header Files\package_bgs\ck</Filter> + </ClCompile> + <ClCompile Include="..\package_bgs\ck\MEHistogram.cpp"> + <Filter>Header Files\package_bgs\ck</Filter> + </ClCompile> + <ClCompile Include="..\package_bgs\ck\MEImage.cpp"> + <Filter>Header Files\package_bgs\ck</Filter> + </ClCompile> + <ClCompile Include="..\package_bgs\ck\MotionDetection.cpp"> + <Filter>Header Files\package_bgs\ck</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="..\package_bgs\AdaptiveBackgroundLearning.h"> @@ -536,5 +560,26 @@ <ClInclude Include="..\package_bgs\bl\stdbool.h"> <Filter>Header Files\package_bgs\bl</Filter> </ClInclude> + <ClInclude Include="..\package_bgs\ck\block.h"> + <Filter>Header Files\package_bgs\ck</Filter> + </ClInclude> + <ClInclude Include="..\package_bgs\ck\graph.h"> + <Filter>Header Files\package_bgs\ck</Filter> + </ClInclude> + <ClInclude Include="..\package_bgs\ck\LbpMrf.h"> + <Filter>Header Files\package_bgs\ck</Filter> + </ClInclude> + <ClInclude Include="..\package_bgs\ck\MEDefs.hpp"> + <Filter>Header Files\package_bgs\ck</Filter> + </ClInclude> + <ClInclude Include="..\package_bgs\ck\MEHistogram.hpp"> + <Filter>Header Files\package_bgs\ck</Filter> + </ClInclude> + <ClInclude Include="..\package_bgs\ck\MEImage.hpp"> + <Filter>Header Files\package_bgs\ck</Filter> + </ClInclude> + <ClInclude Include="..\package_bgs\ck\MotionDetection.hpp"> + <Filter>Header Files\package_bgs\ck</Filter> + </ClInclude> </ItemGroup> </Project> \ No newline at end of file diff --git a/vs2010/bgslibrary.vcxproj.user b/vs2010/bgslibrary.vcxproj.user index 471a5d00739b89391a056890a6ba493a3b4b5ee1..2249595b7cd9ff2ff4778c512091a50ca3b2f498 100644 --- a/vs2010/bgslibrary.vcxproj.user +++ b/vs2010/bgslibrary.vcxproj.user @@ -5,4 +5,15 @@ <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> <LocalDebuggerCommandArguments>-uf=true -fn=dataset/video.avi</LocalDebuggerCommandArguments> </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo|Win32'"> + <LocalDebuggerWorkingDirectory>../</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + <LocalDebuggerCommandArguments> + </LocalDebuggerCommandArguments> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDemo2|Win32'"> + <LocalDebuggerWorkingDirectory>../</LocalDebuggerWorkingDirectory> + <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> + <LocalDebuggerCommandArguments /> + </PropertyGroup> </Project> \ No newline at end of file