/Code/core/ComponentBackgroundSubtractionGray.cpp

https://github.com/roboshepherd/swistrackplus · C++ · 125 lines · 93 code · 18 blank · 14 comment · 29 complexity · 929716ce4f4a9edf7e8d20e4b1110977 MD5 · raw file

  1. #include "ComponentBackgroundSubtractionGray.h"
  2. #define THISCLASS ComponentBackgroundSubtractionGray
  3. #include <highgui.h>
  4. #include "DisplayEditor.h"
  5. THISCLASS::ComponentBackgroundSubtractionGray(SwisTrackCore *stc):
  6. Component(stc, wxT("BackgroundSubtractionGray")),
  7. mBackgroundImage(0), mBackgroundImageMean(cvScalarAll(0)),
  8. mCorrectMean(true), mMode(sMode_AbsDiff),
  9. mDisplayOutput(wxT("Output"), wxT("After background subtraction")) {
  10. // Data structure relations
  11. mCategory = &(mCore->mCategoryPreprocessingGray);
  12. AddDataStructureRead(&(mCore->mDataStructureImageGray));
  13. AddDataStructureWrite(&(mCore->mDataStructureImageGray));
  14. AddDisplay(&mDisplayOutput);
  15. // Read the XML configuration file
  16. Initialize();
  17. }
  18. THISCLASS::~ComponentBackgroundSubtractionGray() {
  19. }
  20. void THISCLASS::OnStart() {
  21. // Load the background image
  22. wxString filename_string = GetConfigurationString(wxT("BackgroundImage"), wxT(""));
  23. wxFileName filename = mCore->GetProjectFileName(filename_string);
  24. if (filename.IsOk()) {
  25. mBackgroundImage = cvLoadImage(filename.GetFullPath().mb_str(wxConvFile), CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);
  26. }
  27. if (! mBackgroundImage) {
  28. AddError(wxT("Cannot open background image."));
  29. return;
  30. }
  31. // Check the background image
  32. // We explicitely do not convert image to grayscale automatically, as this is likely to be a configuration error of the user (e.g. wrong background selected). In addition, the user can easily convert a file to grayscale.
  33. if (mBackgroundImage->nChannels != 1) {
  34. AddError(wxT("Background image is not grayscale."));
  35. return;
  36. }
  37. // Read the reloadable parameters
  38. OnReloadConfiguration();
  39. }
  40. void THISCLASS::OnReloadConfiguration() {
  41. // Whether to correct the mean or not
  42. mCorrectMean = GetConfigurationBool(wxT("CorrectMean"), true);
  43. // Mode
  44. wxString modestr = GetConfigurationString(wxT("Mode"), wxT("AbsDiff"));
  45. if (modestr == wxT("SubImageBackground")) {
  46. mMode = sMode_SubImageBackground;
  47. } else if (modestr == wxT("SubBackgroundImage")) {
  48. mMode = sMode_SubBackgroundImage;
  49. } else {
  50. mMode = sMode_AbsDiff;
  51. }
  52. // We always calculate the background average, so we can select if we use the moving threshold during the segmentation
  53. if (mCorrectMean) {
  54. mBackgroundImageMean = cvAvg(mBackgroundImage);
  55. } else {
  56. mBackgroundImageMean = cvScalar(0);
  57. }
  58. }
  59. void THISCLASS::OnStep() {
  60. // Get and check input image
  61. IplImage *inputimage = mCore->mDataStructureImageGray.mImage;
  62. if (! inputimage) {
  63. AddError(wxT("No input image."));
  64. return;
  65. }
  66. if (inputimage->nChannels != 1) {
  67. AddError(wxT("The input image is not a grayscale image."));
  68. return;
  69. }
  70. // Check the background image
  71. if (! mBackgroundImage) {
  72. AddError(wxT("No background image loaded."));
  73. return;
  74. }
  75. if ((cvGetSize(inputimage).height != cvGetSize(mBackgroundImage).height) || (cvGetSize(inputimage).width != cvGetSize(mBackgroundImage).width)) {
  76. AddError(wxT("Input and background images don't have the same size."));
  77. return;
  78. }
  79. try {
  80. // Correct the inputimage with the difference in image mean
  81. if (mCorrectMean) {
  82. cvAddS(inputimage, cvScalar(mBackgroundImageMean.val[0] - cvAvg(inputimage).val[0]), inputimage);
  83. }
  84. // Background subtraction
  85. if (mMode == sMode_SubImageBackground) {
  86. cvSub(inputimage, mBackgroundImage, inputimage);
  87. } else if (mMode == sMode_SubBackgroundImage) {
  88. cvSub(mBackgroundImage, inputimage, inputimage);
  89. } else {
  90. cvAbsDiff(inputimage, mBackgroundImage, inputimage);
  91. }
  92. } catch (...) {
  93. AddError(wxT("Background subtraction failed."));
  94. }
  95. // Set the display
  96. DisplayEditor de(&mDisplayOutput);
  97. if (de.IsActive()) {
  98. de.SetMainImage(inputimage);
  99. }
  100. }
  101. void THISCLASS::OnStepCleanup() {
  102. }
  103. void THISCLASS::OnStop() {
  104. if (mBackgroundImage) {
  105. cvReleaseImage(&mBackgroundImage);
  106. }
  107. }