PageRenderTime 88ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/Code/core/ComponentHSVBackgroundSubtractionColor.cpp

https://github.com/roboshepherd/swistrackplus
C++ | 148 lines | 120 code | 14 blank | 14 comment | 27 complexity | 5d9bc34f3b011640dc638431a958858d MD5 | raw file
  1. #include "ComponentHSVBackgroundSubtractionColor.h"
  2. #define THISCLASS ComponentHSVBackgroundSubtractionColor
  3. #include <highgui.h>
  4. #include "DisplayEditor.h"
  5. THISCLASS::ComponentHSVBackgroundSubtractionColor(SwisTrackCore *stc):
  6. Component(stc, wxT("HSVBackgroundSubtractionColor")),
  7. mBackgroundImage(0), mCorrectMean(true),
  8. mDisplayOutput(wxT("Output"), wxT("After background subtraction")) {
  9. // Data structure relations
  10. mCategory = &(mCore->mCategoryPreprocessingColor);
  11. AddDataStructureRead(&(mCore->mDataStructureImageColor));
  12. AddDataStructureWrite(&(mCore->mDataStructureImageGray));
  13. AddDisplay(&mDisplayOutput);
  14. // Read the XML configuration file
  15. Initialize();
  16. }
  17. THISCLASS::~ComponentHSVBackgroundSubtractionColor() {
  18. }
  19. void THISCLASS::OnStart() {
  20. wxString filename_string = GetConfigurationString(wxT("BackgroundImage"), wxT(""));
  21. wxFileName filename = mCore->GetProjectFileName(filename_string);
  22. if (filename.IsOk()) {
  23. mBackgroundImage = cvLoadImage(filename.GetFullPath().mb_str(wxConvFile), CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);
  24. }
  25. if (! mBackgroundImage) {
  26. AddError(wxT("Cannot open background image."));
  27. return;
  28. }
  29. if (mBackgroundImage->nChannels != 3)
  30. {
  31. AddError(wxT("Background Image has not 3 channels"));
  32. return;
  33. }
  34. tmpHSVImage = cvCreateImage(cvGetSize(mBackgroundImage), 8, 3);
  35. mBackgroundImageHSV = cvCreateImage(cvGetSize(mBackgroundImage), 8, 1);
  36. tmpBinaryImage = cvCreateImage(cvGetSize(mBackgroundImage), 8, 1);
  37. //Convert image in HSV
  38. cvCvtColor(mBackgroundImage, tmpHSVImage, CV_BGR2HSV);
  39. cvSplit(tmpHSVImage, mBackgroundImageHSV, NULL, NULL, NULL);
  40. outputImage = NULL;
  41. }
  42. void THISCLASS::OnReloadConfiguration()
  43. {
  44. }
  45. void THISCLASS::OnStep() {
  46. IplImage *inputimage = mCore->mDataStructureImageColor.mImage;
  47. //Check the images
  48. if (! inputimage)
  49. {
  50. AddError(wxT("No input Image"));
  51. return;
  52. }
  53. if (inputimage->nChannels != 3)
  54. {
  55. AddError(wxT("Input image has not 3 channels."));
  56. return;
  57. }
  58. if (!outputImage)
  59. {
  60. //If the input image was not yet created
  61. outputImage = cvCreateImage(cvGetSize(inputimage), 8, 1);
  62. }
  63. mCore->mDataStructureImageGray.mImage = outputImage;
  64. if (! mBackgroundImage)
  65. {
  66. AddError(wxT("Background image not accessible"));
  67. return;
  68. }
  69. if ((cvGetSize(inputimage).height != cvGetSize(mBackgroundImage).height) || (cvGetSize(inputimage).width != cvGetSize(mBackgroundImage).width))
  70. {
  71. AddError(wxT("Input and background images have not the same dimension"));
  72. return;
  73. }
  74. //Check for the color system of the input image (The loaded image is BGR, OpenCV default) and convert the background respectively
  75. if (strncmp(mCore->mDataStructureImageColor.mImage->channelSeq, mBackgroundImage->channelSeq, 3))
  76. {
  77. //Make a temporary clone of the image in 3 seperate channels
  78. IplImage* tmpImage[3];
  79. for (int i = 0;i < 3;i++)
  80. tmpImage[i] = cvCreateImage(cvGetSize(mBackgroundImage), 8, 1);
  81. cvSplit(mBackgroundImage, tmpImage[0], tmpImage[1], tmpImage[2], NULL);
  82. //Modify the sequence of the channels in the background
  83. for (int i = 0;i < 3;i++)
  84. //If the channel is not the same, search for the corresponding channel to copy, else copy the channel directly
  85. if (inputimage->channelSeq[i] != mBackgroundImage->channelSeq[i])
  86. for (int j = 0;j < 3;j++)
  87. if (inputimage->channelSeq[i] == mBackgroundImage->channelSeq[j])
  88. {
  89. cvSetImageCOI(mBackgroundImage, i + 1);
  90. cvCopy(tmpImage[j], mBackgroundImage);
  91. //Remove the COI
  92. cvSetImageCOI(mBackgroundImage, 0);
  93. }
  94. strcpy(mBackgroundImage->channelSeq, inputimage->channelSeq);
  95. for (int i = 0; i < 3;i++)
  96. cvReleaseImage(&(tmpImage[i]));
  97. //Convert image in HSV
  98. cvCvtColor(mBackgroundImage, tmpHSVImage, CV_BGR2HSV);
  99. cvSplit(tmpHSVImage, mBackgroundImageHSV, NULL, NULL, NULL);
  100. }
  101. try {
  102. cvCvtColor(inputimage, tmpHSVImage, CV_BGR2HSV);
  103. cvSplit(tmpHSVImage, outputImage, NULL, NULL, NULL);
  104. // Background Substraction
  105. cvAbsDiff(outputImage, mBackgroundImageHSV, outputImage);
  106. //Here we have to do something fancy, has in HSV 180 is close to 0
  107. cvThreshold(outputImage, tmpBinaryImage, 90, 255, CV_THRESH_BINARY);
  108. cvSubRS(outputImage, cvScalar(180), outputImage, tmpBinaryImage);
  109. } catch (...) {
  110. AddError(wxT("Background subtraction failed."));
  111. }
  112. // Set the display
  113. DisplayEditor de(&mDisplayOutput);
  114. if (de.IsActive()) {
  115. de.SetMainImage(outputImage);
  116. }
  117. }
  118. void THISCLASS::OnStepCleanup() {
  119. }
  120. void THISCLASS::OnStop()
  121. {
  122. if (mBackgroundImage) {
  123. cvReleaseImage(&mBackgroundImage);
  124. }
  125. if (tmpHSVImage) {
  126. cvReleaseImage(&tmpHSVImage);
  127. }
  128. if (tmpBinaryImage) {
  129. cvReleaseImage(&tmpBinaryImage);
  130. }
  131. if (outputImage) {
  132. cvReleaseImage(&(outputImage));
  133. }
  134. }