Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

178 linhas
6.7 KiB

  1. """test_feature_extractors_functional.py -- functional tests for feature extractors
  2. This module contains functional tests for FEs using crafted and/or generated media files
  3. to verify that the FEs are working as expected:
  4. - laughter detection -- uses videos with laughs at known times
  5. - video activity -- uses videos with visual activity at known times
  6. - audio loudness -- uses videos with audio at known times
  7. etc.
  8. These tests are marked slow to avoid running them during normal test runs.
  9. """
  10. import pytest
  11. import unittest
  12. import pipeline.feature_extractors as extractors
  13. import test.mocks as mocks
  14. class FEFunctionalTest(unittest.TestCase):
  15. """FEFunctionalTest -- base class for functional tests for feature extractors
  16. """
  17. SAMPLE_DIR = "/home/robert/code/softdev2023-24/summerproject/highlights/test/sample_videos"
  18. @pytest.mark.slow
  19. @pytest.mark.veryslow
  20. class TestLaughterFEFunctional(FEFunctionalTest):
  21. """TestLaughterFEFunctional -- functional tests for laughter detection feature extractor"""
  22. def test_laughter_detection_positive(self):
  23. """Test laughter detection feature extractor
  24. Uses:
  25. - sample_videos/sample-manual-audio-laughs-video-colours.mp4
  26. :: laughters at 15-20s
  27. -- pass iff laughter features extracted in this range, *but*
  28. NOTE: LaughFE subtracts from start time to capture what preceded the laughter
  29. so we need to subtract this time (and adds a little after too)
  30. FE 'exposes' these as _PREPEND_TIME and _APPEND_TIME
  31. Note: takes 8-10s to run for this 30s video using GTX 970. As such this test can be skipped with either:
  32. "-m 'not veryslow'" or "-m 'not slow'"
  33. """
  34. SAMPLE_VIDEO = f"{self.SAMPLE_DIR}/sample-manual-audio-laughs-video-colours.mp4"
  35. START_TIME = 15
  36. END_TIME = 20
  37. # create mock source with the video
  38. source = mocks.MockSource(path=SAMPLE_VIDEO)
  39. # create the feature extractor
  40. testfe = extractors.LaughterFeatureExtractor(input_files=[source])
  41. testfe.setup()
  42. testfe.run()
  43. testfe.teardown()
  44. # check if the feature was extracted:
  45. self.assertTrue(testfe.features)
  46. # check if the feature interval is within the expected range
  47. self.assertTrue(testfe.features[0].interval.start >= (START_TIME - testfe._PREPEND_TIME))
  48. self.assertTrue(testfe.features[0].interval.end <= (END_TIME + testfe._APPEND_TIME))
  49. def test_laughter_detection_negative(self):
  50. """Negative test for laughter detection feature extractor -- should not detect laughter in a silent video
  51. Uses:
  52. - sample_videos/sample-manual-audio-blank-video-colours.mp4
  53. :: silent video (30s)
  54. -- pass iff no laughter features
  55. """
  56. SAMPLE_VIDEO = f"{self.SAMPLE_DIR}/sample-manual-audio-blank-video-colours.mp4"
  57. # create mock source with the video
  58. source = mocks.MockSource(path=SAMPLE_VIDEO)
  59. # create the feature extractor
  60. testfe = extractors.LaughterFeatureExtractor(input_files=[source])
  61. testfe.setup()
  62. testfe.run()
  63. testfe.teardown()
  64. # check if the feature was extracted:
  65. self.assertFalse(testfe.features)
  66. class TestVideoActivityFEFunctional(FEFunctionalTest):
  67. """TestVisualActivityFEFunctional -- functional tests for visual activity feature extractor
  68. """
  69. def test_visual_activity_functional(self):
  70. """Test visual activity feature extractor
  71. use:
  72. - sample_videos/sample-manual-visualactivity.mp4 :: activity at 15-20s -- pass if activity detected anywhere in this range
  73. """
  74. SAMPLE_VIDEO = f"{self.SAMPLE_DIR}/sample-manual-visualactivity.mp4"
  75. START_TIME = 15
  76. END_TIME = 20
  77. # create mock source with the video
  78. source = mocks.MockSource(path=SAMPLE_VIDEO)
  79. # create the feature extractor
  80. testfe = extractors.VideoActivityFeatureExtractor(input_files=[source])
  81. testfe.setup()
  82. testfe.run()
  83. testfe.teardown()
  84. # check if the feature was extracted:
  85. self.assertTrue(testfe.features)
  86. # check if the feature interval is within the expected range
  87. self.assertTrue(testfe.features[0].interval.start >= START_TIME)
  88. class TestLoudAudioFEFunctional(FEFunctionalTest):
  89. """TestAudioLoudnessFEFunctional -- functional tests for audio loudness feature extractor
  90. """
  91. def test_audio_loudness_functional_one_feature(self):
  92. """Test audio loudness feature extractor
  93. use:
  94. - sample_videos/sample-manual-audio.mp4 :: audio at 15-20s -- pass if audio detected anywhere in this range
  95. -- peak at 16s - 18s, verify this is highest scoring
  96. """
  97. SAMPLE_VIDEO = f"{self.SAMPLE_DIR}/sample-manual-audio.mp4"
  98. START_TIME = 15
  99. END_TIME = 20
  100. PEAK_START = 16
  101. PEAK_END = 18
  102. # create mock source with the video
  103. source = mocks.MockSource(path=SAMPLE_VIDEO)
  104. # create the feature extractor
  105. testfe = extractors.LoudAudioFeatureExtractor(input_files=[source])
  106. testfe.setup()
  107. testfe.run()
  108. testfe.teardown()
  109. # check if the feature was extracted:
  110. self.assertTrue(testfe.features)
  111. # check if the feature interval is within the expected range
  112. self.assertTrue(testfe.features[0].interval.start >= START_TIME)
  113. # get sorted list of features based on feature.score
  114. sorted_features = sorted(testfe.features, key=lambda x: x.score, reverse=True)
  115. # check if the highest scoring feature is within the peak range
  116. self.assertTrue(sorted_features[0].interval.start >= PEAK_START)
  117. def test_audio_loudness_functional_no_features(self):
  118. """Test audio loudness feature extractor using a silent video. This should produce no features
  119. since "-inf" results from pyloudnorm are filtered out by the FE.
  120. Use:
  121. - sample_videos/sample-manual-audio-blank-video-colours.mp4
  122. :: silent video (30s)
  123. -- pass if no features extracted
  124. """
  125. SAMPLE_VIDEO = f"{self.SAMPLE_DIR}/sample-manual-audio-blank-video-colours.mp4"
  126. # create mock source with the video
  127. source = mocks.MockSource(path=SAMPLE_VIDEO)
  128. # create the feature extractor
  129. testfe = extractors.LoudAudioFeatureExtractor(input_files=[source])
  130. testfe.setup()
  131. testfe.run()
  132. testfe.teardown()
  133. # check if the feature was extracted:
  134. self.assertFalse(testfe.features)
  135. if __name__ == "__main__":
  136. unittest.main()