From d96978ac1107f3463b77f69a9c1b1ec5d45291a0 Mon Sep 17 00:00:00 2001 From: Blanca Macazaga Date: Tue, 14 Jan 2025 19:48:36 +0100 Subject: [PATCH] Update main (#7) Update --- .github/workflows/c-cpp.yml | 16 +- CMakeLists.txt | 16 +- README.md | 2 - config/appsettings.json | 272 +----- example/CMakeLists.txt | 2 +- example/appsettings.json | 577 ------------- example/main.cpp | 6 - include/iris/Configuration.h | 21 +- include/iris/FrameData.h | 4 +- include/iris/Log.h | 3 +- include/iris/Result.h | 2 +- include/iris/VideoAnalyser.h | 15 +- src/CDLuminance.cpp | 57 -- src/CDLuminance.h | 40 - src/Configuration.cpp | 66 +- src/ConfigurationParams.h | 6 +- src/Flash.cpp | 13 +- src/Flash.h | 7 +- src/FlashDetection.cpp | 76 +- src/FlashDetection.h | 11 +- src/FpsFrameManager.cpp | 40 + src/FpsFrameManager.h | 61 ++ src/FrameData.h | 307 ------- src/IFrameManager.h | 47 + src/IrisFrame.h | 2 +- src/PatternDetection.cpp | 18 +- src/PatternDetection.h | 31 +- src/RedSaturation.cpp | 4 +- src/RedSaturation.h | 3 +- src/RelativeLuminance.cpp | 5 +- src/RelativeLuminance.h | 5 +- src/TimeFrameManager.cpp | 43 + src/TimeFrameManager.h | 134 +++ src/TransitionTracker.cpp | 106 +++ src/TransitionTracker.h | 46 +- src/TransitionTrackerByFPS.cpp | 78 -- src/TransitionTrackerByFPS.h | 27 - src/TransitionTrackerByTime.cpp | 106 --- src/TransitionTrackerByTime.h | 120 --- src/VideoAnalyser.cpp | 106 ++- test/Iris.Tests/CMakeLists.txt | 7 +- test/Iris.Tests/appsettings.json | 811 ++++++------------ test/Iris.Tests/include/IrisLibTest.h | 1 + test/Iris.Tests/src/CDLuminanceTest.cpp | 146 ---- test/Iris.Tests/src/FlashDetectionTests.cpp | 328 +++---- test/Iris.Tests/src/FlashTest.cpp | 17 +- test/Iris.Tests/src/FrameManagerTests.cpp | 154 ++++ test/Iris.Tests/src/PatternDetectionTests.cpp | 142 ++- test/Iris.Tests/src/RedSaturationTests.cpp | 82 +- test/Iris.Tests/src/RelativeLuminanceTest.cpp | 109 +-- .../src/TransitionTrackerByFPSTests.cpp | 247 ------ .../src/TransitionTrackerByTimeTests.cpp | 369 -------- .../Iris.Tests/src/TransitionTrackerTests.cpp | 519 +++++++++++ test/Iris.Tests/src/VideoAnalysisTests.cpp | 182 ++-- utils/include/utils/BaseLog.h | 2 +- 55 files changed, 2170 insertions(+), 3447 deletions(-) delete mode 100644 example/appsettings.json delete mode 100644 src/CDLuminance.cpp delete mode 100644 src/CDLuminance.h create mode 100644 src/FpsFrameManager.cpp create mode 100644 src/FpsFrameManager.h delete mode 100644 src/FrameData.h create mode 100644 src/IFrameManager.h create mode 100644 src/TimeFrameManager.cpp create mode 100644 src/TimeFrameManager.h create mode 100644 src/TransitionTracker.cpp delete mode 100644 src/TransitionTrackerByFPS.cpp delete mode 100644 src/TransitionTrackerByFPS.h delete mode 100644 src/TransitionTrackerByTime.cpp delete mode 100644 src/TransitionTrackerByTime.h delete mode 100644 test/Iris.Tests/src/CDLuminanceTest.cpp create mode 100644 test/Iris.Tests/src/FrameManagerTests.cpp delete mode 100644 test/Iris.Tests/src/TransitionTrackerByFPSTests.cpp delete mode 100644 test/Iris.Tests/src/TransitionTrackerByTimeTests.cpp create mode 100644 test/Iris.Tests/src/TransitionTrackerTests.cpp diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 0ec908f..3f2f449 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -48,6 +48,13 @@ jobs: mkdir -p ${{ github.workspace }}/vcpkg/bincache fi shell: bash + + - name: Install packages + if: runner.os == 'Linux' + run: sudo apt-get install -y libxi-dev libxtst-dev bison gperf libgles2-mesa-dev libxrandr-dev libxcursor-dev libxdamage-dev libxinerama-dev nasm autoconf automake libtool pkg-config + + - if: runner.os == 'macOS' + run: brew install nasm - uses: lukka/get-cmake@latest @@ -55,7 +62,7 @@ jobs: uses: lukka/run-vcpkg@v4 with: setupOnly: true - vcpkgGitCommitId: 0affe8710a4a5b26328e909fe1ad7146df39d108 + vcpkgGitCommitId: d320630b28aeb59b24424eb2a7ef3905314107a1 # Restore vpkg cache - name: Restore vcpkg @@ -73,13 +80,6 @@ jobs: # Ensure that the developer command promt is present on Windows runners - uses: ilammy/msvc-dev-cmd@v1 - - name: Install packages - if: runner.os == 'Linux' - run: sudo apt-get install -y libxi-dev libxtst-dev bison gperf libgles2-mesa-dev libxrandr-dev libxcursor-dev libxdamage-dev libxinerama-dev nasm - - - if: runner.os == 'macOS' - run: brew install nasm - - name: Restore from cache the dependencies and generate project files run: | cmake -DBUILD_EXAMPLE_APP=ON -DBUILD_TESTS=ON --preset ${{ env.CURRENT_OS }}-release diff --git a/CMakeLists.txt b/CMakeLists.txt index 6bac6f8..722b614 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,6 +31,7 @@ set(PUBLIC_HEADERS "include/iris/VideoAnalyser.h" "include/iris/Configuration.h" "include/iris/Log.h" + "include/iris/FrameData.h" "include/iris/Result.h" "include/iris/TotalFlashIncidents.h" "include/iris/ScopeProfiler.h" @@ -45,14 +46,11 @@ set(SOURCE_FILES "src/RelativeLuminance.cpp" "src/RedSaturation.h" "src/RedSaturation.cpp" - "src/CDLuminance.cpp" "src/Configuration.cpp" "src/ConfigurationParams.h" "src/Flash.h" "src/RelativeLuminance.h" - "src/CDLuminance.h" - "src/FrameRgbConverter.h" - "src/FrameData.h" + "src/FrameRgbConverter.h" "src/FlashDetection.h" "src/FlashDetection.cpp" "src/IrisFrame.h" @@ -61,11 +59,13 @@ set(SOURCE_FILES "src/PatternDetection.cpp" "src/PhotosensitivityDetector.h" "src/TransitionTracker.h" - "src/TransitionTrackerByFPS.h" - "src/TransitionTrackerByTime.h" - "src/TransitionTrackerByFPS.cpp" - "src/TransitionTrackerByTime.cpp" + "src/TransitionTracker.cpp" "src/ScopeProfiler.cpp" + "src/IFrameManager.h" + "src/FpsFrameManager.h" + "src/FpsFrameManager.cpp" + "src/TimeFrameManager.h" + "src/TimeFrameManager.cpp" ) source_group("Source files" FILES ${SOURCE_FILES}) diff --git a/README.md b/README.md index 7e4fab3..fa24a5f 100644 --- a/README.md +++ b/README.md @@ -50,8 +50,6 @@ When running IRIS in the example app, the following command line arguments can b - `-j`: when passing true/1 generates the results in a json file. - `-v`: the path to a video can be specified as to. - `-p`: enabled/disable the pattern detection (true/1 or false/0). -- `-l`: specify the luminance type for the luminance calculations (CD || RELATIVE), relative luminance is the default and standard. - ## Configuration The [appsettings.json](config/appsettings.json) is a file where values used by IRIS are defined and can be modified to alter the execution of the analysis. These default values are configured to detect photosensitive content based on publicly available guidelines. IRIS is not intended to guarantee, certify or otherwise validate video content’s photosensitivity compliance. Modifying IRIS’s default values should be done at your own risk, understanding that doing so may impact IRIS’s results and its ability to detect photosensitivity issues. diff --git a/config/appsettings.json b/config/appsettings.json index af3ccac..ce49499 100644 --- a/config/appsettings.json +++ b/config/appsettings.json @@ -1,272 +1,7 @@ { "Luminance": { - "FormulaYval1": 413.435, //CD luminance formula values - "FormulaYval2": 0.002745, - "FormulaYval3": 0.0189623, - "FormulaYvalpow": 2.2, "RelativeLuminanceFlashThreshold": 0.1, //flash transition - "RelativeDarkLuminanceThreshold": 0.8, - "CdLuminanceFlashThreshold": 20, //flash transition - "CdDarkLuminanceThreshold": 160, - //possible CD luminanve values for look up table - "CdLuminanceValues": [ - 0.07, - 0.09, - 0.12, - 0.15, - 0.18, - 0.22, - 0.27, - 0.31, - 0.37, - 0.42, - 0.48, - 0.55, - 0.62, - 0.69, - 0.77, - 0.85, - 0.94, - 1.03, - 1.13, - 1.23, - 1.34, - 1.45, - 1.57, - 1.69, - 1.82, - 1.95, - 2.09, - 2.23, - 2.37, - 2.53, - 2.68, - 2.85, - 3.01, - 3.19, - 3.37, - 3.55, - 3.74, - 3.93, - 4.13, - 4.34, - 4.55, - 4.77, - 4.99, - 5.21, - 5.45, - 5.68, - 5.93, - 6.18, - 6.43, - 6.69, - 6.96, - 7.23, - 7.51, - 7.79, - 8.08, - 8.38, - 8.68, - 8.98, - 9.3, - 9.61, - 9.94, - 10.27, - 10.6, - 10.94, - 11.29, - 11.64, - 12, - 12.37, - 12.74, - 13.12, - 13.5, - 13.89, - 14.28, - 14.69, - 15.09, - 15.51, - 15.93, - 16.35, - 16.78, - 17.22, - 17.67, - 18.12, - 18.57, - 19.04, - 19.5, - 19.98, - 20.46, - 20.95, - 21.44, - 21.94, - 22.45, - 22.96, - 23.48, - 24.01, - 24.54, - 25.08, - 25.62, - 26.17, - 26.73, - 27.29, - 27.86, - 28.44, - 29.02, - 29.61, - 30.21, - 30.81, - 31.42, - 32.03, - 32.66, - 33.29, - 33.92, - 34.56, - 35.21, - 35.86, - 36.53, - 37.19, - 37.87, - 38.55, - 39.24, - 39.93, - 40.63, - 41.34, - 42.05, - 42.78, - 43.5, - 44.24, - 44.98, - 45.73, - 46.48, - 47.24, - 48.01, - 48.79, - 49.57, - 50.36, - 51.15, - 51.95, - 52.76, - 53.58, - 54.4, - 55.23, - 56.07, - 56.91, - 57.76, - 58.62, - 59.48, - 60.35, - 61.23, - 62.11, - 63, - 63.9, - 64.81, - 65.72, - 66.64, - 67.56, - 68.5, - 69.44, - 70.38, - 71.34, - 72.3, - 73.27, - 74.24, - 75.22, - 76.21, - 77.21, - 78.21, - 79.22, - 80.24, - 81.26, - 82.3, - 83.34, - 84.38, - 85.43, - 86.49, - 87.56, - 88.64, - 89.72, - 90.81, - 91.9, - 93, - 94.11, - 95.23, - 96.36, - 97.49, - 98.63, - 99.77, - 100.93, - 102.09, - 103.25, - 104.43, - 105.61, - 106.8, - 108, - 109.2, - 110.41, - 111.63, - 112.86, - 114.09, - 115.33, - 116.58, - 117.84, - 119.1, - 120.37, - 121.65, - 122.93, - 124.22, - 125.52, - 126.83, - 128.14, - 129.47, - 130.8, - 132.13, - 133.48, - 134.83, - 136.19, - 137.55, - 138.93, - 140.31, - 141.69, - 143.09, - 144.49, - 145.9, - 147.32, - 148.75, - 150.18, - 151.62, - 153.07, - 154.53, - 155.99, - 157.46, - 158.94, - 160.43, - 161.92, - 163.42, - 164.93, - 166.45, - 167.97, - 169.5, - 171.04, - 172.59, - 174.14, - 175.7, - 177.27, - 178.85, - 180.43, - 182.03, - 183.63, - 185.23, - 186.85, - 188.47, - 190.1, - 191.74, - 193.38, - 195.04, - 196.7, - 198.37, - 200 - ] + "RelativeDarkLuminanceThreshold": 0.8 }, "RedSaturation": { @@ -277,12 +12,10 @@ "PatternDetection": { "MinStripes": 6, //min stripes for harmful patterns "TimeThreshold": 0.5, //max seconds for harmful patterns until failure - "CDDarkLuminanceThreshold": 160, "RelativeDarkLuminanceThreshold": 0.8, "AreaProportion": 0.25 }, - "FilePersistence": { "MaxDataStored": 10 //max stored frame data in memory until persistence }, @@ -292,7 +25,7 @@ "MinTransitions": 4, //amount of min transitions to add to extended fail count "ExtendedFailSeconds": 4, //max seconds until the start of extended failure "ExtendedFailWindow": 5, //seconds in extended fail count window - "AnalyseByTime": false + "WarningTransitions": 4 }, "FlashDetection": { @@ -559,7 +292,6 @@ }, "VideoAnalyser": { - "LuminanceType": "RELATIVE", //CD || RELATIVE "PatternDetectionEnabled": false, "FrameResizeEnabled": false, "ResizeFrameProportion": 0.2 diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 2caf50f..40c9b7a 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -6,7 +6,7 @@ project(IrisApp) # Add source to this project's executable. add_executable (${PROJECT_NAME} "main.cpp") -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/appsettings.json ${CMAKE_CURRENT_BINARY_DIR}/appsettings.json COPYONLY) +configure_file(${CMAKE_SOURCE_DIR}/config/appsettings.json ${CMAKE_CURRENT_BINARY_DIR}/appsettings.json COPYONLY) # Included libraries target_link_libraries(${PROJECT_NAME} iris) diff --git a/example/appsettings.json b/example/appsettings.json deleted file mode 100644 index 2e3c3ef..0000000 --- a/example/appsettings.json +++ /dev/null @@ -1,577 +0,0 @@ -{ - "Luminance": { - "FormulaYval1": 413.435, //CD luminance formula values - "FormulaYval2": 0.002745, - "FormulaYval3": 0.0189623, - "FormulaYvalpow": 2.2, - "RelativeLuminanceFlashThreshold": 0.1, //flash transition - "RelativeDarkLuminanceThreshold": 0.8, - "CdLuminanceFlashThreshold": 20, //flash transition - "CdDarkLuminanceThreshold": 160, - //possible CD luminanve values for look up table - "CdLuminanceValues": [ - 0.07, - 0.09, - 0.12, - 0.15, - 0.18, - 0.22, - 0.27, - 0.31, - 0.37, - 0.42, - 0.48, - 0.55, - 0.62, - 0.69, - 0.77, - 0.85, - 0.94, - 1.03, - 1.13, - 1.23, - 1.34, - 1.45, - 1.57, - 1.69, - 1.82, - 1.95, - 2.09, - 2.23, - 2.37, - 2.53, - 2.68, - 2.85, - 3.01, - 3.19, - 3.37, - 3.55, - 3.74, - 3.93, - 4.13, - 4.34, - 4.55, - 4.77, - 4.99, - 5.21, - 5.45, - 5.68, - 5.93, - 6.18, - 6.43, - 6.69, - 6.96, - 7.23, - 7.51, - 7.79, - 8.08, - 8.38, - 8.68, - 8.98, - 9.3, - 9.61, - 9.94, - 10.27, - 10.6, - 10.94, - 11.29, - 11.64, - 12, - 12.37, - 12.74, - 13.12, - 13.5, - 13.89, - 14.28, - 14.69, - 15.09, - 15.51, - 15.93, - 16.35, - 16.78, - 17.22, - 17.67, - 18.12, - 18.57, - 19.04, - 19.5, - 19.98, - 20.46, - 20.95, - 21.44, - 21.94, - 22.45, - 22.96, - 23.48, - 24.01, - 24.54, - 25.08, - 25.62, - 26.17, - 26.73, - 27.29, - 27.86, - 28.44, - 29.02, - 29.61, - 30.21, - 30.81, - 31.42, - 32.03, - 32.66, - 33.29, - 33.92, - 34.56, - 35.21, - 35.86, - 36.53, - 37.19, - 37.87, - 38.55, - 39.24, - 39.93, - 40.63, - 41.34, - 42.05, - 42.78, - 43.5, - 44.24, - 44.98, - 45.73, - 46.48, - 47.24, - 48.01, - 48.79, - 49.57, - 50.36, - 51.15, - 51.95, - 52.76, - 53.58, - 54.4, - 55.23, - 56.07, - 56.91, - 57.76, - 58.62, - 59.48, - 60.35, - 61.23, - 62.11, - 63, - 63.9, - 64.81, - 65.72, - 66.64, - 67.56, - 68.5, - 69.44, - 70.38, - 71.34, - 72.3, - 73.27, - 74.24, - 75.22, - 76.21, - 77.21, - 78.21, - 79.22, - 80.24, - 81.26, - 82.3, - 83.34, - 84.38, - 85.43, - 86.49, - 87.56, - 88.64, - 89.72, - 90.81, - 91.9, - 93, - 94.11, - 95.23, - 96.36, - 97.49, - 98.63, - 99.77, - 100.93, - 102.09, - 103.25, - 104.43, - 105.61, - 106.8, - 108, - 109.2, - 110.41, - 111.63, - 112.86, - 114.09, - 115.33, - 116.58, - 117.84, - 119.1, - 120.37, - 121.65, - 122.93, - 124.22, - 125.52, - 126.83, - 128.14, - 129.47, - 130.8, - 132.13, - 133.48, - 134.83, - 136.19, - 137.55, - 138.93, - 140.31, - 141.69, - 143.09, - 144.49, - 145.9, - 147.32, - 148.75, - 150.18, - 151.62, - 153.07, - 154.53, - 155.99, - 157.46, - 158.94, - 160.43, - 161.92, - 163.42, - 164.93, - 166.45, - 167.97, - 169.5, - 171.04, - 172.59, - 174.14, - 175.7, - 177.27, - 178.85, - 180.43, - 182.03, - 183.63, - 185.23, - 186.85, - 188.47, - 190.1, - 191.74, - 193.38, - 195.04, - 196.7, - 198.37, - 200 - ] - }, - - "RedSaturation": { - "FlashThreshold": 20, //threshold for red saturation transitions - "RedDarkThreshold": 321 - }, - - "PatternDetection": { - "MinStripes": 6, //min stripes for harmful patterns - "TimeThreshold": 0.5, //max seconds for harmful patterns until failure - "CDDarkLuminanceThreshold": 160, - "RelativeDarkLuminanceThreshold": 0.8, - "AreaProportion": 0.25 - }, - - "FilePersistence": { - "MaxDataStored": 10 //max stored frame data in memory until persistence - }, - - "TransitionTracker": { - "MaxTransitions": 6, //max allowed transitions and max transitions to count for extended fail - "MinTransitions": 4, //amount of min transitions to add to extended fail count - "ExtendedFailSeconds": 4, //max seconds until the start of extended failure - "ExtendedFailWindow": 5, //seconds in extended fail count window - "AnalyseByTime": false - }, - - "FlashDetection": { - "AreaProportion": 0.25, //screen display flashing area - //sRGB possible values for look up table - "sRGBValues": [ - 0, - 0.0003035269835488375, - 0.000607053967097675, - 0.0009105809506465125, - 0.00121410793419535, - 0.0015176349177441874, - 0.001821161901293025, - 0.0021246888848418626, - 0.0024282158683907, - 0.0027317428519395373, - 0.003035269835488375, - 0.003346535763899161, - 0.003676507324047436, - 0.004024717018496307, - 0.004391442037410293, - 0.004776953480693729, - 0.005181516702338386, - 0.005605391624202723, - 0.006048833022857054, - 0.006512090792594475, - 0.006995410187265387, - 0.007499032043226175, - 0.008023192985384994, - 0.008568125618069307, - 0.009134058702220787, - 0.00972121732023785, - 0.010329823029626936, - 0.010960094006488246, - 0.011612245179743885, - 0.012286488356915872, - 0.012983032342173012, - 0.013702083047289686, - 0.014443843596092545, - 0.01520851442291271, - 0.01599629336550963, - 0.016807375752887384, - 0.017641954488384078, - 0.018500220128379697, - 0.019382360956935723, - 0.0202885630566524, - 0.021219010376003555, - 0.022173884793387385, - 0.02315336617811041, - 0.024157632448504756, - 0.02518685962736163, - 0.026241221894849898, - 0.027320891639074894, - 0.028426039504420793, - 0.0295568344378088, - 0.030713443732993635, - 0.03189603307301153, - 0.033104766570885055, - 0.03433980680868217, - 0.03560131487502034, - 0.03688945040110004, - 0.0382043715953465, - 0.03954623527673284, - 0.04091519690685319, - 0.042311410620809675, - 0.043735029256973465, - 0.04518620438567554, - 0.046665086336880095, - 0.04817182422688942, - 0.04970656598412723, - 0.05126945837404324, - 0.052860647023180246, - 0.05448027644244237, - 0.05612849004960009, - 0.05780543019106723, - 0.0595112381629812, - 0.06124605423161761, - 0.06301001765316767, - 0.06480326669290577, - 0.06662593864377289, - 0.06847816984440017, - 0.07036009569659588, - 0.07227185068231748, - 0.07421356838014963, - 0.07618538148130785, - 0.07818742180518633, - 0.08021982031446832, - 0.0822827071298148, - 0.08437621154414882, - 0.08650046203654976, - 0.08865558628577294, - 0.09084171118340768, - 0.09305896284668745, - 0.0953074666309647, - 0.09758734714186246, - 0.09989872824711389, - 0.10224173308810132, - 0.10461648409110419, - 0.10702310297826761, - 0.10946171077829933, - 0.1119324278369056, - 0.11443537382697373, - 0.11697066775851084, - 0.11953842798834562, - 0.12213877222960187, - 0.12477181756095049, - 0.12743768043564743, - 0.1301364766903643, - 0.13286832155381798, - 0.13563332965520566, - 0.13843161503245183, - 0.14126329114027164, - 0.14412847085805777, - 0.14702726649759498, - 0.14995978981060856, - 0.15292615199615017, - 0.1559264637078274, - 0.1589608350608804, - 0.162029375639111, - 0.1651321945016676, - 0.16826940018969075, - 0.1714411007328226, - 0.17464740365558504, - 0.17788841598362912, - 0.18116424424986022, - 0.184474994500441, - 0.18782077230067787, - 0.19120168274079138, - 0.1946178304415758, - 0.19806931955994886, - 0.20155625379439707, - 0.20507873639031693, - 0.20863687014525575, - 0.21223075741405523, - 0.21586050011389926, - 0.2195261997292692, - 0.2232279573168085, - 0.22696587351009836, - 0.23074004852434915, - 0.23455058216100522, - 0.238397573812271, - 0.24228112246555486, - 0.24620132670783548, - 0.25015828472995344, - 0.25415209433082675, - 0.2581828529215958, - 0.26225065752969623, - 0.26635560480286247, - 0.2704977910130658, - 0.27467731206038465, - 0.2788942634768104, - 0.2831487404299921, - 0.2874408377269175, - 0.29177064981753587, - 0.2961382707983211, - 0.3005437944157765, - 0.3049873140698863, - 0.30946892281750854, - 0.31398871337571754, - 0.31854677812509186, - 0.32314320911295075, - 0.3277780980565422, - 0.33245153634617935, - 0.33716361504833037, - 0.3419144249086609, - 0.3467040563550296, - 0.35153259950043936, - 0.3564001441459435, - 0.3613067797835095, - 0.3662525955988395, - 0.3712376804741491, - 0.3762621229909065, - 0.38132601143253014, - 0.386429433787049, - 0.39157247774972326, - 0.39675523072562685, - 0.4019777798321958, - 0.4072402119017367, - 0.41254261348390375, - 0.4178850708481375, - 0.4232676699860717, - 0.4286904966139066, - 0.43415363617474895, - 0.4396571738409188, - 0.44520119451622786, - 0.45078578283822346, - 0.45641102318040466, - 0.4620769996544071, - 0.467783796112159, - 0.47353149614800955, - 0.4793201831008268, - 0.4851499400560704, - 0.4910208498478356, - 0.4969329950608704, - 0.5028864580325687, - 0.5088813208549338, - 0.5149176653765214, - 0.5209955732043543, - 0.5271151257058131, - 0.5332764040105052, - 0.5394794890121072, - 0.5457244613701866, - 0.5520114015120001, - 0.5583403896342679, - 0.5647115057049292, - 0.5711248294648731, - 0.5775804404296506, - 0.5840784178911641, - 0.5906188409193369, - 0.5972017883637634, - 0.6038273388553378, - 0.6104955708078648, - 0.6172065624196511, - 0.6239603916750761, - 0.6307571363461468, - 0.6375968739940326, - 0.6444796819705821, - 0.6514056374198242, - 0.6583748172794485, - 0.665387298282272, - 0.6724431569576875, - 0.6795424696330938, - 0.6866853124353135, - 0.6938717612919899, - 0.7011018919329731, - 0.7083757798916868, - 0.7156935005064807, - 0.7230551289219693, - 0.7304607400903537, - 0.7379104087727308, - 0.7454042095403874, - 0.7529422167760779, - 0.7605245046752924, - 0.768151147247507, - 0.7758222183174236, - 0.7835377915261935, - 0.7912979403326302, - 0.799102738014409, - 0.8069522576692516, - 0.8148465722161012, - 0.8227857543962835, - 0.8307698767746546, - 0.83879901174074, - 0.846873231509858, - 0.8549926081242338, - 0.8631572134541023, - 0.8713671191987972, - 0.8796223968878317, - 0.8879231178819663, - 0.8962693533742664, - 0.9046611743911496, - 0.9130986517934192, - 0.9215818562772946, - 0.9301108583754237, - 0.938685728457888, - 0.9473065367331999, - 0.9559733532492861, - 0.9646862478944651, - 0.9734452903984125, - 0.9822505503331171, - 0.9911020971138298, - 1 - ] - }, - - "VideoAnalyser": { - "LuminanceType": "RELATIVE", //CD || RELATIVE - "PatternDetectionEnabled": false, - "FrameResizeEnabled": false, - "ResizeFrameProportion": 0.2 - }, - - "Logging": { - "Console": { - "LogLevel": { - "Default": "Debug", - "System": "Information", - "Microsoft": "Information" - }, - "IncludeScopes": true - } - } -} \ No newline at end of file diff --git a/example/main.cpp b/example/main.cpp index 4e14335..b44ef3e 100644 --- a/example/main.cpp +++ b/example/main.cpp @@ -94,12 +94,6 @@ int main(int argc, char* argv[]) sourceVideo = getCmdOption(argv, argv + argc, "-v"); } - if (cmdOptionExists(argv, argv + argc, "-l")) - { - std::string lumType = getCmdOption(argv, argv + argc, "-l"); - configuration.SetLuminanceType(lumType); - } - //load configuration configuration.Init(); diff --git a/include/iris/Configuration.h b/include/iris/Configuration.h index 26c662d..c504424 100644 --- a/include/iris/Configuration.h +++ b/include/iris/Configuration.h @@ -30,30 +30,34 @@ namespace iris /// path to appsettings files void Init(const char* path = ""); - enum class LuminanceType {UN_SET = 0, CD, RELATIVE}; - - inline void SetLuminanceType(LuminanceType luminance) { m_luminanceType = luminance; } - inline void SetLuminanceType(const std::string& luminance) { m_luminanceType = luminance == "CD" ?LuminanceType::CD : LuminanceType::RELATIVE; } - LuminanceType GetLuminanceType() { return m_luminanceType; } - float GetSafeAreaProportion(); inline FlashParams* GetLuminanceFlashParams() { return m_luminanceFlashParams; } inline FlashParams* GetRedSaturationFlashParams() { return m_redSaturationFlashParams; } inline EA::EACC::Utils::FrameConverterParams* GetFrameSrgbConverterParams() { return m_frameSrgbConverterParams; } - inline EA::EACC::Utils::FrameConverterParams* GetFrameCDLuminanceConverterParams() { return m_frameCDLuminanceConverterParams; } inline TransitionTrackerParams* GetTransitionTrackerParams() { return m_transitionTrackerParams; } inline PatternDetectionParams* GetPatternDetectionParams() { return m_patternDetectionParams; } inline bool PatternDetectionEnabled() { return m_patternDetectionEnabled; } inline void SetPatternDetectionStatus(bool status) { m_patternDetectionEnabled = status; } + inline bool AnalyseByTimeEnabled() { return m_analyseByTime; } + inline void SetAnalyseByTimeStatus(bool status) { m_analyseByTime = status; } + inline bool FrameResizeEnabled() { return m_frameResizeEnabled; } inline void SetFrameResizeEnabled(bool status) { m_frameResizeEnabled = status; } inline float GetFrameResizeProportion() { return m_frameResizeProportion; } inline void SetFrameResizeProportion(float proportion) { m_frameResizeProportion = proportion; } + void SetRedSaturationFlashThreshold(float newFlashThreshold); + void SetRedSaturationDarkThreshold(float newDarkThreshold); + + void SetLuminanceFlashThreshold(float newFlashThreshold); + void SetLuminanceDarkThreshold(float newDarkThreshold); + + void SetMinimumTransitionsForWarning(int count); + void SetSafeArea(float areaProportion); inline const std::string& GetResultsPath() { return m_resultsPath; } @@ -63,15 +67,14 @@ namespace iris FlashParams* m_luminanceFlashParams = nullptr; FlashParams* m_redSaturationFlashParams = nullptr; EA::EACC::Utils::FrameConverterParams* m_frameSrgbConverterParams = nullptr; - EA::EACC::Utils::FrameConverterParams* m_frameCDLuminanceConverterParams = nullptr; TransitionTrackerParams* m_transitionTrackerParams = nullptr; PatternDetectionParams* m_patternDetectionParams = nullptr; - LuminanceType m_luminanceType = LuminanceType::UN_SET; bool m_patternDetectionEnabled = true; bool m_frameResizeEnabled = true; float m_frameResizeProportion = 1; + bool m_analyseByTime = false; std::string m_resultsPath; }; diff --git a/include/iris/FrameData.h b/include/iris/FrameData.h index 20ce321..f0d6702 100644 --- a/include/iris/FrameData.h +++ b/include/iris/FrameData.h @@ -3,7 +3,7 @@ #pragma once #include #include /* fmod */ -#include "utils/JsonWrapper" +#include "utils/JsonWrapper.h" #include "iris/TotalFlashIncidents.h" namespace iris @@ -28,6 +28,7 @@ namespace iris FrameData() {}; FrameData(unsigned int frame, unsigned long timeMs) : Frame(frame) { + TimeStampVal = timeMs; TimeStampMs = msToTimeSpan(timeMs); }; @@ -132,6 +133,7 @@ namespace iris std::string patternArea = "0.00%"; int patternDetectedLines = 0; PatternResult patternFrameResult = PatternResult::Pass; + unsigned long TimeStampVal = 0; }; //Serializes FrameData to Json object diff --git a/include/iris/Log.h b/include/iris/Log.h index cf5ff06..11e795f 100644 --- a/include/iris/Log.h +++ b/include/iris/Log.h @@ -44,4 +44,5 @@ namespace iris } //Data Logger macro - only used for data persistence -#define LOG_DATA_INFO(...) iris::Log::GetDataLogger()->info(__VA_ARGS__) \ No newline at end of file +#define LOG_DATA_INFO(...) iris::Log::GetDataLogger()->info(__VA_ARGS__) +#define FLUSH_DATA_LOGGER() iris::Log::GetDataLogger()->flush() \ No newline at end of file diff --git a/include/iris/Result.h b/include/iris/Result.h index 5f064cd..5a605bc 100644 --- a/include/iris/Result.h +++ b/include/iris/Result.h @@ -2,7 +2,7 @@ #pragma once #include -#include "../src/FrameData.h" +#include "iris/FrameData.h" #include "iris/TotalFlashIncidents.h" namespace iris diff --git a/include/iris/VideoAnalyser.h b/include/iris/VideoAnalyser.h index acb069b..2fd56c1 100644 --- a/include/iris/VideoAnalyser.h +++ b/include/iris/VideoAnalyser.h @@ -37,6 +37,7 @@ namespace iris class PatternDetection; class PhotosensitivityDetector; class FrameData; + class IFrameManager; struct FrameDataJson; struct Result; @@ -51,6 +52,11 @@ namespace iris /// void Init(const std::string& videoName, bool flagJson = false); + /// + /// Real time use Only - Initializes FlashDetection and PatternDection + /// + void RealTimeInit(cv::Size& frameSize); + /// /// Release FlashDetection and PatternDection /// @@ -59,7 +65,7 @@ namespace iris /// /// Checks if the video file can be opened and read /// - bool VideoIsOpen(const char* sourceVideo, cv::VideoCapture& video, const char* videoName); + bool VideoIsOpen(const char* sourceVideo, cv::VideoCapture& video); /// /// Anlyses video to check photosensitivity @@ -87,8 +93,11 @@ namespace iris cv::Size frameSize; //video resolution }; - inline VideoInfo GetVideoInfo() { return m_videoInfo; } + [[nodiscard]] inline VideoInfo GetVideoInfo() const { return m_videoInfo; } + [[nodiscard]] inline std::string GetResultJsonPath() const { return m_resultJsonPath; }; + [[nodiscard]] inline std::string GetFrameDataJsonPath() const {return m_frameDataJsonPath;}; + [[nodiscard]] inline std::string GetFrameDataPath() const {return m_frameDataPath;}; private: /// @@ -114,7 +123,9 @@ namespace iris std::string m_resultJsonPath; std::string m_frameDataJsonPath; + std::string m_frameDataPath; + IFrameManager* m_frameManager = nullptr; VideoInfo m_videoInfo; }; } \ No newline at end of file diff --git a/src/CDLuminance.cpp b/src/CDLuminance.cpp deleted file mode 100644 index e03765d..0000000 --- a/src/CDLuminance.cpp +++ /dev/null @@ -1,57 +0,0 @@ -//Copyright (C) 2023 Electronic Arts, Inc. All rights reserved. - -/* -**** RelativeLuminance **** -Abstract class for Flash detection -*/ - -#include "CDLuminance.h" -#include -#include -#include "ConfigurationParams.h" -#include "IrisFrame.h" -#include "utils/FrameConverter.h" - -namespace iris -{ - CDLuminance::CDLuminance(EA::EACC::Utils::FrameConverter *converter, const short& fps,const cv::Size& frameSize, FlashParams* params) - : Flash(fps, frameSize, params) - { - m_converter = converter; - } - - CDLuminance::~CDLuminance() - { - ReleaseLastFrame(); - ReleaseCurrentFrame(); - } - - /// - /// Set the new current frame and move the previous one as the last frame. - /// in RelativeLuminance this method and class are responsible to release memory for the frame created - /// - /// - void CDLuminance::SetCurrentFrame(const IrisFrame& irisFrame) - { - cv::Mat YCrCb; - cv::cvtColor(*irisFrame.originalFrame, YCrCb, cv::COLOR_BGR2YCrCb); //luma-chroma colour space - cv::Mat channelY; - cv::extractChannel(YCrCb, channelY, 0); - cv::Mat *frame = m_converter->Convert(channelY); - - ReleaseLastFrame(); - Flash::SetCurrentFrame(frame); - } - - void CDLuminance::SetCurrentFrame(cv::Mat* bgrFrame) - { - cv::Mat YCrCb; - cv::cvtColor(*bgrFrame, YCrCb, cv::COLOR_BGR2YCrCb); //luma-chroma colour space - cv::Mat channelY; - cv::extractChannel(YCrCb, channelY, 0); - cv::Mat* frame = m_converter->Convert(channelY); - - ReleaseLastFrame(); - Flash::SetCurrentFrame(frame); - } -} diff --git a/src/CDLuminance.h b/src/CDLuminance.h deleted file mode 100644 index 7527a47..0000000 --- a/src/CDLuminance.h +++ /dev/null @@ -1,40 +0,0 @@ -//Copyright (C) 2023 Electronic Arts, Inc. All rights reserved. - -#pragma once -#include "Flash.h" -#include "opencv2/core/types.hpp" - -namespace cv -{ - class Mat; -} - -namespace EA::EACC::Utils -{ - class FrameConverter; -} - - -namespace iris -{ - struct FlashParams; - struct IrisFrame; - - class CDLuminance : public Flash - { - public: - /// - /// - /// - /// - /// - CDLuminance(EA::EACC::Utils::FrameConverter* converter, const short& fps, const cv::Size& frameSize, FlashParams* params); - void SetCurrentFrame(const IrisFrame& irisFrame) override; - void SetCurrentFrame (cv::Mat* bgrFrame) override; - - ~CDLuminance(); - protected: - private: - EA::EACC::Utils::FrameConverter* m_converter; - }; -} \ No newline at end of file diff --git a/src/Configuration.cpp b/src/Configuration.cpp index 8cfc521..214c815 100644 --- a/src/Configuration.cpp +++ b/src/Configuration.cpp @@ -8,7 +8,8 @@ namespace iris { - Configuration::Configuration() + Configuration::Configuration() : m_analyseByTime(false), m_patternDetectionEnabled(false), + m_frameResizeEnabled(false), m_frameResizeProportion(1.0f) { } @@ -29,11 +30,6 @@ namespace iris delete m_frameSrgbConverterParams; m_frameSrgbConverterParams = nullptr; } - if (m_frameCDLuminanceConverterParams != nullptr) - { - delete m_frameCDLuminanceConverterParams; m_frameCDLuminanceConverterParams = nullptr; - } - if (m_transitionTrackerParams != nullptr) { delete m_transitionTrackerParams; m_transitionTrackerParams = nullptr; @@ -53,33 +49,16 @@ namespace iris m_resultsPath = jsonFile.ContainsParam("ResultsPath") ? jsonFile.GetParam("ResultsPath") : "Results/"; - if (m_luminanceType == LuminanceType::UN_SET) - { - std::string lumType = jsonFile.GetParam("VideoAnalyser", "LuminanceType"); - m_luminanceType = lumType == "CD" ? LuminanceType::CD : LuminanceType::RELATIVE; - } - m_patternDetectionEnabled = jsonFile.GetParam("VideoAnalyser", "PatternDetectionEnabled"); m_frameResizeEnabled = jsonFile.GetParam("VideoAnalyser", "FrameResizeEnabled"); m_frameResizeProportion = jsonFile.GetParam("VideoAnalyser", "ResizeFrameProportion"); - - //Luminance - if (m_luminanceType == LuminanceType::CD) - { - m_luminanceFlashParams = new FlashParams( - jsonFile.GetParam("Luminance", "CdLuminanceFlashThreshold"), - jsonFile.GetParam("FlashDetection", "AreaProportion"), - jsonFile.GetParam("Luminance", "CdDarkLuminanceThreshold")); - } - else - { - m_luminanceFlashParams = new FlashParams( - jsonFile.GetParam("Luminance", "RelativeLuminanceFlashThreshold"), - jsonFile.GetParam("FlashDetection", "AreaProportion"), - jsonFile.GetParam("Luminance", "RelativeDarkLuminanceThreshold")); - } - + + m_luminanceFlashParams = new FlashParams( + jsonFile.GetParam("Luminance", "RelativeLuminanceFlashThreshold"), + jsonFile.GetParam("FlashDetection", "AreaProportion"), + jsonFile.GetParam("Luminance", "RelativeDarkLuminanceThreshold")); + //Red Saturation m_redSaturationFlashParams = new FlashParams( jsonFile.GetParam("RedSaturation", "FlashThreshold"), @@ -90,33 +69,20 @@ namespace iris m_frameSrgbConverterParams = new EA::EACC::Utils::FrameConverterParams( jsonFile.GetVector("FlashDetection", "sRGBValues")); - //FrameRgbConverter Params for CD Luminance conversion - if (m_luminanceType == LuminanceType::CD) - { - m_frameCDLuminanceConverterParams = new EA::EACC::Utils::FrameConverterParams( - jsonFile.GetVector("Luminance", "CdLuminanceValues")); - } - //Transition Tracker Params m_transitionTrackerParams = new TransitionTrackerParams( jsonFile.GetParam("TransitionTracker", "MaxTransitions"), jsonFile.GetParam("TransitionTracker", "MinTransitions"), - jsonFile.GetParam("TransitionTracker", "ExtendedFailSeconds"), + jsonFile.GetParam("TransitionTracker", "ExtendedFailSeconds"), jsonFile.GetParam("TransitionTracker", "ExtendedFailWindow"), - jsonFile.GetParam("TransitionTracker", "AnalyseByTime")); + jsonFile.GetParam("TransitionTracker", "WarningTransitions")); + //Pattern Detection int minStripes = jsonFile.GetParam("PatternDetection", "MinStripes"); float darkLumThreshold = 0.0f; - if (m_luminanceType == LuminanceType::CD) - { - darkLumThreshold = jsonFile.GetParam("PatternDetection", "CDDarkLuminanceThreshold"); - } - else - { - darkLumThreshold = jsonFile.GetParam("PatternDetection", "RelativeDarkLuminanceThreshold"); - } + darkLumThreshold = jsonFile.GetParam("PatternDetection", "RelativeDarkLuminanceThreshold"); m_patternDetectionParams = new PatternDetectionParams( minStripes, @@ -135,4 +101,12 @@ namespace iris { return m_luminanceFlashParams->areaProportion; } + + void Configuration::SetRedSaturationFlashThreshold(float newFlashThreshold) { m_redSaturationFlashParams->flashThreshold = newFlashThreshold; }; + void Configuration::SetRedSaturationDarkThreshold(float newDarkThreshold) { m_redSaturationFlashParams->darkThreshold = newDarkThreshold; }; + + void Configuration::SetLuminanceFlashThreshold(float newFlashThreshold) { m_luminanceFlashParams->flashThreshold = newFlashThreshold; }; + void Configuration::SetLuminanceDarkThreshold(float newDarkThreshold) { m_luminanceFlashParams->darkThreshold = newDarkThreshold; }; + + void Configuration::SetMinimumTransitionsForWarning(int count) { m_transitionTrackerParams->warningTransitions = count; } } \ No newline at end of file diff --git a/src/ConfigurationParams.h b/src/ConfigurationParams.h index 9eb11f3..97da94f 100644 --- a/src/ConfigurationParams.h +++ b/src/ConfigurationParams.h @@ -27,14 +27,14 @@ namespace iris struct TransitionTrackerParams { - TransitionTrackerParams(uint maxTransition, uint minTransitions, uint extendedFailSeconds, uint extendedFailWindow, bool analyseByTime) - : maxTransitions(maxTransition), minTransitions(minTransitions), extendedFailSeconds(extendedFailSeconds), extendedFailWindow (extendedFailWindow), analyseByTime(analyseByTime) {}; + TransitionTrackerParams(uint maxTransition, uint minTransitions, uint extendedFailSeconds, uint extendedFailWindow, uint warningTransitions) + : maxTransitions(maxTransition), minTransitions(minTransitions), extendedFailSeconds(extendedFailSeconds), extendedFailWindow (extendedFailWindow), warningTransitions(warningTransitions) {}; uint maxTransitions; //max allowed transitions and max transitions to count for extended fail uint minTransitions; //amount of min transitions to add to extended fail count uint extendedFailSeconds; //if extendedFailFramesIS reach this value, extended failure has occured uint extendedFailWindow; //seconds in extended fail count window - bool analyseByTime; //realise the flash analysis by time instead of FPS + uint warningTransitions = 4;//minimum number of transitions to trigger a warning }; struct PatternDetectionParams diff --git a/src/Flash.cpp b/src/Flash.cpp index 831276f..b0810ad 100644 --- a/src/Flash.cpp +++ b/src/Flash.cpp @@ -12,20 +12,24 @@ Abstract class for Flash detection #include #include #include "iris/Log.h" +#include "IFrameManager.h" namespace iris { short Flash::fps = 0; - Flash::Flash(short fps, const cv::Size& frameSize, FlashParams* flashParams) + Flash::Flash(short fps, const cv::Size& frameSize, FlashParams* flashParams, IFrameManager* frameManager) : m_frameManager(frameManager) { Flash::fps = fps; + m_params = flashParams; m_avgDiffInSecond.reserve(fps); m_avgDiffInSecond.emplace_back(0); //initial frame m_frameSize = frameSize.area(); m_safeArea = frameSize.area() * m_params->areaProportion; + m_managerIndx = m_frameManager->RegisterManager(fps, TIME_WINDOW); + LOG_CORE_INFO("Flash Area in pixels: {0}", m_safeArea); LOG_CORE_INFO("Number of pixels in frame: {0}", frameSize.area()); } @@ -111,10 +115,12 @@ namespace iris if (SameSign(lastAvgDiffAcc, avgDiff)) //accumulate increase/decrease (positive/negative) { - if (m_avgDiffInSecond.size() == m_avgDiffInSecond.capacity()) + int removeExcess = m_frameManager->GetFramesToRemove(m_managerIndx); + while(removeExcess>0) { lastAvgDiffAcc -= m_avgDiffInSecond[0]; m_avgDiffInSecond.erase(m_avgDiffInSecond.begin()); + removeExcess--; } m_avgDiffInSecond.emplace_back(avgDiff); @@ -122,10 +128,11 @@ namespace iris } else { + m_frameManager->ResetManager(m_managerIndx); m_avgDiffInSecond.clear(); m_avgDiffInSecond.emplace_back(avgDiff); } - + result.checkResult = IsFlashTransition(result.lastAvgDiffAcc, avgDiff, m_params->flashThreshold); result.lastAvgDiffAcc = avgDiff; //new start acc value diff --git a/src/Flash.h b/src/Flash.h index 45a77a0..00da1ff 100644 --- a/src/Flash.h +++ b/src/Flash.h @@ -13,6 +13,7 @@ namespace cv namespace iris { + class IFrameManager; struct FlashParams; struct CheckTransitionResult; struct IrisFrame; @@ -24,7 +25,7 @@ namespace iris /// /// struct with config parameters /// method to use to check the flashing area - Flash(short fps, const cv::Size& frameSize, FlashParams* flashParams); + Flash(short fps, const cv::Size& frameSize, FlashParams* flashParams, IFrameManager* frameManager); virtual ~Flash(); @@ -134,6 +135,10 @@ namespace iris float m_avgLastFrame = 0; float m_flashArea = 0; int m_frameSize = 0; //frame width * frame height + + const float TIME_WINDOW = 1.0; //max time to consider for calculating flash frequency + int m_managerIndx; + IFrameManager* m_frameManager; }; } \ No newline at end of file diff --git a/src/FlashDetection.cpp b/src/FlashDetection.cpp index fb49a32..cd50278 100644 --- a/src/FlashDetection.cpp +++ b/src/FlashDetection.cpp @@ -4,42 +4,23 @@ #include "iris/Configuration.h" #include "utils/FrameConverter.h" #include "RelativeLuminance.h" -#include "CDLuminance.h" #include "RedSaturation.h" #include -#include "FrameData.h" +#include "iris/FrameData.h" #include "IrisFrame.h" #include "iris/Log.h" #include "iris/Result.h" -#include "TransitionTrackerByFPS.h" -#include "TransitionTrackerByTime.h" +#include "IFrameManager.h" namespace iris { - FlashDetection::FlashDetection(Configuration* configuration, const short& fps, const cv::Size& frameSize) + FlashDetection::FlashDetection(Configuration* configuration, const short& fps, const cv::Size& frameSize, IFrameManager* frameManager) : m_sRgbConverter(configuration->GetFrameSrgbConverterParams()), m_fps(fps) { - - if (configuration->GetTransitionTrackerParams()->analyseByTime) { - m_transitionTracker = new TransitionTrackerByTime(fps, configuration->GetTransitionTrackerParams()); - } - else { - m_transitionTracker = new TransitionTrackerByFPS(fps, configuration->GetTransitionTrackerParams()); - } - - if (configuration->GetLuminanceType() == Configuration::LuminanceType::RELATIVE) - { - m_luminance = new RelativeLuminance(fps, frameSize, configuration->GetLuminanceFlashParams()); - } - else - { - m_cdLuminanceConverter = new EA::EACC::Utils::FrameConverter(configuration->GetFrameCDLuminanceConverterParams()); - m_luminance = new CDLuminance(m_cdLuminanceConverter, fps, frameSize, configuration->GetLuminanceFlashParams()); - } - - m_redSaturation = new RedSaturation(fps, frameSize, configuration->GetRedSaturationFlashParams()); - //m_luminance->CalculateSrgbValues(); + m_transitionTracker = new TransitionTracker(fps, configuration->GetTransitionTrackerParams(), frameManager); + m_luminance = new RelativeLuminance(fps, frameSize, configuration->GetLuminanceFlashParams(), frameManager); + m_redSaturation = new RedSaturation(fps, frameSize, configuration->GetRedSaturationFlashParams(), frameManager); } FlashDetection::~FlashDetection() @@ -52,10 +33,6 @@ namespace iris { delete m_redSaturation; m_redSaturation = nullptr; } - if (m_cdLuminanceConverter != nullptr) - { - delete m_cdLuminanceConverter; m_cdLuminanceConverter = nullptr; - } if (m_transitionTracker != nullptr) { delete m_transitionTracker; @@ -79,11 +56,7 @@ namespace iris if (framePos != 0) //check difference between frame(n) and frame (n - 1) { frameDifference(framePos, data); - m_transitionTracker->EvaluateFrameMoment(framePos, m_fps, data); - } - else - { - m_transitionTracker->SetFirstFrame(data); + m_transitionTracker->EvaluateFrameMoment(data); } data.AverageLuminanceDiffAcc = m_lastAvgLumDiffAcc; @@ -108,7 +81,7 @@ namespace iris m_lastAvgLumDiffAcc = luminanceTransition.lastAvgDiffAcc; //Evaluate and count new transitions - m_transitionTracker->SetTransitions(luminanceTransition.checkResult, redTranstion.checkResult, data); + m_transitionTracker->SetTransitions(luminanceTransition.checkResult, redTranstion.checkResult, data, framePos); data.LuminanceFlashArea = data.proportionToPercentage(m_luminance->GetFlashArea()); data.RedFlashArea = data.proportionToPercentage(m_redSaturation->GetFlashArea()); @@ -122,19 +95,14 @@ namespace iris bool FlashDetection::isFail() { - if (m_transitionTracker->getFlashFail()) - { - LOG_CORE_INFO("Flash FAIL"); - } - - if (m_transitionTracker->getExtendedFailure()) - { - LOG_CORE_INFO("Extended Failure"); - } - return m_transitionTracker->getFlashFail() || m_transitionTracker->getExtendedFailure(); } + bool FlashDetection::isWarning() + { + return m_transitionTracker->getLumPassWithWarning() || m_transitionTracker->getRedPassWithWarning(); + } + cv::Mat* FlashDetection::getLuminanceFrame() { return m_luminance->getCurrentFrame(); @@ -152,14 +120,14 @@ namespace iris result.OverallResult = AnalysisResult::Fail; result.Results.emplace_back(AnalysisResult::LuminanceFlashFailure); - LOG_CORE_INFO("Luminance Flash FAIL"); + LOG_CORE_CRITICAL("Luminance Flash Failure"); } if (m_transitionTracker->getLumExtendedFailure()) { result.OverallResult = AnalysisResult::Fail; result.Results.emplace_back(AnalysisResult::LuminanceExtendedFlashFailure); - LOG_CORE_INFO("Luminance Extended Failure"); + LOG_CORE_CRITICAL("Luminance Extended Failure"); } if (m_transitionTracker->getRedFlashFail()) @@ -167,20 +135,26 @@ namespace iris result.OverallResult = AnalysisResult::Fail; result.Results.emplace_back(AnalysisResult::RedFlashFailure); - LOG_CORE_INFO("Red Flash FAIL"); + LOG_CORE_CRITICAL("Red Flash Failure"); } if (m_transitionTracker->getRedExtendedFailure()) { result.OverallResult = AnalysisResult::Fail; result.Results.emplace_back(AnalysisResult::RedExtendedFlashFailure); - LOG_CORE_INFO("Red Extended Failure"); + LOG_CORE_CRITICAL("Red Extended Failure"); + } + + if (result.OverallResult != AnalysisResult::Fail && m_transitionTracker->getLumPassWithWarning()) + { + result.OverallResult = AnalysisResult::PassWithWarning; + LOG_CORE_WARNING("Luminance Pass with Warning"); } - if (result.OverallResult != AnalysisResult::Fail && ( m_transitionTracker->getLumPassWithWarning() || m_transitionTracker->getRedPassWithWarning() )) + if (result.OverallResult != AnalysisResult::Fail && m_transitionTracker->getRedPassWithWarning()) { result.OverallResult = AnalysisResult::PassWithWarning; - LOG_CORE_INFO("Pass with Warning"); + LOG_CORE_WARNING("Red Pass with Warning"); } } diff --git a/src/FlashDetection.h b/src/FlashDetection.h index 8c1c8af..3dd07ba 100644 --- a/src/FlashDetection.h +++ b/src/FlashDetection.h @@ -24,13 +24,14 @@ namespace iris { class Flash; class FrameData; + class IFrameManager; struct IrisFrame; struct Result; class FlashDetection : public PhotosensitivityDetector { public: - FlashDetection(Configuration* configuration, const short& fps, const cv::Size& frameSize); + FlashDetection(Configuration* configuration, const short& fps, const cv::Size& frameSize, IFrameManager* frameManager); ~FlashDetection(); /// @@ -48,10 +49,15 @@ namespace iris void checkFrame(const IrisFrame& irisFrame, const int& framePos, FrameData& data) override; /// - /// Returns the flash analysis result + /// Returns true if the flash analysis overall result = Fail /// bool isFail() override; + /// + /// Returns true if the flash analysis overall result = PassWithWarning + /// + bool isWarning(); + /// /// Sets the flash detection results for a chunk result object /// @@ -72,7 +78,6 @@ namespace iris Flash* m_luminance = nullptr; Flash* m_redSaturation = nullptr; EA::EACC::Utils::FrameConverter m_sRgbConverter; - EA::EACC::Utils::FrameConverter* m_cdLuminanceConverter = nullptr; float m_lastAvgLumDiffAcc = 0; //first frame has 0 variation float m_lastAvgRedDiffAcc = 0; //first frame has 0 variation diff --git a/src/FpsFrameManager.cpp b/src/FpsFrameManager.cpp new file mode 100644 index 0000000..9e69094 --- /dev/null +++ b/src/FpsFrameManager.cpp @@ -0,0 +1,40 @@ +//Copyright (C) 2024 Electronic Arts, Inc. All rights reserved. +#include "FpsFrameManager.h" +#include "iris/FrameData.h" + +namespace iris +{ + +int FpsFrameManager::RegisterManager(const int& maxFrames, const float& maxTime) +{ + m_managers.emplace_back(FrameManager{ maxFrames }); + return m_managers.size() - 1; +} + +void FpsFrameManager::AddFrame(const iris::FrameData& data) +{ + for (auto& manager: m_managers) + { + int condition = manager.currentFrames >= manager.maxFrames; + manager.framesToRemove = condition; + manager.currentFrames += 1 - condition; + } +} + +int FpsFrameManager::GetFramesToRemove(const int& index) const +{ + return m_managers[index].framesToRemove; +} + +int FpsFrameManager::GetCurrentFrameNum(const int& index) const +{ + return m_managers[index].maxFrames; //max for fps as it's always set +} + +void FpsFrameManager::ResetManager(const int& index, bool removeLast) +{ + m_managers[index].framesToRemove = 0; + m_managers[index].currentFrames = 1; //assume we are always adding a frame when resetting +} + +} \ No newline at end of file diff --git a/src/FpsFrameManager.h b/src/FpsFrameManager.h new file mode 100644 index 0000000..7473f62 --- /dev/null +++ b/src/FpsFrameManager.h @@ -0,0 +1,61 @@ +//Copyright (C) 2024 Electronic Arts, Inc. All rights reserved. +#pragma once +#include "IFrameManager.h" +#include + +namespace iris +{ +class FrameData; + +class FpsFrameManager : public IFrameManager +{ +public: + + FpsFrameManager() = default; + virtual ~FpsFrameManager() {}; + + /// + /// Adds a new manager, then returns the index to access the new elements. + /// + /// max capacity of frames in window + /// max time capacity in window (seconds) not used for FPS + virtual int RegisterManager(const int& maxFrames, const float& maxTime) override; + + /// + /// Adds a new frame to the manager. If using real-time, the timeStampValue from data is used. + /// Updates tracking time/fps and framesToRemove. + /// + virtual void AddFrame(const iris::FrameData& data) override; + + /// + /// Returns the number of frames that need to be removed from the counter vectors. + /// + /// Integer to access the desired element in the vectors. + virtual int GetFramesToRemove(const int& index) const override; + + /// + /// Returns the number of frames in the window. + /// + /// Integer to access the desired element in the vectors. + virtual int GetCurrentFrameNum(const int& index) const override; + + /// + /// Reset the manager. + /// + /// Integer to access the desired element in the vectors. + virtual void ResetManager(const int& index, bool removeLast = false) override; + +private: + + struct FrameManager + { + int maxFrames; //max capacity + int currentFrames; + int framesToRemove; + }; + + std::vector m_managers; + +}; + +} \ No newline at end of file diff --git a/src/FrameData.h b/src/FrameData.h deleted file mode 100644 index f0d6702..0000000 --- a/src/FrameData.h +++ /dev/null @@ -1,307 +0,0 @@ -//Copyright (C) 2023 Electronic Arts, Inc. All rights reserved. - -#pragma once -#include -#include /* fmod */ -#include "utils/JsonWrapper.h" -#include "iris/TotalFlashIncidents.h" - -namespace iris -{ - static std::string msToTimeSpan(int ms) - { - float seconds = fmodf((ms / 1000.0), 60); - int minutes = floor((ms / (1000 * 60)) % 60); - int hours = floor((ms / (1000 * 60 * 60)) % 24); - - std::string h = (hours < 10) ? "0" + std::to_string(hours) : std::to_string(hours); - std::string m = (minutes < 10) ? "0" + std::to_string(minutes) : std::to_string(minutes); - std::string s = (seconds < 10) ? "0" + std::to_string(seconds) : std::to_string(seconds); - - return h + ":" + m + ":" + s; - } - - class FrameData - { - public: - - FrameData() {}; - FrameData(unsigned int frame, unsigned long timeMs) : Frame(frame) - { - TimeStampVal = timeMs; - TimeStampMs = msToTimeSpan(timeMs); - }; - - //To convert the area proportion into a percentage - std::string proportionToPercentage(float proportion) - { - std::string str = std::to_string(proportion * 100); - return str.substr(0, str.find('.') + 3) + '%'; //truncate to two decimal points - } - - std::string ToCSV() - { - std::string csvOutput = std::to_string(Frame) - + ',' + TimeStampMs - + ',' + std::to_string(LuminanceAverage) - + ',' + LuminanceFlashArea - + ',' + std::to_string(AverageLuminanceDiff) - + ',' + std::to_string(AverageLuminanceDiffAcc) - + ',' + std::to_string(RedAverage) - + ',' + RedFlashArea - + ',' + std::to_string(AverageRedDiff) - + ',' + std::to_string(AverageRedDiffAcc) - + ',' + std::to_string(LuminanceTransitions) - + ',' + std::to_string(RedTransitions) - + ',' + std::to_string(LuminanceExtendedFailCount) - + ',' + std::to_string(RedExtendedFailCount) - + ',' + std::to_string((int)luminanceFrameResult) - + ',' + std::to_string((int)redFrameResult) - + ',' + patternArea - + ',' + std::to_string(patternDetectedLines) - + ',' + std::to_string((int)patternFrameResult) + '\0'; - return csvOutput; - } - - std::string CsvColumns() - { - std::string propertyNames [] = { - "Frame", - "TimeStamp", - "AverageLuminance", - "FlashAreaLuminance", - "AverageLuminanceDiff", - "AverageLuminanceDiffAcc", - "AverageRed", - "FlashAreaRed", - "AverageRedDiff", - "AverageRedDiffAcc", - "LuminanceTransitions", - "RedTransitions", - "LuminanceExtendedFailCount", - "RedExtendedFailCount", - "LuminanceFrameResult", - "RedFrameResult", - "PatternArea", - "PatternDetectedLines", - "PatternFrameResult" - }; - - std::string columns; - - bool first = true; - for (auto property : propertyNames) - { - if (!first) - { - columns += ',' + property; - } - else - { - columns += property; - first = false; - } - } - - return columns; - } - - /// - /// Frame index - /// - unsigned int Frame = 0; - - /// - /// frame timestamp in milliseconds - /// - std::string TimeStampMs = "00:00"; - std::string LuminanceFlashArea = "0.00%"; - float LuminanceAverage = 0; - float AverageLuminanceDiff = 0; - float AverageLuminanceDiffAcc = 0; - std::string RedFlashArea = "0.00%"; - float RedAverage = 0; - float AverageRedDiff = 0; - float AverageRedDiffAcc = 0; - float PatternRisk = 0; - unsigned int LuminanceTransitions = 0; - unsigned int RedTransitions = 0; - unsigned int LuminanceExtendedFailCount = 0; - unsigned int RedExtendedFailCount = 0; - FlashResult luminanceFrameResult = FlashResult::Pass; - FlashResult redFrameResult = FlashResult::Pass; - std::string patternArea = "0.00%"; - int patternDetectedLines = 0; - PatternResult patternFrameResult = PatternResult::Pass; - unsigned long TimeStampVal = 0; - }; - - //Serializes FrameData to Json object - static void to_json(json& j, const FrameData& data) - { - j = json - { {"Frame", data.Frame}, - {"TimeStampString", data.TimeStampMs}, - {"AverageLuminance", data.LuminanceAverage}, - {"FlashAreaLuminance", data.LuminanceFlashArea}, - {"AverageLuminanceDiff", data.AverageLuminanceDiff}, - {"AverageLuminanceDiffAcc", data.AverageLuminanceDiffAcc}, - {"AverageRed", data.RedAverage}, - {"FlashAreaRed", data.RedFlashArea}, - {"AverageRedDiff", data.AverageRedDiff}, - {"AverageRedDiffAcc", data.AverageRedDiffAcc}, - {"LuminanceTransitions", data.LuminanceTransitions}, - {"RedTransitions", data.RedTransitions}, - {"LuminanceExtendedFailCount", data.LuminanceExtendedFailCount}, - {"RedExtendedFailCount", data.RedExtendedFailCount}, - {"LuminanceFrameResult", data.luminanceFrameResult}, - {"RedFrameResult", data.redFrameResult}, - {"PatternArea", data.patternArea}, - {"PatternDetectedLines", data.patternDetectedLines}, - {"PatternFrameResult", data.patternFrameResult} }; - }; - - struct FrameDataJson - { - void reserve(const unsigned int& size) - { - frame.reserve(size); - timeStampMs.reserve(size); - - luminanceFlashArea.reserve(size); - luminanceAverage.reserve(size); - averageLuminanceDiff.reserve(size); - averageLuminanceDiffAcc.reserve(size); - - redFlashArea.reserve(size); - redAverage.reserve(size); - averageRedDiff.reserve(size); - averageRedDiffAcc.reserve(size); - - luminanceTransitions.reserve(size); - redTransitions.reserve(size); - - luminanceExtendedFailCount.reserve(size); - redExtendedFailCount.reserve(size); - luminanceFrameResult.reserve(size); - redFrameResult.reserve(size); - - patternArea.reserve(size); - patternDetectedLines.reserve(size); - patternFrameResult.reserve(size); - - } - - void reserveLineGraphData(const unsigned int& size) - { - timeStampMs.reserve(size); - luminanceTransitions.reserve(size); - redTransitions.reserve(size); - luminanceFrameResult.reserve(size); - redFrameResult.reserve(size); - patternFrameResult.reserve(size); - } - - void push_back(const FrameData& data) - { - frame.push_back(data.Frame); - timeStampMs.push_back(data.TimeStampMs); - - luminanceFlashArea.push_back(data.LuminanceFlashArea); - luminanceAverage.push_back(data.LuminanceAverage); - averageLuminanceDiff.push_back(data.AverageLuminanceDiff); - averageLuminanceDiffAcc.push_back(data.AverageLuminanceDiffAcc); - - redFlashArea.push_back(data.RedFlashArea); - redAverage.push_back(data.RedAverage); - averageRedDiff.push_back(data.AverageRedDiff); - averageRedDiffAcc.push_back(data.AverageRedDiffAcc); - - luminanceTransitions.push_back(data.LuminanceTransitions); - redTransitions.push_back(data.RedTransitions); - - luminanceExtendedFailCount.push_back(data.LuminanceExtendedFailCount); - redExtendedFailCount.push_back(data.RedExtendedFailCount); - luminanceFrameResult.push_back((int)data.luminanceFrameResult); - redFrameResult.push_back((int)data.redFrameResult); - - patternArea.push_back(data.patternArea); - patternDetectedLines.push_back(data.patternDetectedLines); - patternFrameResult.push_back((int)data.patternFrameResult); - } - - void push_back_lineGraphData(const FrameData& data) - { - timeStampMs.push_back(data.TimeStampMs); - luminanceTransitions.push_back(data.LuminanceTransitions); - redTransitions.push_back(data.RedTransitions); - luminanceFrameResult.push_back((int)data.luminanceFrameResult); - redFrameResult.push_back((int)data.redFrameResult); - patternFrameResult.push_back((int)data.patternFrameResult); - } - - std::vector frame; - std::vector timeStampMs; - std::vector luminanceFlashArea; - std::vector luminanceAverage; - std::vector averageLuminanceDiff; - std::vector averageLuminanceDiffAcc; - std::vector < std::string> redFlashArea; - std::vector redAverage; - std::vector averageRedDiff; - std::vector averageRedDiffAcc; - std::vector luminanceTransitions; - std::vector redTransitions; - std::vector luminanceExtendedFailCount; - std::vector redExtendedFailCount; - std::vector luminanceFrameResult; - std::vector redFrameResult; - std::vector patternArea; - std::vector patternDetectedLines; - std::vector patternFrameResult; - }; - - //Serializes FrameData to Json object - static void to_json(json& j, const FrameDataJson& data) - { - if (data.frame.capacity() == 0) //if frame vector is empty, line graph data serialization - { - j = json - { - {"TimeStampString", data.timeStampMs}, - {"LuminanceTransitions", data.luminanceTransitions}, - {"RedTransitions", data.redTransitions}, - {"LuminanceFrameResult", data.luminanceFrameResult}, - {"RedFrameResult", data.redFrameResult}, - {"PatternFrameResult", data.patternFrameResult} - }; - } - else - { - j = json - { {"Frame", data.frame}, - {"TimeStampString", data.timeStampMs}, - {"AverageLuminance", data.luminanceAverage}, - {"FlashAreaLuminance", data.luminanceFlashArea}, - {"AverageLuminanceDiff", data.averageLuminanceDiff}, - {"AverageLuminanceDiffAcc", data.averageLuminanceDiffAcc}, - {"AverageRed", data.redAverage}, - {"FlashAreaRed", data.redFlashArea}, - {"AverageRedDiff", data.averageRedDiff}, - {"AverageRedDiffAcc", data.averageRedDiffAcc}, - {"LuminanceTransitions", data.luminanceTransitions}, - {"RedTransitions", data.redTransitions}, - {"LuminanceExtendedFailCount", data.luminanceExtendedFailCount}, - {"RedExtendedFailCount", data.redExtendedFailCount}, - {"LuminanceFrameResult", data.luminanceFrameResult}, - {"RedFrameResult", data.redFrameResult}, - {"PatternArea", data.patternArea}, - {"PatternDetectedLines", data.patternDetectedLines}, - {"PatternFrameResult", data.patternFrameResult} }; - } - }; - -} - - - diff --git a/src/IFrameManager.h b/src/IFrameManager.h new file mode 100644 index 0000000..1f1f89a --- /dev/null +++ b/src/IFrameManager.h @@ -0,0 +1,47 @@ +//Copyright (C) 2024 Electronic Arts, Inc. All rights reserved. +#pragma once + + +namespace iris +{ +class FrameData; + +class IFrameManager +{ +public: + virtual ~IFrameManager() {}; + + /// + /// Adds a new manager, then returns the index to access the new elements. + /// + /// max capacity of frames in window + /// max time capacity in window (seconds) + virtual int RegisterManager(const int& maxFrames, const float& maxTime = 0) = 0; + + /// + /// Adds a new frame to the manager. If using real-time, the timeStampValue from data is used. + /// Updates tracking time/fps and framesToRemove. + /// + virtual void AddFrame(const iris::FrameData& data) = 0; + + /// + /// Returns the number of frames that need to be removed from the counter vectors. + /// + /// Integer to access the desired element in the vectors. + virtual int GetFramesToRemove(const int& index) const = 0; + + /// + /// Returns the current number of frames. + /// + /// Integer to access the desired element in the vectors. + virtual int GetCurrentFrameNum(const int& index) const = 0; + + /// + /// Reset the manager. + /// + /// Integer to access the desired element in the vectors. + virtual void ResetManager(const int& index, bool removeLast = false) = 0; + +}; + +} \ No newline at end of file diff --git a/src/IrisFrame.h b/src/IrisFrame.h index 6294ce9..2140d0a 100644 --- a/src/IrisFrame.h +++ b/src/IrisFrame.h @@ -2,7 +2,7 @@ #pragma once #include -#include "FrameData.h" +#include "iris/FrameData.h" namespace iris { diff --git a/src/PatternDetection.cpp b/src/PatternDetection.cpp index 92cefc2..41d2596 100644 --- a/src/PatternDetection.cpp +++ b/src/PatternDetection.cpp @@ -1,13 +1,14 @@ //Copyright (C) 2023 Electronic Arts, Inc. All rights reserved. #include "PatternDetection.h" -#include "FrameData.h" +#include "iris/FrameData.h" #include "IrisFrame.h" #include "iris/Result.h" #include "iris/Log.h" #include "iris/Configuration.h" #include "ConfigurationParams.h" #include "iris/TotalFlashIncidents.h" +#include "IFrameManager.h" #include @@ -23,8 +24,8 @@ namespace iris { -PatternDetection::PatternDetection(Configuration* configuration, const short& fps, const cv::Size& frameSize) - : m_params(configuration->GetPatternDetectionParams()), m_fps(fps), m_isFail(false), m_patternFailFrames(0) +PatternDetection::PatternDetection(Configuration* configuration, const short& fps, const cv::Size& frameSize, IFrameManager* frameManager) + : m_params(configuration->GetPatternDetectionParams()), m_fps(fps), m_isFail(false), m_patternFailFrames(0), m_frameManager(frameManager) { if (frameSize.width > 480) @@ -51,6 +52,8 @@ PatternDetection::PatternDetection(Configuration* configuration, const short& fp m_patternFrameCount.count.reserve(m_frameTimeThresh); m_patternFrameCount.count.push_back(0); + m_managerIndx = m_frameManager->RegisterManager(m_frameTimeThresh, m_params->timeThreshold); + //TODO:: CACULATE CROPPED IMAGE centerPoint = cv::Point(scaleSize.width / 2, scaleSize.height / 2); @@ -115,7 +118,8 @@ PatternDetection::Pattern PatternDetection::detectPattern(const IrisFrame& irisF void PatternDetection::checkFrameCount(FrameData& data) { - if (m_patternFrameCount.current >= m_frameTimeThresh) + int framesInHalfSecond = m_frameManager->GetCurrentFrameNum(m_managerIndx); + if(m_patternFrameCount.current >= framesInHalfSecond) { data.patternFrameResult = PatternResult::Fail; m_isFail = true; @@ -126,7 +130,8 @@ void PatternDetection::checkFrameCount(FrameData& data) data.patternFrameResult = PatternResult::Pass; } - if (m_patternFrameCount.count.size() == m_frameTimeThresh) + int frameExcess = m_frameManager->GetFramesToRemove(m_managerIndx); + for (frameExcess; frameExcess > 0; frameExcess--) { m_patternFrameCount.updatePassed(); } @@ -389,7 +394,6 @@ std::tuple, int> PatternDetection::getSimilarContours(con bool PatternDetection::isFail() { - LOG_CORE_INFO("Pattern FAIL: {}", (m_isFail ? "true" : "false")); return m_isFail; } @@ -397,11 +401,11 @@ void PatternDetection::setResult(Result& result) { if (isFail()) { + LOG_CORE_CRITICAL("Pattern Failure"); result.OverallResult = AnalysisResult::Fail; result.Results.push_back(AnalysisResult::PatternFailure); result.patternFailFrames = m_patternFailFrames; } - } diff --git a/src/PatternDetection.h b/src/PatternDetection.h index 11c5397..fbf0946 100644 --- a/src/PatternDetection.h +++ b/src/PatternDetection.h @@ -7,6 +7,7 @@ namespace iris { class FrameData; + class IFrameManager; class Configuration; struct IrisFrame; struct Result; @@ -33,7 +34,7 @@ namespace iris class PatternDetection : public PhotosensitivityDetector { public: - PatternDetection(Configuration* configuration, const short& fps, const cv::Size& frameSize); + PatternDetection(Configuration* configuration, const short& fps, const cv::Size& frameSize, IFrameManager* frameManager); //Checks a video frame for harmful patterns void checkFrame(const IrisFrame& irisFrame, const int& framePos, FrameData& data) override; @@ -94,12 +95,18 @@ class PatternDetection : public PhotosensitivityDetector const cv::Mat& contourMat); #endif // DEBUG_PATTERN_REGION true - - struct Counter { void updateCurrent(bool add) { + //Real-time only. If a big frame drop occurs + if (count.empty()) + { + count.emplace_back(add); + current = add; + return; + } + if (add) { count.emplace_back(count.back() + 1); @@ -109,23 +116,28 @@ class PatternDetection : public PhotosensitivityDetector count.emplace_back(count.back()); } - current = count.back() - passed; + current = count.back() - passed; } void updatePassed() { passed = count.front(); count.erase(count.begin()); - } + //Real-time only. If a big frame drop occurs + if (count.empty()) + { + passed = 0; + current = 0; + } + } std::vector count; - int passed; - int current; + int passed = 0; + int current = 0; }; PatternDetectionParams* m_params; - - + IFrameManager* m_frameManager; Counter m_patternFrameCount; int m_frameTimeThresh; @@ -138,6 +150,7 @@ class PatternDetection : public PhotosensitivityDetector int m_diffThreshold; //number of pixels that must have changed to continue the pattern detection flow bool m_isFail; int m_contourThreshArea; + int m_managerIndx; //FrameManager vectors index cv::Mat m_dilationElement; cv::Mat m_erosionElement; diff --git a/src/RedSaturation.cpp b/src/RedSaturation.cpp index 2f6a476..52fb4a9 100644 --- a/src/RedSaturation.cpp +++ b/src/RedSaturation.cpp @@ -7,8 +7,8 @@ namespace iris { - RedSaturation::RedSaturation(short fps, const cv::Size& frameSize, FlashParams* params) - : Flash(fps, frameSize, params) + RedSaturation::RedSaturation(short fps, const cv::Size& frameSize, FlashParams* params, IFrameManager* frameManager) + : Flash(fps, frameSize, params, frameManager) { } diff --git a/src/RedSaturation.h b/src/RedSaturation.h index e87086f..566d92a 100644 --- a/src/RedSaturation.h +++ b/src/RedSaturation.h @@ -12,13 +12,14 @@ namespace cv namespace iris { + class IFrameManager; struct FlashParams; class RedSaturation : public Flash { public: - RedSaturation(short fps, const cv::Size& frameSize, FlashParams* params); + RedSaturation(short fps, const cv::Size& frameSize, FlashParams* params, IFrameManager* frameManager); ~RedSaturation(); void SetCurrentFrame(cv::Mat* sRgbFrame) override; diff --git a/src/RelativeLuminance.cpp b/src/RelativeLuminance.cpp index 30257b3..376cb68 100644 --- a/src/RelativeLuminance.cpp +++ b/src/RelativeLuminance.cpp @@ -10,13 +10,14 @@ Abstract class for Flash detection #include #include "ConfigurationParams.h" #include "IrisFrame.h" +#include "IFrameManager.h" namespace iris { cv::Scalar RelativeLuminance::rgbValues(0.0722f, 0.7152f, 0.2126f); - RelativeLuminance::RelativeLuminance(short fps, const cv::Size& frameSize, FlashParams* params) - : Flash(fps, frameSize, params) + RelativeLuminance::RelativeLuminance(short fps, const cv::Size& frameSize, FlashParams* params, IFrameManager* frameManager) + : Flash(fps, frameSize, params, frameManager) { } diff --git a/src/RelativeLuminance.h b/src/RelativeLuminance.h index bb6d435..355921a 100644 --- a/src/RelativeLuminance.h +++ b/src/RelativeLuminance.h @@ -11,6 +11,7 @@ namespace cv namespace iris { + class IFRameManager; struct FlashParams; struct IrisFrame; @@ -22,11 +23,11 @@ namespace iris /// /// /// - RelativeLuminance(short fps, const cv::Size& frameSize, FlashParams* params); + RelativeLuminance(short fps, const cv::Size& frameSize, FlashParams* params, IFrameManager* frameManager); void SetCurrentFrame(const IrisFrame& irisFrame) override; - void SetCurrentFrame(cv::Mat* bgrFrame) override; + void SetCurrentFrame(cv::Mat* bgrFrame); ~RelativeLuminance(); protected: diff --git a/src/TimeFrameManager.cpp b/src/TimeFrameManager.cpp new file mode 100644 index 0000000..77f7853 --- /dev/null +++ b/src/TimeFrameManager.cpp @@ -0,0 +1,43 @@ +//Copyright (C) 2024 Electronic Arts, Inc. All rights reserved. + +#include "TimeFrameManager.h" +#include "iris/FrameData.h" + +namespace iris +{ + +int TimeFrameManager::RegisterManager(const int& maxFrames, const float& maxTime) +{ + m_managers.emplace_back( + TimeStampManager + { + maxFrames, + (int)(maxTime * 1000) //convert seconds to milliseconds + }); + return m_managers.size() - 1; +} + +void TimeFrameManager::AddFrame(const iris::FrameData& data) +{ + for (auto& manager : m_managers) + { + manager.AddFrame(data.TimeStampVal); + } +} + +int TimeFrameManager::GetFramesToRemove(const int& index) const +{ + return m_managers[index].framesToRemove; +} + +int TimeFrameManager::GetCurrentFrameNum(const int& index) const +{ + return m_managers[index].frameTimeStamps.size(); +} + +void TimeFrameManager::ResetManager(const int& index, bool removeLast) +{ + m_managers[index].Reset(removeLast); +} + +} \ No newline at end of file diff --git a/src/TimeFrameManager.h b/src/TimeFrameManager.h new file mode 100644 index 0000000..62c9f4c --- /dev/null +++ b/src/TimeFrameManager.h @@ -0,0 +1,134 @@ +//Copyright (C) 2024 Electronic Arts, Inc. All rights reserved. +#pragma once +#include "IFrameManager.h" +#include + +namespace iris +{ +class FrameData; + +class TimeFrameManager : public IFrameManager +{ +public: + + TimeFrameManager() = default; + virtual ~TimeFrameManager() {}; + + /// + /// Adds a new manager, then returns the index to access the new elements. + /// + /// max capacity of frames in window + /// max time capacity in window (seconds) + virtual int RegisterManager(const int& maxFrames, const float& maxTime) override; + + /// + /// Adds a new frame to the manager. If using real-time, the timeStampValue from data is used. + /// Updates tracking time/fps and framesToRemove. + /// + virtual void AddFrame(const iris::FrameData& data) override; + + /// + /// Returns the number of frames that need to be removed from the counter vectors. + /// + /// Integer to access the desired element in the vectors. + virtual int GetFramesToRemove(const int& index) const override; + + /// + /// Returns the number of frames in the window. + /// + /// Integer to access the desired element in the vectors. + virtual int GetCurrentFrameNum(const int& index) const override; + + /// + /// Reset the manager. + /// + /// Integer to access the desired element in the vectors. + virtual void ResetManager(const int& index, bool removeLast = false) override; + +private: + + /// + /// Struct to manage time stamps and time between frames in a specific time window + /// + struct TimeStampManager + { + + TimeStampManager(const int& maxFrames, const int& maxTime) + : maxFrames(maxFrames), maxTime(maxTime), framesToRemove(0), timeSum(0) + { + frameTimeStamps.reserve(maxFrames); + timesBetweenFrames.reserve(maxFrames + (maxFrames <= 0) -1); + } + + int maxFrames; //max capacity + int maxTime; //max amount of time in seconds that the window can hold + int framesToRemove; //number of frames to that are no longer inside the time window + long long timeSum; //sum of all times between frames in the window + + std::vector frameTimeStamps; //vector of current frame entry times frames in the window + std::vector timesBetweenFrames; //vector of current times between frames in the window + + /// + /// Add frame to frameTimeStamps checking if it fits in the time window + /// + void AddFrame(const long long& timeStamp) + { + if (!frameTimeStamps.empty()) + { + UpdateTime(timeStamp); + } + frameTimeStamps.emplace_back(timeStamp); + } + + /// + /// Updates time keeping related vector and variables + /// + void UpdateTime(const long long& newTimeStamp) + { + long long newTimeBetweenFrames = newTimeStamp - frameTimeStamps.back(); + int framesToRemove = 0; + + if (newTimeBetweenFrames >= maxTime) + { + framesToRemove = frameTimeStamps.size(); + Reset(true); //clear absolutely everything before adding the new frame + } + else + { + //Remove frames until new frame fits inside the time window + while (timeSum + newTimeBetweenFrames >= maxTime) + { + timeSum -= timesBetweenFrames.front(); + frameTimeStamps.erase(frameTimeStamps.begin()); + if (!timesBetweenFrames.empty()) + { + timesBetweenFrames.erase(timesBetweenFrames.begin()); + } + framesToRemove++; + } + + timeSum += newTimeBetweenFrames; + timesBetweenFrames.emplace_back(newTimeBetweenFrames); + } + + this->framesToRemove = framesToRemove; + } + + /// + /// Reset the time in the manager + /// + /// To specify if the last frame should remain or should be removed + void Reset(bool removeLast = false) + { + timeSum = 0; + framesToRemove = 0; + frameTimeStamps.erase(frameTimeStamps.begin(), frameTimeStamps.end() - 1 + removeLast); + timesBetweenFrames.clear(); + } + }; + + std::vector m_managers; + +}; + +} \ No newline at end of file diff --git a/src/TransitionTracker.cpp b/src/TransitionTracker.cpp new file mode 100644 index 0000000..73a9c41 --- /dev/null +++ b/src/TransitionTracker.cpp @@ -0,0 +1,106 @@ +//Copyright (C) 2023 Electronic Arts, Inc. All rights reserved. + +#include "TransitionTracker.h" +#include "IFrameManager.h" +#include "iris/FrameData.h" +#include "ConfigurationParams.h" + +namespace iris +{ + TransitionTracker::TransitionTracker(unsigned int fps, TransitionTrackerParams* params, IFrameManager* frameManager) + : m_params(params), m_frameManager(frameManager) + { + m_luminanceTransitionCount.count.reserve(fps); + m_redTransitionCount.count.reserve(fps); + m_luminanceExtendedCount.count.reserve(EXTENDED_FAIL_WINDOW * fps); + m_redExtendedCount.count.reserve(EXTENDED_FAIL_WINDOW * fps); + + m_redTransitionCount.count.emplace_back(0); + m_luminanceExtendedCount.count.emplace_back(0); + m_luminanceTransitionCount.count.emplace_back(0); + m_redExtendedCount.count.emplace_back(0); + + m_failManagerIndx = m_frameManager->RegisterManager(fps, FAIL_TIME_WINDOW); + m_extendedSecManagerIndx = m_frameManager->RegisterManager(EXTENDED_FAIL_SECONDS * fps, EXTENDED_FAIL_SECONDS); + m_extendedWinManagerIndx = m_frameManager->RegisterManager(EXTENDED_FAIL_WINDOW * fps, EXTENDED_FAIL_WINDOW); + + } + + void TransitionTracker::SetTransitions(bool lumTransition, bool redTransition, FrameData& data, const int& framePos) + { + UpdateCounters(framePos); + + data.LuminanceTransitions = m_luminanceTransitionCount.updateCurrent(lumTransition); + data.RedTransitions = m_redTransitionCount.updateCurrent(redTransition); + + data.LuminanceExtendedFailCount = m_luminanceExtendedCount.updateCurrent( + m_luminanceTransitionCount.current <= m_params->maxTransitions + && m_luminanceTransitionCount.current >= m_params->minTransitions); + + data.RedExtendedFailCount = m_redExtendedCount.updateCurrent( + m_redTransitionCount.current <= m_params->maxTransitions + && m_redTransitionCount.current >= m_params->minTransitions); + } + + void TransitionTracker::EvaluateFrameMoment(FrameData& data) + { + int framesInFourSeconds = m_frameManager->GetCurrentFrameNum(m_extendedSecManagerIndx); + + if (m_luminanceTransitionCount.current > m_params->maxTransitions) //FAIL as max allowed transitions has been surpassed + { + m_luminanceResults.flashFail = true; + data.luminanceFrameResult = FlashResult::FlashFail; + m_luminanceIncidents.flashFailFrames += 1; + } + else if (m_luminanceExtendedCount.current >= framesInFourSeconds && m_luminanceTransitionCount.current >= m_params->minTransitions) //EXTENDED FAILURE + { + m_luminanceResults.extendedFail = true; + data.luminanceFrameResult = FlashResult::ExtendedFail; + m_luminanceIncidents.extendedFailFrames += 1; + } + else if (m_luminanceTransitionCount.current >= m_params->warningTransitions) + { + m_luminanceResults.passWithWarning = true; + data.luminanceFrameResult = FlashResult::PassWithWarning; + m_luminanceIncidents.passWithWarningFrames += 1; + } + + if (m_redTransitionCount.current > m_params->maxTransitions) //FAIL as max allowed transitions has been surpassed + { + m_redResults.flashFail = true; + data.redFrameResult = FlashResult::FlashFail; + m_redIncidents.flashFailFrames += 1; + } + else if (m_redExtendedCount.current >= framesInFourSeconds && m_redTransitionCount.current >= m_params->minTransitions) //EXTENDED FAILURE + { + m_redResults.extendedFail = true; + data.redFrameResult = FlashResult::ExtendedFail; + m_redIncidents.extendedFailFrames += 1; + } + else if (m_redTransitionCount.current >= m_params->warningTransitions) + { + m_redResults.passWithWarning = true; + data.redFrameResult = FlashResult::PassWithWarning; + m_redIncidents.passWithWarningFrames += 1; + } + } + + void TransitionTracker::UpdateCounters(const int& framePos) + { + int oneSecondFramesToRemove = m_frameManager->GetFramesToRemove(m_failManagerIndx); + int fiveSecondFramesToRemove = m_frameManager->GetFramesToRemove(m_extendedWinManagerIndx); + + //update transition counters as 1s has passed + for (oneSecondFramesToRemove; oneSecondFramesToRemove > 0; oneSecondFramesToRemove--) + { + m_luminanceTransitionCount.updatePassed(); + m_redTransitionCount.updatePassed(); + } + //update extended failure counters as 5s have passed + for (fiveSecondFramesToRemove; fiveSecondFramesToRemove > 0; fiveSecondFramesToRemove--) + { + m_luminanceExtendedCount.updatePassed(); + m_redExtendedCount.updatePassed(); + } + } +} \ No newline at end of file diff --git a/src/TransitionTracker.h b/src/TransitionTracker.h index 54881a9..aa64af6 100644 --- a/src/TransitionTracker.h +++ b/src/TransitionTracker.h @@ -9,13 +9,14 @@ namespace iris struct TransitionTrackerParams; class FrameData; + class IFrameManager; class TransitionTracker { public: - - virtual ~TransitionTracker() {}; + + TransitionTracker(unsigned int fps, TransitionTrackerParams* params, IFrameManager* frameManager); inline bool getLumPassWithWarning() { return m_luminanceResults.passWithWarning; }; inline bool getRedPassWithWarning() { return m_redResults.passWithWarning; }; @@ -39,25 +40,22 @@ namespace iris /// true if there is a new luminance transition /// true if there is a new red transition /// data to persist - virtual void SetTransitions(bool lumTransition, bool redTransition, FrameData& data)=0; + /// current frame index + void SetTransitions(bool lumTransition, bool redTransition, FrameData& data, const int& framePos = 0); /// /// Checks if in the current frame (moment of the video) the video has failed the flash criteria /// - /// current frame index - /// video frame rate /// data to persist - virtual void EvaluateFrameMoment(int framePos, int fps,FrameData& data) = 0; + void EvaluateFrameMoment(FrameData& data); /// - /// If AnalysisByTime is enabled, add the first frame to the FrameTimeStamps structs + /// If the new frame exceeds the frame rate, it is necessary to remove 1 or more elements from the counters. /// - /// data to persist - virtual void SetFirstFrame(FrameData& data) {} + /// current frame index + void UpdateCounters(const int& framePos); protected: - TransitionTracker() {}; - struct Counter { std::vector count; //transition count that surpass the luminance/red threshold from the last second @@ -72,8 +70,13 @@ namespace iris // return new current int updateCurrent(const bool& newTransition) { - - + //Real-time only. If a big frame drop occurs + if (count.empty()) + { + count.emplace_back(newTransition); + current = newTransition; + return newTransition; + } //update the new transition count if (newTransition) { @@ -93,6 +96,13 @@ namespace iris { passed = count.front(); count.erase(count.begin()); + + //Real-time only. If a big frame drop occurs + if (count.empty()) + { + passed = 0; + current = 0; + } } }; @@ -117,6 +127,16 @@ namespace iris TransitionTrackerParams* m_params = nullptr; + IFrameManager* m_frameManager = nullptr; + + const int FAIL_TIME_WINDOW = 1; //window to calculate flash frequency (1s) + int m_failManagerIndx; + + const int EXTENDED_FAIL_SECONDS = 4; //time at which extended failure can occur (4s) + int m_extendedSecManagerIndx; + + const int EXTENDED_FAIL_WINDOW = 5; //max time window for extended failure (5s) + int m_extendedWinManagerIndx; }; } \ No newline at end of file diff --git a/src/TransitionTrackerByFPS.cpp b/src/TransitionTrackerByFPS.cpp deleted file mode 100644 index dc00e64..0000000 --- a/src/TransitionTrackerByFPS.cpp +++ /dev/null @@ -1,78 +0,0 @@ -#include "TransitionTrackerByFPS.h" - -namespace iris -{ - TransitionTrackerByFPS::TransitionTrackerByFPS(unsigned int fps, TransitionTrackerParams* params) - : TransitionTracker() - { - m_params = params; - m_luminanceTransitionCount.count.reserve(fps); m_luminanceTransitionCount.count.emplace_back(0); - m_redTransitionCount.count.reserve(fps); m_redTransitionCount.count.emplace_back(0); - m_luminanceExtendedCount.count.reserve(m_params->extendedFailWindow * fps); m_luminanceExtendedCount.count.emplace_back(0); - m_redExtendedCount.count.reserve(m_params->extendedFailWindow * fps); m_redExtendedCount.count.emplace_back(0); - } - - void TransitionTrackerByFPS::SetTransitions(bool lumTransition, bool redTransition, FrameData& data) - { - data.LuminanceTransitions = m_luminanceTransitionCount.updateCurrent(lumTransition); - data.RedTransitions = m_redTransitionCount.updateCurrent(redTransition); - - data.LuminanceExtendedFailCount = m_luminanceExtendedCount.updateCurrent(m_luminanceTransitionCount.current <= m_params->maxTransitions && m_luminanceTransitionCount.current >= m_params->minTransitions); - data.RedExtendedFailCount = m_redExtendedCount.updateCurrent(m_redTransitionCount.current <= m_params->maxTransitions && m_redTransitionCount.current >= m_params->minTransitions); - } - - void TransitionTrackerByFPS::EvaluateFrameMoment(int framePos, int fps, FrameData& data) - { - if (m_luminanceTransitionCount.current > m_params->maxTransitions) //FAIL as max allowed transitions has been surpassed - { - m_luminanceResults.flashFail = true; - data.luminanceFrameResult = FlashResult::FlashFail; - m_luminanceIncidents.flashFailFrames += 1; - } - else if (m_luminanceExtendedCount.current >= m_params->extendedFailSeconds * fps && m_luminanceTransitionCount.current >= 4) //EXTENDED FAILURE - { - m_luminanceResults.extendedFail = true; - data.luminanceFrameResult = FlashResult::ExtendedFail; - m_luminanceIncidents.extendedFailFrames += 1; - } - else if (m_luminanceTransitionCount.current >= 4) - { - m_luminanceResults.passWithWarning = true; - data.luminanceFrameResult = FlashResult::PassWithWarning; - m_luminanceIncidents.passWithWarningFrames += 1; - } - - if (m_redTransitionCount.current > m_params->maxTransitions) //FAIL as max allowed transitions has been surpassed - { - m_redResults.flashFail = true; - data.redFrameResult = FlashResult::FlashFail; - m_redIncidents.flashFailFrames += 1; - } - else if (m_redExtendedCount.current >= m_params->extendedFailSeconds * fps && m_redTransitionCount.current >= 4) //EXTENDED FAILURE - { - m_redResults.extendedFail = true; - data.redFrameResult = FlashResult::ExtendedFail; - m_redIncidents.extendedFailFrames += 1; - } - else if (m_redTransitionCount.current >= 4) - { - m_redResults.passWithWarning = true; - data.redFrameResult = FlashResult::PassWithWarning; - m_redIncidents.passWithWarningFrames += 1; - } - - //update transition lists as 1s has passed - if (framePos >= fps - 1) - { - m_luminanceTransitionCount.updatePassed(); - m_redTransitionCount.updatePassed(); - - // update extended failure as 5s have passed - if (framePos >= m_params->extendedFailWindow * fps - 1) - { - m_luminanceExtendedCount.updatePassed(); - m_redExtendedCount.updatePassed(); - } - } - } -} \ No newline at end of file diff --git a/src/TransitionTrackerByFPS.h b/src/TransitionTrackerByFPS.h deleted file mode 100644 index d53950e..0000000 --- a/src/TransitionTrackerByFPS.h +++ /dev/null @@ -1,27 +0,0 @@ -//Copyright (C) 2023 Electronic Arts, Inc. All rights reserved. - -#pragma once -#include "TransitionTracker.h" -#include "ConfigurationParams.h" -#include "FrameData.h" -#include - -namespace iris -{ - class TransitionTrackerByFPS :public TransitionTracker { - - public: - TransitionTrackerByFPS(unsigned int fps, TransitionTrackerParams* params); - - void SetTransitions(bool lumTransition, bool redTransition, FrameData& data) override; - - /// - /// Checks if in the current frame (moment of the video) the video has - /// failed the flash criteria - /// - /// current frame index - /// video frame rate - /// data to persist - void EvaluateFrameMoment(int framePos, int fps, FrameData& data) override; - }; -} \ No newline at end of file diff --git a/src/TransitionTrackerByTime.cpp b/src/TransitionTrackerByTime.cpp deleted file mode 100644 index 39cd8c8..0000000 --- a/src/TransitionTrackerByTime.cpp +++ /dev/null @@ -1,106 +0,0 @@ -#include "TransitionTrackerByTime.h" - -namespace iris -{ - TransitionTrackerByTime::TransitionTrackerByTime(unsigned int starterFpsReserve, TransitionTrackerParams* params) - : TransitionTracker() - { - m_params = params; - m_luminanceTransitionCount.count.reserve(starterFpsReserve); m_luminanceTransitionCount.count.emplace_back(0); - m_redTransitionCount.count.reserve(starterFpsReserve); m_redTransitionCount.count.emplace_back(0); - m_luminanceExtendedCount.count.reserve(m_params->extendedFailWindow * starterFpsReserve); m_luminanceExtendedCount.count.emplace_back(0); - m_redExtendedCount.count.reserve(m_params->extendedFailWindow * starterFpsReserve); m_redExtendedCount.count.emplace_back(0); - - m_oneSecondTimeStamps.frameTimeStamp.reserve(starterFpsReserve + 1); - m_oneSecondTimeStamps.timesBetweenPairOfFrames.reserve(starterFpsReserve); - - m_fiveSecondTimeStamps.frameTimeStamp.reserve(m_params->extendedFailSeconds * starterFpsReserve + 1); - m_fiveSecondTimeStamps.timesBetweenPairOfFrames.reserve(m_params->extendedFailWindow * starterFpsReserve); - - m_fourSecondTimeStamps.frameTimeStamp.reserve(m_params->extendedFailSeconds * starterFpsReserve + 1); - m_fourSecondTimeStamps.timesBetweenPairOfFrames.reserve(m_params->extendedFailWindow * starterFpsReserve); - - m_oneSecondTimeStamps.SetTimeBarrier(1); - m_fiveSecondTimeStamps.SetTimeBarrier(m_params->extendedFailWindow); - m_fourSecondTimeStamps.SetTimeBarrier(m_params->extendedFailSeconds); - - } - - void TransitionTrackerByTime::SetFirstFrame(FrameData& data) - { - m_oneSecondTimeStamps.AddNewFrame(data.TimeStampVal, 0); - m_fiveSecondTimeStamps.AddNewFrame(data.TimeStampVal, 0); - m_fourSecondTimeStamps.AddNewFrame(data.TimeStampVal, 0); - } - - void TransitionTrackerByTime::SetTransitions(bool lumTransition, bool redTransition, FrameData& data) - { - m_oneSecondFramesToRemove = m_oneSecondTimeStamps.GetFrameNumToRemove(data.TimeStampVal); - m_fiveSecondFramesToRemove = m_fiveSecondTimeStamps.GetFrameNumToRemove(data.TimeStampVal); - m_fourSecondTimeStamps.GetFrameNumToRemove(data.TimeStampVal); - - //update transition lists as 1s has passed - for (; m_oneSecondFramesToRemove > 0; m_oneSecondFramesToRemove--) - { - m_luminanceTransitionCount.updatePassed(); - m_redTransitionCount.updatePassed(); - } - //update extended failure as 5s have passed - for (; m_fiveSecondFramesToRemove > 0; m_fiveSecondFramesToRemove--) - { - m_luminanceExtendedCount.updatePassed(); - m_redExtendedCount.updatePassed(); - } - - - data.LuminanceTransitions = m_luminanceTransitionCount.updateCurrent(lumTransition); - data.RedTransitions = m_redTransitionCount.updateCurrent(redTransition); - - data.LuminanceExtendedFailCount = m_luminanceExtendedCount.updateCurrent(m_luminanceTransitionCount.current <= m_params->maxTransitions && m_luminanceTransitionCount.current >= m_params->minTransitions); - data.RedExtendedFailCount = m_redExtendedCount.updateCurrent(m_redTransitionCount.current <= m_params->maxTransitions && m_redTransitionCount.current >= m_params->minTransitions); - - } - - void TransitionTrackerByTime::EvaluateFrameMoment(int framePos, int fps, FrameData& data) - { - int framesInFourSeconds = m_oneSecondTimeStamps.timesBetweenPairOfFrames.size() * m_params->extendedFailSeconds; //only works on videos, must found a solution to get the exact number of frames in the last 4 seconds - - if (m_luminanceTransitionCount.current > m_params->maxTransitions) //FAIL as max allowed transitions has been surpassed - { - m_luminanceResults.flashFail = true; - data.luminanceFrameResult = FlashResult::FlashFail; - m_luminanceIncidents.flashFailFrames += 1; - } - else if (m_luminanceExtendedCount.current >= framesInFourSeconds && m_luminanceTransitionCount.current >= 4) //EXTENDED FAILURE - { - m_luminanceResults.extendedFail = true; - data.luminanceFrameResult = FlashResult::ExtendedFail; - m_luminanceIncidents.extendedFailFrames += 1; - } - else if (m_luminanceTransitionCount.current >= 4) - { - m_luminanceResults.passWithWarning = true; - data.luminanceFrameResult = FlashResult::PassWithWarning; - m_luminanceIncidents.passWithWarningFrames += 1; - } - - if (m_redTransitionCount.current > m_params->maxTransitions) //FAIL as max allowed transitions has been surpassed - { - m_redResults.flashFail = true; - data.redFrameResult = FlashResult::FlashFail; - m_redIncidents.flashFailFrames += 1; - } - else if (m_redExtendedCount.current >= framesInFourSeconds && m_redTransitionCount.current >= 4) //EXTENDED FAILURE - { - m_redResults.extendedFail = true; - data.redFrameResult = FlashResult::ExtendedFail; - m_redIncidents.extendedFailFrames += 1; - } - else if (m_redTransitionCount.current >= 4) - { - m_redResults.passWithWarning = true; - data.redFrameResult = FlashResult::PassWithWarning; - m_redIncidents.passWithWarningFrames += 1; - } - } -} \ No newline at end of file diff --git a/src/TransitionTrackerByTime.h b/src/TransitionTrackerByTime.h deleted file mode 100644 index c7ad2d6..0000000 --- a/src/TransitionTrackerByTime.h +++ /dev/null @@ -1,120 +0,0 @@ -//Copyright (C) 2023 Electronic Arts, Inc. All rights reserved. - -#pragma once -#include "TransitionTracker.h" -#include "ConfigurationParams.h" -#include "FrameData.h" -#include -#include -#include "iris/Log.h" - -namespace iris -{ - class TransitionTrackerByTime :public TransitionTracker { - public: - TransitionTrackerByTime(unsigned int starterFpsReserve, TransitionTrackerParams* params); - - - void SetTransitions(bool lumTransition, bool redTransition, FrameData& data) override; - - /// - /// Checks if in the current frame (moment of the video) the video has - /// failed the flash criteria - /// - /// current frame index - /// video frame rate - /// data to persist - void EvaluateFrameMoment(int framePos, int fps, FrameData& data) override; - - /// - /// Add the first frame to the FrameTimeStamps structs - /// - /// data to persist - void SetFirstFrame(FrameData& data)override; - - private: - - struct FrameTimeStamps - { - std::vector frameTimeStamp; //vector of current frame entry times frames in the window - - std::vector timesBetweenPairOfFrames; //vector of current times between frames in the window - - float timesSum = 0; //total sum of times between each pair of Frames - - /// - /// Set time barrier in milliseconds - /// - /// time barrier in seconds - void SetTimeBarrier(int seconds) { - timeBarrier = seconds * 1000; - } - - /// - /// Check if when adding a new frame it is needed to update frameTimeStamp and timesBetweenPairOfFrames vectors (timeBarrier has been surpassed), - /// then add newFrameTime to frameTimeStamp and timesBetweenPairOfFrames vectors. - /// This function returns an integer (number of frames to remove from the count vectors) - /// - /// new frame MS - int GetFrameNumToRemove(const unsigned long & newFrameTime) - { - int framesToRemove = 0; //number of frames to that are no longer inside the time window - long newTimeBetFrames = 0;//time between frame to add and last recorded frame time stamp - - if (frameTimeStamp.size() > 0) - { - newTimeBetFrames= newFrameTime - frameTimeStamp[frameTimeStamp.size() - 1]; - - if (timesSum + newTimeBetFrames == timeBarrier) - { - framesToRemove++; - } - //Remove frames until new frame fits inside the window - while (timesSum + newTimeBetFrames > timeBarrier) - { - timesSum -= timesBetweenPairOfFrames[0]; - frameTimeStamp.erase(frameTimeStamp.begin()); - timesBetweenPairOfFrames.erase(timesBetweenPairOfFrames.begin()); - - framesToRemove++; - } - } - AddNewFrame(newFrameTime, newTimeBetFrames); - - return framesToRemove; - } - - /// - /// add the new frame time in the frameTimeStamp and the timesBetweenPairOfFrames vectors - /// also update the timesSum (times between frames) variable - /// - /// new frame MS - /// time between frame to add and last recorded frame time stamp - void AddNewFrame(const unsigned long & newFrameTime, const unsigned long& newTimeBetFrames) - { - if (frameTimeStamp.size() > 0) - { - timesSum += newTimeBetFrames; - timesBetweenPairOfFrames.emplace_back(newTimeBetFrames); - } - frameTimeStamp.emplace_back(newFrameTime); - } - private: - //Time barrier measured in seconds - //Used to know when timesBetweenPairOfFrames vector sum has surpased the desired second window and vectors needs to be updated - int timeBarrier; - }; - - - FrameTimeStamps m_oneSecondTimeStamps; //1 second window - - FrameTimeStamps m_fiveSecondTimeStamps; //5 second window - - FrameTimeStamps m_fourSecondTimeStamps; //4 second window - - int m_oneSecondFramesToRemove=0 , m_fiveSecondFramesToRemove = 0; //Number of frames to be removed from the count vector of the Counter structs - - - }; - -} diff --git a/src/VideoAnalyser.cpp b/src/VideoAnalyser.cpp index 85c0d0e..d7e9c85 100644 --- a/src/VideoAnalyser.cpp +++ b/src/VideoAnalyser.cpp @@ -18,6 +18,8 @@ #include #include "utils/JsonWrapper.h" #include +#include "FpsFrameManager.h" +#include "TimeFrameManager.h" extern "C" { #include @@ -42,8 +44,10 @@ namespace iris { } - void VideoAnalyser::Init(const std::string& videoName, bool flagJson) + void VideoAnalyser::Init(const std::string& videoPath, bool flagJson) { + m_frameManager = new FpsFrameManager(); + if (m_configuration->FrameResizeEnabled()) { float resizedFrameProportion; @@ -51,29 +55,40 @@ namespace iris LOG_CORE_INFO("Resizing frames at: {0}%", resizedFrameProportion * 100); m_videoInfo.frameSize = cv::Size(m_videoInfo.frameSize.width * resizedFrameProportion, m_videoInfo.frameSize.height * resizedFrameProportion); } - - m_flashDetection = new FlashDetection(m_configuration, m_videoInfo.fps, m_videoInfo.frameSize); + + m_flashDetection = new FlashDetection(m_configuration, m_videoInfo.fps, m_videoInfo.frameSize, m_frameManager); m_photosensitivityDetector.push_back(m_flashDetection); m_frameSrgbConverter = new EA::EACC::Utils::FrameConverter(m_configuration->GetFrameSrgbConverterParams()); - m_patternDetection = new PatternDetection(m_configuration, m_videoInfo.fps, m_videoInfo.frameSize); + m_patternDetection = new PatternDetection(m_configuration, m_videoInfo.fps, m_videoInfo.frameSize, m_frameManager); if (m_configuration->PatternDetectionEnabled()) { m_photosensitivityDetector.push_back(m_patternDetection); } + std::string videoFileName; + if (std::filesystem::exists(videoPath)) + { + videoFileName = std::filesystem::path{ videoPath }.filename().string(); + } + else + { //Video is not a file, it's a URL + int indexBegin = videoPath.find_last_of("/"); + int indexEnd = videoPath.find_last_of("."); + assert(indexBegin != videoFileName.npos); + assert(indexEnd != videoFileName.npos); + + videoFileName = videoPath.substr(indexBegin,indexEnd-indexBegin); + } - std::string frameDataFile = m_configuration->GetResultsPath() + videoName + "/framedata.csv"; - Log::SetDataLoggerFile(frameDataFile.c_str()); + m_frameDataPath = m_configuration->GetResultsPath() + videoFileName + "/framedata.csv"; + Log::SetDataLoggerFile(m_frameDataPath.c_str()); if (flagJson) { - m_resultJsonPath = m_configuration->GetResultsPath() + videoName + "/" + "result" + ".json"; - m_frameDataJsonPath = m_configuration->GetResultsPath() + videoName + "/" + "frameData" + ".json"; + m_resultJsonPath = m_configuration->GetResultsPath() + videoFileName + "/result.json"; + m_frameDataJsonPath = m_configuration->GetResultsPath() + videoFileName + "/frameData.json"; } - const char* luminanceType = m_configuration->GetLuminanceType() == Configuration::LuminanceType::CD ? "CD" : "RELATIVE"; - LOG_CORE_INFO("Luminance Type: {0}", luminanceType); - LOG_CORE_INFO("Pattern Detection: {0}", m_configuration->PatternDetectionEnabled()); LOG_CORE_INFO("Frame Resize: {0}", m_configuration->FrameResizeEnabled()); @@ -83,6 +98,34 @@ namespace iris LOG_CORE_INFO("Write json file: {0}", flagJson); } + void VideoAnalyser::RealTimeInit(cv::Size& frameSize) + { + m_frameManager = new TimeFrameManager(); + + //Default SetUp for Real time use + m_videoInfo.fps = 60; + m_videoInfo.frameCount = -1; + m_videoInfo.duration = -1; + m_videoInfo.frameSize = frameSize; + + if (m_configuration->FrameResizeEnabled()) + { + float resizedFrameProportion; + resizedFrameProportion = m_configuration->GetFrameResizeProportion(); + LOG_CORE_INFO("Resizing frames at: {0}%", resizedFrameProportion * 100); + m_videoInfo.frameSize = cv::Size(m_videoInfo.frameSize.width * resizedFrameProportion, m_videoInfo.frameSize.height * resizedFrameProportion); + } + m_flashDetection = new FlashDetection(m_configuration, m_videoInfo.fps, m_videoInfo.frameSize, m_frameManager); + m_photosensitivityDetector.push_back(m_flashDetection); + m_frameSrgbConverter = new EA::EACC::Utils::FrameConverter(m_configuration->GetFrameSrgbConverterParams()); + m_patternDetection = new PatternDetection(m_configuration, m_videoInfo.fps, m_videoInfo.frameSize, m_frameManager); + + if (m_configuration->PatternDetectionEnabled()) + { + m_photosensitivityDetector.push_back(m_patternDetection); + } + } + void VideoAnalyser::DeInit() { if (m_flashDetection != nullptr) @@ -97,18 +140,21 @@ namespace iris { delete m_frameSrgbConverter; m_frameSrgbConverter = nullptr; } - + if (m_frameManager != nullptr) + { + delete m_frameManager; m_frameManager = nullptr; + } m_photosensitivityDetector.clear(); } void VideoAnalyser::AnalyseVideo(bool flagJson, const char* sourceVideo) { cv::VideoCapture video(sourceVideo); - std::string videoName = std::filesystem::path(sourceVideo).filename().string(); + std::string videoPath(sourceVideo); - if (VideoIsOpen(sourceVideo, video, videoName.c_str())) + if (VideoIsOpen(sourceVideo, video)) { - Init(videoName, flagJson); + Init(videoPath, flagJson); SetOptimalCvThreads(m_videoInfo.frameSize); cv::Mat frame; video.read(frame); @@ -146,6 +192,8 @@ namespace iris LOG_DATA_INFO(data.ToCSV()); + FLUSH_DATA_LOGGER(); + if (flagJson) { lineGraphData.push_back_lineGraphData(data); @@ -162,20 +210,26 @@ namespace iris unsigned int elapsedTime = std::chrono::duration_cast(end - start).count(); LOG_CORE_INFO("Elapsed time: {0} ms", elapsedTime); + Result result; + m_flashDetection->setResult(result); + + if (m_patternDetection != nullptr) { m_patternDetection->setResult(result); } + if (m_flashDetection->isFail() || m_patternDetection->isFail()) { - LOG_CORE_INFO("Video Result: FAIL"); + LOG_CORE_CRITICAL("Video Overall Result: FAIL"); + } + else if (m_flashDetection->isWarning()) + { + LOG_CORE_WARNING("Video Overall Result: PASS WITH WARNING"); } else { - LOG_CORE_INFO("Video Result: PASS"); + LOG_CORE_INFO("Video Overall Result: PASS"); } if (flagJson) - { - Result result; - m_flashDetection->setResult(result); - if (m_patternDetection != nullptr) { m_patternDetection->setResult(result); } + { result.VideoLen = m_videoInfo.duration * 1000; result.AnalysisTime = elapsedTime; result.TotalFrame = m_videoInfo.frameCount; @@ -192,6 +246,8 @@ namespace iris { IrisFrame irisFrame(&(frame), m_frameSrgbConverter->Convert(frame), data); + m_frameManager->AddFrame(data); + m_flashDetection->setLuminance(irisFrame); for (auto detector : m_photosensitivityDetector) { @@ -227,7 +283,7 @@ namespace iris LOG_CORE_INFO("Number of threads used: {0}", threads_used); } - bool VideoAnalyser::VideoIsOpen(const char* sourceVideo, cv::VideoCapture& video, const char* videoName) + bool VideoAnalyser::VideoIsOpen(const char* sourceVideo, cv::VideoCapture& video) { if (video.isOpened()) { @@ -242,7 +298,7 @@ namespace iris m_videoInfo.frameSize = cv::Size(video.get(cv::CAP_PROP_FRAME_WIDTH), video.get(cv::CAP_PROP_FRAME_HEIGHT)); m_videoInfo.duration = m_videoInfo.frameCount / (float)m_videoInfo.fps; - LOG_CORE_INFO("Video: {0} opened successful", videoName); + LOG_CORE_INFO("Video: {0} opened successful", sourceVideo); LOG_CORE_INFO("Video FPS: {}", m_videoInfo.fps); LOG_CORE_INFO("Total frames: {0}", m_videoInfo.frameCount); LOG_CORE_INFO("Video resolution: {0}x{1}", m_videoInfo.frameSize.width, m_videoInfo.frameSize.height); @@ -250,8 +306,8 @@ namespace iris return true; } - LOG_CORE_ERROR("Video: {0} could not be opened\nInformation is missing or corrupt", videoName); - throw std::runtime_error("Video: "+ std::string(videoName) +"could not be opened\nInformation is missing or corrupt"); + LOG_CORE_ERROR("Video: {0} could not be opened\nInformation is missing or corrupt", sourceVideo); + throw std::runtime_error("Video: "+ std::string(sourceVideo) +"could not be opened\nInformation is missing or corrupt"); return false; } diff --git a/test/Iris.Tests/CMakeLists.txt b/test/Iris.Tests/CMakeLists.txt index f3645b6..3b61b71 100644 --- a/test/Iris.Tests/CMakeLists.txt +++ b/test/Iris.Tests/CMakeLists.txt @@ -3,7 +3,7 @@ project(iris_tests) set(HEADER_FILES - "include/IrisLibTest.h" + "include/IrisLibTest.h" ) source_group("Header Files" FILES ${HEADER_FILES}) @@ -12,12 +12,11 @@ set(SOURCE_FILES "src/FlashTest.cpp" "src/RedSaturationTests.cpp" "src/RelativeLuminanceTest.cpp" - "src/CDLuminanceTest.cpp" "src/FlashDetectionTests.cpp" "src/PatternDetectionTests.cpp" "src/VideoAnalysisTests.cpp" - "src/TransitionTrackerByFPSTests.cpp" - "src/TransitionTrackerByTimeTests.cpp" + "src/TransitionTrackerTests.cpp" + "src/FrameManagerTests.cpp" ) source_group("Source Files" FILES ${SOURCE_FILES}) diff --git a/test/Iris.Tests/appsettings.json b/test/Iris.Tests/appsettings.json index 0f644ca..93df1a3 100644 --- a/test/Iris.Tests/appsettings.json +++ b/test/Iris.Tests/appsettings.json @@ -1,557 +1,296 @@ { "Luminance": { - "FormulaYval1": 413.435, //CD luminance formula values - "FormulaYval2": 0.002745, - "FormulaYval3": 0.0189623, - "FormulaYvalpow": 2.2, "RelativeLuminanceFlashThreshold": 0.1, //flash transition - "RelativeDarkLuminanceThreshold": 0.8, - "CdLuminanceFlashThreshold": 20, //flash transition - "CdDarkLuminanceThreshold": 160, - //possible CD luminanve values for look up table - "CdLuminanceValues": [ - 0.07, - 0.09, - 0.12, - 0.15, - 0.18, - 0.22, - 0.27, - 0.31, - 0.37, - 0.42, - 0.48, - 0.55, - 0.62, - 0.69, - 0.77, - 0.85, - 0.94, - 1.03, - 1.13, - 1.23, - 1.34, - 1.45, - 1.57, - 1.69, - 1.82, - 1.95, - 2.09, - 2.23, - 2.37, - 2.53, - 2.68, - 2.85, - 3.01, - 3.19, - 3.37, - 3.55, - 3.74, - 3.93, - 4.13, - 4.34, - 4.55, - 4.77, - 4.99, - 5.21, - 5.45, - 5.68, - 5.93, - 6.18, - 6.43, - 6.69, - 6.96, - 7.23, - 7.51, - 7.79, - 8.08, - 8.38, - 8.68, - 8.98, - 9.3, - 9.61, - 9.94, - 10.27, - 10.6, - 10.94, - 11.29, - 11.64, - 12, - 12.37, - 12.74, - 13.12, - 13.5, - 13.89, - 14.28, - 14.69, - 15.09, - 15.51, - 15.93, - 16.35, - 16.78, - 17.22, - 17.67, - 18.12, - 18.57, - 19.04, - 19.5, - 19.98, - 20.46, - 20.95, - 21.44, - 21.94, - 22.45, - 22.96, - 23.48, - 24.01, - 24.54, - 25.08, - 25.62, - 26.17, - 26.73, - 27.29, - 27.86, - 28.44, - 29.02, - 29.61, - 30.21, - 30.81, - 31.42, - 32.03, - 32.66, - 33.29, - 33.92, - 34.56, - 35.21, - 35.86, - 36.53, - 37.19, - 37.87, - 38.55, - 39.24, - 39.93, - 40.63, - 41.34, - 42.05, - 42.78, - 43.5, - 44.24, - 44.98, - 45.73, - 46.48, - 47.24, - 48.01, - 48.79, - 49.57, - 50.36, - 51.15, - 51.95, - 52.76, - 53.58, - 54.4, - 55.23, - 56.07, - 56.91, - 57.76, - 58.62, - 59.48, - 60.35, - 61.23, - 62.11, - 63, - 63.9, - 64.81, - 65.72, - 66.64, - 67.56, - 68.5, - 69.44, - 70.38, - 71.34, - 72.3, - 73.27, - 74.24, - 75.22, - 76.21, - 77.21, - 78.21, - 79.22, - 80.24, - 81.26, - 82.3, - 83.34, - 84.38, - 85.43, - 86.49, - 87.56, - 88.64, - 89.72, - 90.81, - 91.9, - 93, - 94.11, - 95.23, - 96.36, - 97.49, - 98.63, - 99.77, - 100.93, - 102.09, - 103.25, - 104.43, - 105.61, - 106.8, - 108, - 109.2, - 110.41, - 111.63, - 112.86, - 114.09, - 115.33, - 116.58, - 117.84, - 119.1, - 120.37, - 121.65, - 122.93, - 124.22, - 125.52, - 126.83, - 128.14, - 129.47, - 130.8, - 132.13, - 133.48, - 134.83, - 136.19, - 137.55, - 138.93, - 140.31, - 141.69, - 143.09, - 144.49, - 145.9, - 147.32, - 148.75, - 150.18, - 151.62, - 153.07, - 154.53, - 155.99, - 157.46, - 158.94, - 160.43, - 161.92, - 163.42, - 164.93, - 166.45, - 167.97, - 169.5, - 171.04, - 172.59, - 174.14, - 175.7, - 177.27, - 178.85, - 180.43, - 182.03, - 183.63, - 185.23, - 186.85, - 188.47, - 190.1, - 191.74, - 193.38, - 195.04, - 196.7, - 198.37, - 200 - ] + "RelativeDarkLuminanceThreshold": 0.8 }, "RedSaturation": { "FlashThreshold": 20, //threshold for red saturation transitions "RedDarkThreshold": 321 }, + + "PatternDetection": { + "MinStripes": 6, //min stripes for harmful patterns + "TimeThreshold": 0.5, //max seconds for harmful patterns until failure + "RelativeDarkLuminanceThreshold": 0.8, + "AreaProportion": 0.25 + }, + + "FilePersistence": { + "MaxDataStored": 10 //max stored frame data in memory until persistence + }, + + "TransitionTracker": { + "MaxTransitions": 6, //max allowed transitions and max transitions to count for extended fail + "MinTransitions": 4, //amount of min transitions to add to extended fail count + "ExtendedFailSeconds": 4, //max seconds until the start of extended failure + "ExtendedFailWindow": 5, //seconds in extended fail count window + "WarningTransitions": 4 + }, + "FlashDetection": { "AreaProportion": 0.25, //screen display flashing area //sRGB possible values for look up table "sRGBValues": [ 0, - 0.000303527, - 0.000607054, - 0.000910581, - 0.001214108, - 0.001517635, - 0.001821162, - 0.0021246888, - 0.002428216, - 0.002731743, - 0.00303527, - 0.0033465363, - 0.0036765079, - 0.004024718, - 0.004391443, - 0.004776954, - 0.005181518, - 0.0056053926, - 0.006048834, - 0.0065120924, - 0.0069954116, - 0.007499033, - 0.008023194, - 0.008568126, - 0.009134059, - 0.00972122, - 0.010329825, - 0.010960096, - 0.011612247, - 0.012286489, - 0.0129830325, - 0.013702083, - 0.014443846, - 0.015208517, - 0.015996296, - 0.016807377, - 0.017641956, - 0.01850022, - 0.019382365, - 0.020288566, - 0.021219013, - 0.022173887, - 0.023153368, - 0.024157634, - 0.025186861, - 0.026241226, - 0.027320895, - 0.028426042, - 0.029556837, - 0.030713446, - 0.031896036, - 0.033104766, - 0.03433981, - 0.035601318, - 0.03688945, - 0.03820437, - 0.039546244, - 0.040915202, - 0.042311415, - 0.043735035, - 0.04518621, - 0.04666509, - 0.048171826, - 0.049706567, - 0.05126947, - 0.05286066, - 0.05448029, - 0.056128502, - 0.05780544, - 0.059511248, - 0.06124608, - 0.06301004, - 0.06480329, - 0.06662596, - 0.06847819, - 0.07036012, - 0.07227187, - 0.07421359, - 0.0761854, - 0.078187436, - 0.080219835, - 0.08228272, - 0.08437622, - 0.08650047, - 0.08865561, - 0.09084174, - 0.09305899, - 0.09530749, - 0.09758737, - 0.09989875, - 0.102241755, - 0.10461651, - 0.10702312, - 0.10946173, - 0.11193245, - 0.11443539, - 0.11697068, - 0.11953844, - 0.122138806, - 0.12477185, - 0.12743771, - 0.1301365, - 0.13286835, - 0.13563335, - 0.13843164, - 0.14126332, - 0.14412849, - 0.14702728, - 0.1499598, - 0.15292618, - 0.15592648, - 0.15896088, - 0.16202942, - 0.16513222, - 0.16826941, - 0.17144111, - 0.1746474, - 0.17788842, - 0.18116425, - 0.18447499, - 0.18782078, - 0.19120169, - 0.19461782, - 0.19806932, - 0.20155625, - 0.20507872, - 0.20863685, - 0.21223074, - 0.21586055, - 0.21952623, - 0.223228, - 0.2269659, - 0.23074009, - 0.23455067, - 0.23839766, - 0.24228121, - 0.24620141, - 0.25015837, - 0.25415218, - 0.25818294, - 0.26225075, - 0.2663557, - 0.27049786, - 0.2746774, - 0.27889434, - 0.28314883, - 0.2874409, - 0.29177073, - 0.29613835, - 0.30054384, - 0.30498737, - 0.30946898, - 0.31398878, - 0.31854683, - 0.32314327, - 0.32777816, - 0.33245158, - 0.33716366, - 0.34191447, - 0.3467041, - 0.35153273, - 0.35640025, - 0.3613069, - 0.36625272, - 0.37123778, - 0.37626222, - 0.3813261, - 0.38642955, - 0.39157256, - 0.39675534, - 0.40197787, - 0.4072403, - 0.4125427, - 0.41788515, - 0.42326775, - 0.42869058, - 0.4341537, - 0.43965724, - 0.44520128, - 0.45078585, - 0.4564111, - 0.46207705, - 0.46778387, - 0.47353154, - 0.47932023, - 0.48515, - 0.4910209, - 0.49693304, - 0.5028866, - 0.50888145, - 0.5149178, - 0.5209957, - 0.5271153, - 0.53327656, - 0.5394796, - 0.5457246, - 0.55201155, - 0.5583405, - 0.56471163, - 0.5711249, - 0.5775806, - 0.58407855, - 0.59061897, - 0.5972019, - 0.6038274, - 0.6104957, - 0.61720663, - 0.6239605, - 0.6307572, - 0.63759696, - 0.64447975, - 0.6514057, - 0.6583749, - 0.66538733, - 0.6724432, - 0.67954254, - 0.6866855, - 0.6938719, - 0.7011021, - 0.70837593, - 0.71569365, - 0.7230553, - 0.7304609, - 0.73791057, - 0.74540436, - 0.7529423, - 0.76052463, - 0.7681513, - 0.77582234, - 0.7835379, - 0.79129803, - 0.79910284, - 0.80695236, - 0.8148467, - 0.82278585, - 0.83076996, - 0.8387991, - 0.84687334, - 0.8549927, - 0.8631573, - 0.8713672, - 0.87962234, - 0.8879232, - 0.89626944, - 0.90466136, - 0.9130987, - 0.92158204, - 0.9301109, - 0.9386859, - 0.9473066, - 0.9559735, - 0.9646863, - 0.9734455, - 0.9822506, - 0.9911022, + 0.0003035269835488375, + 0.000607053967097675, + 0.0009105809506465125, + 0.00121410793419535, + 0.0015176349177441874, + 0.001821161901293025, + 0.0021246888848418626, + 0.0024282158683907, + 0.0027317428519395373, + 0.003035269835488375, + 0.003346535763899161, + 0.003676507324047436, + 0.004024717018496307, + 0.004391442037410293, + 0.004776953480693729, + 0.005181516702338386, + 0.005605391624202723, + 0.006048833022857054, + 0.006512090792594475, + 0.006995410187265387, + 0.007499032043226175, + 0.008023192985384994, + 0.008568125618069307, + 0.009134058702220787, + 0.00972121732023785, + 0.010329823029626936, + 0.010960094006488246, + 0.011612245179743885, + 0.012286488356915872, + 0.012983032342173012, + 0.013702083047289686, + 0.014443843596092545, + 0.01520851442291271, + 0.01599629336550963, + 0.016807375752887384, + 0.017641954488384078, + 0.018500220128379697, + 0.019382360956935723, + 0.0202885630566524, + 0.021219010376003555, + 0.022173884793387385, + 0.02315336617811041, + 0.024157632448504756, + 0.02518685962736163, + 0.026241221894849898, + 0.027320891639074894, + 0.028426039504420793, + 0.0295568344378088, + 0.030713443732993635, + 0.03189603307301153, + 0.033104766570885055, + 0.03433980680868217, + 0.03560131487502034, + 0.03688945040110004, + 0.0382043715953465, + 0.03954623527673284, + 0.04091519690685319, + 0.042311410620809675, + 0.043735029256973465, + 0.04518620438567554, + 0.046665086336880095, + 0.04817182422688942, + 0.04970656598412723, + 0.05126945837404324, + 0.052860647023180246, + 0.05448027644244237, + 0.05612849004960009, + 0.05780543019106723, + 0.0595112381629812, + 0.06124605423161761, + 0.06301001765316767, + 0.06480326669290577, + 0.06662593864377289, + 0.06847816984440017, + 0.07036009569659588, + 0.07227185068231748, + 0.07421356838014963, + 0.07618538148130785, + 0.07818742180518633, + 0.08021982031446832, + 0.0822827071298148, + 0.08437621154414882, + 0.08650046203654976, + 0.08865558628577294, + 0.09084171118340768, + 0.09305896284668745, + 0.0953074666309647, + 0.09758734714186246, + 0.09989872824711389, + 0.10224173308810132, + 0.10461648409110419, + 0.10702310297826761, + 0.10946171077829933, + 0.1119324278369056, + 0.11443537382697373, + 0.11697066775851084, + 0.11953842798834562, + 0.12213877222960187, + 0.12477181756095049, + 0.12743768043564743, + 0.1301364766903643, + 0.13286832155381798, + 0.13563332965520566, + 0.13843161503245183, + 0.14126329114027164, + 0.14412847085805777, + 0.14702726649759498, + 0.14995978981060856, + 0.15292615199615017, + 0.1559264637078274, + 0.1589608350608804, + 0.162029375639111, + 0.1651321945016676, + 0.16826940018969075, + 0.1714411007328226, + 0.17464740365558504, + 0.17788841598362912, + 0.18116424424986022, + 0.184474994500441, + 0.18782077230067787, + 0.19120168274079138, + 0.1946178304415758, + 0.19806931955994886, + 0.20155625379439707, + 0.20507873639031693, + 0.20863687014525575, + 0.21223075741405523, + 0.21586050011389926, + 0.2195261997292692, + 0.2232279573168085, + 0.22696587351009836, + 0.23074004852434915, + 0.23455058216100522, + 0.238397573812271, + 0.24228112246555486, + 0.24620132670783548, + 0.25015828472995344, + 0.25415209433082675, + 0.2581828529215958, + 0.26225065752969623, + 0.26635560480286247, + 0.2704977910130658, + 0.27467731206038465, + 0.2788942634768104, + 0.2831487404299921, + 0.2874408377269175, + 0.29177064981753587, + 0.2961382707983211, + 0.3005437944157765, + 0.3049873140698863, + 0.30946892281750854, + 0.31398871337571754, + 0.31854677812509186, + 0.32314320911295075, + 0.3277780980565422, + 0.33245153634617935, + 0.33716361504833037, + 0.3419144249086609, + 0.3467040563550296, + 0.35153259950043936, + 0.3564001441459435, + 0.3613067797835095, + 0.3662525955988395, + 0.3712376804741491, + 0.3762621229909065, + 0.38132601143253014, + 0.386429433787049, + 0.39157247774972326, + 0.39675523072562685, + 0.4019777798321958, + 0.4072402119017367, + 0.41254261348390375, + 0.4178850708481375, + 0.4232676699860717, + 0.4286904966139066, + 0.43415363617474895, + 0.4396571738409188, + 0.44520119451622786, + 0.45078578283822346, + 0.45641102318040466, + 0.4620769996544071, + 0.467783796112159, + 0.47353149614800955, + 0.4793201831008268, + 0.4851499400560704, + 0.4910208498478356, + 0.4969329950608704, + 0.5028864580325687, + 0.5088813208549338, + 0.5149176653765214, + 0.5209955732043543, + 0.5271151257058131, + 0.5332764040105052, + 0.5394794890121072, + 0.5457244613701866, + 0.5520114015120001, + 0.5583403896342679, + 0.5647115057049292, + 0.5711248294648731, + 0.5775804404296506, + 0.5840784178911641, + 0.5906188409193369, + 0.5972017883637634, + 0.6038273388553378, + 0.6104955708078648, + 0.6172065624196511, + 0.6239603916750761, + 0.6307571363461468, + 0.6375968739940326, + 0.6444796819705821, + 0.6514056374198242, + 0.6583748172794485, + 0.665387298282272, + 0.6724431569576875, + 0.6795424696330938, + 0.6866853124353135, + 0.6938717612919899, + 0.7011018919329731, + 0.7083757798916868, + 0.7156935005064807, + 0.7230551289219693, + 0.7304607400903537, + 0.7379104087727308, + 0.7454042095403874, + 0.7529422167760779, + 0.7605245046752924, + 0.768151147247507, + 0.7758222183174236, + 0.7835377915261935, + 0.7912979403326302, + 0.799102738014409, + 0.8069522576692516, + 0.8148465722161012, + 0.8227857543962835, + 0.8307698767746546, + 0.83879901174074, + 0.846873231509858, + 0.8549926081242338, + 0.8631572134541023, + 0.8713671191987972, + 0.8796223968878317, + 0.8879231178819663, + 0.8962693533742664, + 0.9046611743911496, + 0.9130986517934192, + 0.9215818562772946, + 0.9301108583754237, + 0.938685728457888, + 0.9473065367331999, + 0.9559733532492861, + 0.9646862478944651, + 0.9734452903984125, + 0.9822505503331171, + 0.9911020971138298, 1 ] }, - "TransitionTracker": { - "MaxTransitions": 6, - "MinTransitions": 4, - "ExtendedFailSeconds": 4, - "ExtendedFailWindow": 5, - "AnalyseByTime": false - }, - "PatternDetection": { - "MinStripes": 6, //min stripes for harmful patterns - "TimeThreshold": 0.5, //max seconds for harmful patterns until failure - "CDDarkLuminanceThreshold": 160, - "RelativeDarkLuminanceThreshold": 0.8, - "AreaProportion": 0.25 - }, "VideoAnalyser": { - "ScreenShotsPath": "ScreenShots", - "LuminanceType": "RELATIVE", //CD || RELATIVE "PatternDetectionEnabled": false, "FrameResizeEnabled": false, "ResizeFrameProportion": 0.2 diff --git a/test/Iris.Tests/include/IrisLibTest.h b/test/Iris.Tests/include/IrisLibTest.h index bafdea9..03a42f0 100644 --- a/test/Iris.Tests/include/IrisLibTest.h +++ b/test/Iris.Tests/include/IrisLibTest.h @@ -8,6 +8,7 @@ #include #include "iris/Configuration.h" #include +#include "iris/FrameData.h" //redefine logging macros #ifdef LOG_CORE_DEBUG diff --git a/test/Iris.Tests/src/CDLuminanceTest.cpp b/test/Iris.Tests/src/CDLuminanceTest.cpp deleted file mode 100644 index 1c3102b..0000000 --- a/test/Iris.Tests/src/CDLuminanceTest.cpp +++ /dev/null @@ -1,146 +0,0 @@ -//Copyright (C) 2023 Electronic Arts, Inc. All rights reserved. - -#include -#include "utils/FrameConverter.h" -#include "CDLuminance.h" -#include "IrisLibTest.h" -#include "IrisFrame.h" -#include - -namespace iris::Tests -{ - class CDLuminanceTest : public IrisLibTest { - protected: - EA::EACC::Utils::FrameConverter* frameRgbConverter = nullptr; - void SetUp() override { - configuration.SetLuminanceType(Configuration::LuminanceType::CD); - IrisLibTest::SetUp(); - frameRgbConverter = new EA::EACC::Utils::FrameConverter(configuration.GetFrameCDLuminanceConverterParams()); - } - ~CDLuminanceTest() override { - delete frameRgbConverter; - } - }; - - TEST_F(CDLuminanceTest, Luminance_When_WhiteFrame_Test) - { - cv::Size size(1280, 720); - iris::CDLuminance cdLuminance(frameRgbConverter, 3, size, configuration.GetLuminanceFlashParams()); - cv::Mat imageBgr(size, CV_8UC3, white); - - cdLuminance.SetCurrentFrame(&imageBgr); - cv::Mat* luminance = cdLuminance.getCurrentFrame(); - float testLum = luminance->at(0, 0); - EXPECT_EQ(200, testLum); - - imageBgr.release(); - } - - TEST_F(CDLuminanceTest, Luminance_When_BlackFrame_Test) - { - cv::Size size(1280, 720); - iris::CDLuminance cdLuminance(frameRgbConverter, 3, size, configuration.GetLuminanceFlashParams()); - cv::Mat imageBgr(size, CV_8UC3, black); - - cdLuminance.SetCurrentFrame(&imageBgr); - cv::Mat* luminance = cdLuminance.getCurrentFrame(); - float testLum = luminance->at(0, 0); - EXPECT_EQ(0.07f, testLum); - } - - TEST_F(CDLuminanceTest, Luminance_When_GrayFrame_Test) - { - cv::Size size(1280, 720); - iris::CDLuminance cdLuminance(frameRgbConverter, 3, size, configuration.GetLuminanceFlashParams()); - cv::Mat imageBgr(size, CV_8UC3, gray); - - cdLuminance.SetCurrentFrame(&imageBgr); - cv::Mat* luminance = cdLuminance.getCurrentFrame(); - float testLum = luminance->at(0, 0); - EXPECT_EQ(46.48f, testLum); - - imageBgr.release(); - } - - TEST_F(CDLuminanceTest, Luminance_When_BlueFrame_Test) - { - cv::Size size(1280, 720); - CDLuminance cdLuminance(frameRgbConverter, 3, size, configuration.GetLuminanceFlashParams()); - cv::Mat imageBgr(size, CV_8UC3, blue); - - cdLuminance.SetCurrentFrame(&imageBgr); - cv::Mat* luminance = cdLuminance.getCurrentFrame(); - float testLum = luminance->at(0, 0); - EXPECT_EQ(2.53f, testLum); - - imageBgr.release(); - } - - TEST_F(CDLuminanceTest, SafeArea_No_Change_Threshold) - { - cv::Size size(5, 5); - CDLuminance cdLuminance(frameRgbConverter, 3, size, configuration.GetLuminanceFlashParams()); - - cv::Mat imageBgr(size, CV_8UC3, blue); - cdLuminance.SetCurrentFrame(&imageBgr); - cdLuminance.SetCurrentFrame(&imageBgr); - - cv::Mat* frameDiff = cdLuminance.FrameDifference(); - float avgDifference = cdLuminance.CheckSafeArea(frameDiff); - EXPECT_EQ(0, avgDifference); - - float flashAreaProportion = cdLuminance.GetFlashArea(); - EXPECT_EQ(0, flashAreaProportion); - - delete frameDiff; - } - - TEST_F(CDLuminanceTest, SafeArea_20_Percent_Change_Threshold) - { - cv::Size size(5, 5); - - float frameDiffArray[5][5] = { - { 200, 200, 200, 0, 0 }, - { 200, 200, 0, 0, 0 }, - { 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0 } - }; - cv::Mat frameDiff = cv::Mat(size, CV_32FC1, &frameDiffArray); - - CDLuminance cdLuminance(frameRgbConverter, 3, size, configuration.GetLuminanceFlashParams()); - - cv::Mat imageBgr(size, CV_8UC3, blue); - cdLuminance.SetCurrentFrame(&imageBgr); - - cv::Mat imageBgr2(size, CV_8UC3, white); - cdLuminance.SetCurrentFrame(&imageBgr2); - - float avgDifference = cdLuminance.CheckSafeArea(&frameDiff); - EXPECT_EQ(0, avgDifference); - - float flashAreaProportion = cdLuminance.GetFlashArea(); - EXPECT_TRUE(CompareFloat(0.2, flashAreaProportion)); - } - - TEST_F(CDLuminanceTest, SafeArea_100_Percent_Change_Threshold) - { - cv::Size size(5, 5); - CDLuminance cdLuminance(frameRgbConverter, 3, size, configuration.GetLuminanceFlashParams()); - - cv::Mat imageBgr(size, CV_8UC3, blue); - cdLuminance.SetCurrentFrame(&imageBgr); - - cv::Mat imageBgr2(size, CV_8UC3, white); - cdLuminance.SetCurrentFrame(&imageBgr2); - - cv::Mat* frameDiff = cdLuminance.FrameDifference(); - float avgDifference = cdLuminance.CheckSafeArea(frameDiff); - EXPECT_TRUE(CompareFloat(197.47, avgDifference)); - - float flashAreaProportion = cdLuminance.GetFlashArea(); - EXPECT_EQ(1, flashAreaProportion); - - delete frameDiff; - } -} diff --git a/test/Iris.Tests/src/FlashDetectionTests.cpp b/test/Iris.Tests/src/FlashDetectionTests.cpp index e85575c..a799274 100644 --- a/test/Iris.Tests/src/FlashDetectionTests.cpp +++ b/test/Iris.Tests/src/FlashDetectionTests.cpp @@ -4,168 +4,182 @@ #include "IrisLibTest.h" #include #include "FlashDetection.h" -#include "FrameData.h" +#include "iris/FrameData.h" #include "utils/FrameConverter.h" #include "IrisFrame.h" +#include "FpsFrameManager.h" +#include "TimeFrameManager.h" namespace iris::Tests { - class FlashDetectionTests : public IrisLibTest { - protected: - - void SetUp() override { //call configuration loading per test to load different luminances - cv::utils::logging::setLogLevel(cv::utils::logging::LogLevel::LOG_LEVEL_ERROR); - iris::Log::Init(false, false); - } - ~FlashDetectionTests() override { - } - }; - - TEST_F(FlashDetectionTests, RELATIVE_LUMINANCE) - { - configuration.SetLuminanceType(Configuration::LuminanceType::RELATIVE); - configuration.Init(); - - cv::Size size(100, 100); - - cv::Mat blackFrame(size, CV_8UC3, black); //lum = 0f - cv::Mat whiteFrame(size, CV_8UC3, white); //lum = 1f - cv::Mat redFrame(size, CV_8UC3, red); //lum = 0.2126f - - FlashDetection flashDetection(&configuration, 7, size); - EA::EACC::Utils::FrameConverter sRgbConverter(configuration.GetFrameSrgbConverterParams()); - - FrameData data; - IrisFrame irisBlackFrame(&blackFrame, sRgbConverter.Convert(blackFrame), FrameData()); - IrisFrame irisWhiteFrame(&whiteFrame, sRgbConverter.Convert(whiteFrame), FrameData()); - IrisFrame irisRedFrame(&redFrame, sRgbConverter.Convert(redFrame), FrameData()); - - //add transitions - flashDetection.setLuminance(irisBlackFrame); - flashDetection.checkFrame(irisBlackFrame, 0, data); - - flashDetection.setLuminance(irisWhiteFrame); - flashDetection.checkFrame(irisWhiteFrame, 1, data); - - flashDetection.setLuminance(irisRedFrame); - flashDetection.checkFrame(irisRedFrame, 2, data); - - flashDetection.setLuminance(irisWhiteFrame); - flashDetection.checkFrame(irisWhiteFrame, 3, data); - - flashDetection.setLuminance(irisRedFrame); - flashDetection.checkFrame(irisRedFrame, 4, data); - - FrameData expectedData; - expectedData.Frame = 0; - expectedData.LuminanceAverage = 0.2126f; - expectedData.LuminanceFlashArea = "100.00%"; - expectedData.AverageLuminanceDiff = -0.7874f; - expectedData.AverageLuminanceDiffAcc = -0.7874f; - expectedData.RedAverage = 320; - expectedData.RedFlashArea = "100.00%"; - expectedData.AverageRedDiff = 320; - expectedData.AverageRedDiffAcc = 320; - expectedData.LuminanceTransitions = 4; - expectedData.RedTransitions = 3; - expectedData.LuminanceExtendedFailCount = 1; - expectedData.RedExtendedFailCount = 0; - expectedData.luminanceFrameResult = FlashResult::PassWithWarning; - expectedData.redFrameResult = FlashResult::Pass; - - EXPECT_EQ(expectedData.LuminanceAverage, data.LuminanceAverage); - EXPECT_EQ(expectedData.LuminanceFlashArea, data.LuminanceFlashArea); - EXPECT_EQ(expectedData.AverageLuminanceDiff, data.AverageLuminanceDiff); - EXPECT_EQ(expectedData.AverageLuminanceDiffAcc, data.AverageLuminanceDiffAcc); - EXPECT_EQ(expectedData.RedAverage, data.RedAverage); - EXPECT_EQ(expectedData.RedFlashArea, data.RedFlashArea); - EXPECT_EQ(expectedData.AverageRedDiff, data.AverageRedDiff); - EXPECT_EQ(expectedData.AverageRedDiffAcc, data.AverageRedDiffAcc); - EXPECT_EQ(expectedData.LuminanceTransitions, data.LuminanceTransitions); - EXPECT_EQ(expectedData.RedTransitions, data.RedTransitions); - EXPECT_EQ(expectedData.LuminanceExtendedFailCount, data.LuminanceExtendedFailCount); - EXPECT_EQ(expectedData.RedExtendedFailCount, data.RedExtendedFailCount); - EXPECT_EQ(expectedData.luminanceFrameResult, data.luminanceFrameResult); - EXPECT_EQ(expectedData.redFrameResult, data.redFrameResult); - - EXPECT_FALSE(flashDetection.isFail()); - - irisBlackFrame.Release(); - irisRedFrame.Release(); - irisWhiteFrame.Release(); - } - TEST_F(FlashDetectionTests, CD_LUMINANCE) - { - configuration.SetLuminanceType(Configuration::LuminanceType::CD); - configuration.Init(); - - cv::Size size(100, 100); - - cv::Mat blackFrame(size, CV_8UC3, black); //lum = 0.07f - cv::Mat whiteFrame(size, CV_8UC3, white); //lum = 200f - cv::Mat redFrame(size, CV_8UC3, red); //lum = 015.93f - - FlashDetection flashDetection(&configuration, 7, size); - EA::EACC::Utils::FrameConverter sRgbConverter(configuration.GetFrameSrgbConverterParams()); - - FrameData data; - IrisFrame irisBlackFrame(&blackFrame, sRgbConverter.Convert(blackFrame), FrameData()); - IrisFrame irisWhiteFrame(&whiteFrame, sRgbConverter.Convert(whiteFrame), FrameData()); - IrisFrame irisRedFrame(&redFrame, sRgbConverter.Convert(redFrame), FrameData()); - - //add transitions - flashDetection.setLuminance(irisBlackFrame); - flashDetection.checkFrame(irisBlackFrame, 0, data); - - flashDetection.setLuminance(irisWhiteFrame); - flashDetection.checkFrame(irisWhiteFrame, 1, data); - - flashDetection.setLuminance(irisRedFrame); - flashDetection.checkFrame(irisRedFrame, 2, data); - - flashDetection.setLuminance(irisWhiteFrame); - flashDetection.checkFrame(irisWhiteFrame, 3, data); - - flashDetection.setLuminance(irisRedFrame); - flashDetection.checkFrame(irisRedFrame, 4, data); - - FrameData expectedData; - expectedData.Frame = 0; - expectedData.LuminanceAverage = 15.93f; - expectedData.LuminanceFlashArea = "100.00%"; - expectedData.AverageLuminanceDiff = -184.07f; - expectedData.AverageLuminanceDiffAcc = -184.07f; - expectedData.RedAverage = 320; - expectedData.RedFlashArea = "100.00%"; - expectedData.AverageRedDiff = 320; - expectedData.AverageRedDiffAcc = 320; - expectedData.LuminanceTransitions = 4; - expectedData.RedTransitions = 3; - expectedData.LuminanceExtendedFailCount = 1; - expectedData.RedExtendedFailCount = 0; - expectedData.luminanceFrameResult = FlashResult::PassWithWarning; - expectedData.redFrameResult = FlashResult::Pass; - - EXPECT_EQ(expectedData.LuminanceAverage, data.LuminanceAverage); - EXPECT_EQ(expectedData.LuminanceFlashArea, data.LuminanceFlashArea); - EXPECT_EQ(expectedData.AverageLuminanceDiff, data.AverageLuminanceDiff); - EXPECT_EQ(expectedData.AverageLuminanceDiffAcc, data.AverageLuminanceDiffAcc); - EXPECT_EQ(expectedData.RedAverage, data.RedAverage); - EXPECT_EQ(expectedData.RedFlashArea, data.RedFlashArea); - EXPECT_EQ(expectedData.AverageRedDiff, data.AverageRedDiff); - EXPECT_EQ(expectedData.AverageRedDiffAcc, data.AverageRedDiffAcc); - EXPECT_EQ(expectedData.LuminanceTransitions, data.LuminanceTransitions); - EXPECT_EQ(expectedData.RedTransitions, data.RedTransitions); - EXPECT_EQ(expectedData.LuminanceExtendedFailCount, data.LuminanceExtendedFailCount); - EXPECT_EQ(expectedData.RedExtendedFailCount, data.RedExtendedFailCount); - EXPECT_EQ(expectedData.luminanceFrameResult, data.luminanceFrameResult); - EXPECT_EQ(expectedData.redFrameResult, data.redFrameResult); - - EXPECT_FALSE(flashDetection.isFail()); - - irisBlackFrame.Release(); - irisRedFrame.Release(); - irisWhiteFrame.Release(); +class FlashDetectionTests : public IrisLibTest +{ +protected: + + void SetUp() override //call configuration loading per test to load different luminances + { + cv::utils::logging::setLogLevel(cv::utils::logging::LogLevel::LOG_LEVEL_ERROR); + iris::Log::Init(false, false); } + + ~FlashDetectionTests() override + { + } +}; + +TEST_F(FlashDetectionTests, RELATIVE_LUMINANCE) +{ + configuration.Init(); + FpsFrameManager frameManager{}; + + cv::Size size(100, 100); + + cv::Mat blackFrame(size, CV_8UC3, black); //lum = 0f + cv::Mat whiteFrame(size, CV_8UC3, white); //lum = 1f + cv::Mat redFrame(size, CV_8UC3, red); //lum = 0.2126f + + FlashDetection flashDetection(&configuration, 7, size, &frameManager); + EA::EACC::Utils::FrameConverter sRgbConverter(configuration.GetFrameSrgbConverterParams()); + + FrameData data; + IrisFrame irisBlackFrame(&blackFrame, sRgbConverter.Convert(blackFrame), FrameData()); + IrisFrame irisWhiteFrame(&whiteFrame, sRgbConverter.Convert(whiteFrame), FrameData()); + IrisFrame irisRedFrame(&redFrame, sRgbConverter.Convert(redFrame), FrameData()); + + //add transitions + flashDetection.setLuminance(irisBlackFrame); + flashDetection.checkFrame(irisBlackFrame, 0, data); + + flashDetection.setLuminance(irisWhiteFrame); + flashDetection.checkFrame(irisWhiteFrame, 1, data); + + flashDetection.setLuminance(irisRedFrame); + flashDetection.checkFrame(irisRedFrame, 2, data); + + flashDetection.setLuminance(irisWhiteFrame); + flashDetection.checkFrame(irisWhiteFrame, 3, data); + + flashDetection.setLuminance(irisRedFrame); + flashDetection.checkFrame(irisRedFrame, 4, data); + + FrameData expectedData; + expectedData.Frame = 0; + expectedData.LuminanceAverage = 0.2126f; + expectedData.LuminanceFlashArea = "100.00%"; + expectedData.AverageLuminanceDiff = -0.7874f; + expectedData.AverageLuminanceDiffAcc = -0.7874f; + expectedData.RedAverage = 320; + expectedData.RedFlashArea = "100.00%"; + expectedData.AverageRedDiff = 320; + expectedData.AverageRedDiffAcc = 320; + expectedData.LuminanceTransitions = 4; + expectedData.RedTransitions = 3; + expectedData.LuminanceExtendedFailCount = 1; + expectedData.RedExtendedFailCount = 0; + expectedData.luminanceFrameResult = FlashResult::PassWithWarning; + expectedData.redFrameResult = FlashResult::Pass; + + EXPECT_EQ(expectedData.LuminanceAverage, data.LuminanceAverage); + EXPECT_EQ(expectedData.LuminanceFlashArea, data.LuminanceFlashArea); + EXPECT_EQ(expectedData.AverageLuminanceDiff, data.AverageLuminanceDiff); + EXPECT_EQ(expectedData.AverageLuminanceDiffAcc, data.AverageLuminanceDiffAcc); + EXPECT_EQ(expectedData.RedAverage, data.RedAverage); + EXPECT_EQ(expectedData.RedFlashArea, data.RedFlashArea); + EXPECT_EQ(expectedData.AverageRedDiff, data.AverageRedDiff); + EXPECT_EQ(expectedData.AverageRedDiffAcc, data.AverageRedDiffAcc); + EXPECT_EQ(expectedData.LuminanceTransitions, data.LuminanceTransitions); + EXPECT_EQ(expectedData.RedTransitions, data.RedTransitions); + EXPECT_EQ(expectedData.LuminanceExtendedFailCount, data.LuminanceExtendedFailCount); + EXPECT_EQ(expectedData.RedExtendedFailCount, data.RedExtendedFailCount); + EXPECT_EQ(expectedData.luminanceFrameResult, data.luminanceFrameResult); + EXPECT_EQ(expectedData.redFrameResult, data.redFrameResult); + + EXPECT_FALSE(flashDetection.isFail()); + + irisBlackFrame.Release(); + irisRedFrame.Release(); + irisWhiteFrame.Release(); +} + +TEST_F(FlashDetectionTests, RealTime_RELATIVE_LUMINANCE) +{ + configuration.Init(); + configuration.SetAnalyseByTimeStatus(true); + TimeFrameManager frameManager{}; + + cv::Size size(100, 100); + + cv::Mat blackFrame(size, CV_8UC3, black); //lum = 0f + cv::Mat whiteFrame(size, CV_8UC3, white); //lum = 1f + cv::Mat redFrame(size, CV_8UC3, red); //lum = 0.2126f + + FlashDetection flashDetection(&configuration, 7, size, &frameManager); + EA::EACC::Utils::FrameConverter sRgbConverter(configuration.GetFrameSrgbConverterParams()); + + FrameData data; + IrisFrame irisBlackFrame(&blackFrame, sRgbConverter.Convert(blackFrame), FrameData()); + IrisFrame irisWhiteFrame(&whiteFrame, sRgbConverter.Convert(whiteFrame), FrameData()); + IrisFrame irisRedFrame(&redFrame, sRgbConverter.Convert(redFrame), FrameData()); + + //add transitions + frameManager.AddFrame(data); + flashDetection.setLuminance(irisBlackFrame); + flashDetection.checkFrame(irisBlackFrame, 0, data); + + frameManager.AddFrame(data); + flashDetection.setLuminance(irisWhiteFrame); + flashDetection.checkFrame(irisWhiteFrame, 1, data); + + frameManager.AddFrame(data); + flashDetection.setLuminance(irisRedFrame); + flashDetection.checkFrame(irisRedFrame, 2, data); + + frameManager.AddFrame(data); + flashDetection.setLuminance(irisWhiteFrame); + flashDetection.checkFrame(irisWhiteFrame, 3, data); + + frameManager.AddFrame(data); + flashDetection.setLuminance(irisRedFrame); + flashDetection.checkFrame(irisRedFrame, 4, data); + + FrameData expectedData; + expectedData.Frame = 0; + expectedData.LuminanceAverage = 0.2126f; + expectedData.LuminanceFlashArea = "100.00%"; + expectedData.AverageLuminanceDiff = -0.7874f; + expectedData.AverageLuminanceDiffAcc = -0.7874f; + expectedData.RedAverage = 320; + expectedData.RedFlashArea = "100.00%"; + expectedData.AverageRedDiff = 320; + expectedData.AverageRedDiffAcc = 320; + expectedData.LuminanceTransitions = 4; + expectedData.RedTransitions = 3; + expectedData.LuminanceExtendedFailCount = 1; + expectedData.RedExtendedFailCount = 0; + expectedData.luminanceFrameResult = FlashResult::PassWithWarning; + expectedData.redFrameResult = FlashResult::Pass; + + EXPECT_EQ(expectedData.LuminanceAverage, data.LuminanceAverage); + EXPECT_EQ(expectedData.LuminanceFlashArea, data.LuminanceFlashArea); + EXPECT_EQ(expectedData.AverageLuminanceDiff, data.AverageLuminanceDiff); + EXPECT_EQ(expectedData.AverageLuminanceDiffAcc, data.AverageLuminanceDiffAcc); + EXPECT_EQ(expectedData.RedAverage, data.RedAverage); + EXPECT_EQ(expectedData.RedFlashArea, data.RedFlashArea); + EXPECT_EQ(expectedData.AverageRedDiff, data.AverageRedDiff); + EXPECT_EQ(expectedData.AverageRedDiffAcc, data.AverageRedDiffAcc); + EXPECT_EQ(expectedData.LuminanceTransitions, data.LuminanceTransitions); + EXPECT_EQ(expectedData.RedTransitions, data.RedTransitions); + EXPECT_EQ(expectedData.LuminanceExtendedFailCount, data.LuminanceExtendedFailCount); + EXPECT_EQ(expectedData.RedExtendedFailCount, data.RedExtendedFailCount); + EXPECT_EQ(expectedData.luminanceFrameResult, data.luminanceFrameResult); + EXPECT_EQ(expectedData.redFrameResult, data.redFrameResult); + + EXPECT_FALSE(flashDetection.isFail()); + + irisBlackFrame.Release(); + irisRedFrame.Release(); + irisWhiteFrame.Release(); +} + } \ No newline at end of file diff --git a/test/Iris.Tests/src/FlashTest.cpp b/test/Iris.Tests/src/FlashTest.cpp index b39ae03..cef3647 100644 --- a/test/Iris.Tests/src/FlashTest.cpp +++ b/test/Iris.Tests/src/FlashTest.cpp @@ -5,6 +5,7 @@ #include "utils/FrameConverter.h" #include "Flash.h" #include +#include "FpsFrameManager.h" namespace iris::Tests { @@ -20,16 +21,12 @@ namespace iris::Tests } }; - class FlashWrapper : public Flash { - public: - FlashWrapper(const short& fps, const cv::Size& size, FlashParams* params) : Flash(fps, size, params) { - } - }; - TEST_F(FlashTest, Transition_Over_Dark_Threshold) { cv::Size size(1, 1); - Flash flash(5, size, configuration.GetLuminanceFlashParams()); + FpsFrameManager frameManager{}; + + Flash flash(5, size, configuration.GetLuminanceFlashParams(), &frameManager); cv::Mat frame(size, CV_32FC1, cv::Scalar(0.8f)); cv::Mat frame2(size, CV_32FC1, cv::Scalar(1.0f)); @@ -49,7 +46,8 @@ namespace iris::Tests TEST_F(FlashTest, Transition_Below_Dark_Threshold) { cv::Size size(1, 1); - Flash flash(5, size, configuration.GetLuminanceFlashParams()); + FpsFrameManager frameManager{}; + Flash flash(5, size, configuration.GetLuminanceFlashParams(), &frameManager); cv::Mat frame(size, CV_32FC1, cv::Scalar(0.6f)); cv::Mat frame2(size, CV_32FC1, cv::Scalar(1.0f)); @@ -69,8 +67,9 @@ namespace iris::Tests //Edge case test: when a flash transition occurrs but the value continues increasing/decreasing, no new transition is occurring TEST_F(FlashTest, CheckTransition_Same_Sign_Above_Threshold) { + FpsFrameManager frameManager{}; cv::Size size(1, 1); - Flash flash(2, size, configuration.GetLuminanceFlashParams()); + Flash flash(2, size, configuration.GetLuminanceFlashParams(), &frameManager); flash.CheckTransition(0.01f, 0.0f); flash.CheckTransition(0.09f, 0.01f); diff --git a/test/Iris.Tests/src/FrameManagerTests.cpp b/test/Iris.Tests/src/FrameManagerTests.cpp new file mode 100644 index 0000000..c09b555 --- /dev/null +++ b/test/Iris.Tests/src/FrameManagerTests.cpp @@ -0,0 +1,154 @@ +//Copyright (C) 2023 Electronic Arts, Inc. All rights reserved. + +#include "IrisLibTest.h" +#include +#include "TimeFrameManager.h" + +namespace iris::Tests +{ + class FrameManagerTest : public IrisLibTest + { + void SetUp() override + { + } + }; + + TEST_F(FrameManagerTest, Half_Second_Removal) + { + // (5 frames) + // 0 125 250 375 500 = frame entry time stamps + // |-----|-----|-----|-----| = time line + // 0 1 2 3 4 = frame index + // + // As no more frames can be added to the window, the first one must be removed. + // + // Final result (1 frame removed = number of elements to be removed from the relevant vectors): + // 125 250 375 500 = frame entry time stamps + // |-----|-----|-----| = time line + // 1 2 3 4 = frame index + + TimeFrameManager frameManager{}; + + FrameData data; + float timeBarrier = 0.5; //half a second window + int framesToAdd = 4; + + int index = frameManager.RegisterManager(0, timeBarrier); + float timeBetweenFrames = (timeBarrier * 1000.0) / framesToAdd; // 500 / 4 = 125 ms + + //frame 0 + frameManager.AddFrame(data); + + //fill out with 4 new frames + for (int i = 0; i < framesToAdd; i++) + { + data.TimeStampVal += timeBetweenFrames; + frameManager.AddFrame(data); + } + + EXPECT_EQ(framesToAdd, frameManager.GetCurrentFrameNum(index)); + EXPECT_EQ(1, frameManager.GetFramesToRemove(index)); + + } + + TEST_F(FrameManagerTest, Frame_Drop) + { + // A. (5 Frames) + // 0 250 500 750 1750 = frame entry time stamps + // |-----|-----|-----|---------------| = time line + // 0 1 2 3 4 = frame index + // + // As the last frames is as big as the window, all frames have to be removed, except for the last one. + // + // Frame drop result (4 frames removed = number of elements to be removed from the relevant vectors): + // 1750 = frame entry time stamps + // |--- = time line + // 4 = frame index + // + // B. Then 4 frames are added to fill the window and test the correct functionality after a frame drop + // + // Final result (1 frame removed = number of elements to be removed from the relevant vectors): + // 2000 2250 2500 2750 = frame entry time stamps + // |-----|-----|-----| = time line + // 5 6 7 8 = frame index + + TimeFrameManager frameManager{}; + + FrameData data; + float timeBarrier = 1.0; //one second window + + int index = frameManager.RegisterManager(0, timeBarrier); + float timeBetweenFrames = 250.0; + + //A. + //frame 0 + frameManager.AddFrame(data); + + //3 new frames + for (int i = 0; i < 3; i++) + { + data.TimeStampVal += timeBetweenFrames; + frameManager.AddFrame(data); + } + + //1sec frame drop + data.TimeStampVal += 1000; + frameManager.AddFrame(data); + + EXPECT_EQ(1, frameManager.GetCurrentFrameNum(index)); + EXPECT_EQ(4, frameManager.GetFramesToRemove(index)); + + //B. fill out with 4 new frames + for (int i = 0; i < 4; i++) + { + data.TimeStampVal += timeBetweenFrames; + frameManager.AddFrame(data); + } + + EXPECT_EQ(4, frameManager.GetCurrentFrameNum(index)); + EXPECT_EQ(1, frameManager.GetFramesToRemove(index)); + } + + TEST_F(FrameManagerTest, Reset_Window) + { + // A. (4 frames) + // 0 125 250 375 = frame entry time stamps + // |-----|-----|-----| = time line + // 0 1 2 3 = frame index + // + // B. Window reset + // + // Result after reset: + // 375 = frame entry time stamps + // |--- = time line + // 4 = frame index + + TimeFrameManager frameManager{}; + + FrameData data; + float timeBarrier = 0.5; //half a second window + int framesToAdd = 3; + + int index = frameManager.RegisterManager(0, timeBarrier); + float timeBetweenFrames = 250; + + //A. + //frame 0 + frameManager.AddFrame(data); + + //fill out with 4 new frames + for (int i = 0; i < framesToAdd; i++) + { + data.TimeStampVal += timeBetweenFrames; + frameManager.AddFrame(data); + } + + //B. Window reset + frameManager.ResetManager(index); + + EXPECT_EQ(1, frameManager.GetCurrentFrameNum(index)); + EXPECT_EQ(0, frameManager.GetFramesToRemove(index)); + + } + +} \ No newline at end of file diff --git a/test/Iris.Tests/src/PatternDetectionTests.cpp b/test/Iris.Tests/src/PatternDetectionTests.cpp index 15c747c..85ae847 100644 --- a/test/Iris.Tests/src/PatternDetectionTests.cpp +++ b/test/Iris.Tests/src/PatternDetectionTests.cpp @@ -7,67 +7,119 @@ #include "IrisFrame.h" #include "utils/FrameConverter.h" #include "iris/TotalFlashIncidents.h" +#include "FpsFrameManager.h" +#include "TimeFrameManager.h" namespace iris::Tests { - class PatternDetectionTests : public IrisLibTest { - protected: - EA::EACC::Utils::FrameConverter* frameRgbConverter = nullptr; - void SetUp() override { - configuration.SetLuminanceType(Configuration::LuminanceType::RELATIVE); - IrisLibTest::SetUp(); - - frameRgbConverter = new EA::EACC::Utils::FrameConverter(configuration.GetFrameSrgbConverterParams()); - } - - ~PatternDetectionTests() - { - if (frameRgbConverter != nullptr) - { - delete frameRgbConverter; - } - } - }; - - TEST_F(PatternDetectionTests, NoPattern_Pass) +class PatternDetectionTests : public IrisLibTest +{ +protected: + EA::EACC::Utils::FrameConverter* frameRgbConverter = nullptr; + + void SetUp() override { - cv::Mat image = cv::imread("data/TestImages/Patterns/shapes.png"); - IrisFrame irisFrame(&image, frameRgbConverter->Convert(image), FrameData()); + IrisLibTest::SetUp(); + + frameRgbConverter = new EA::EACC::Utils::FrameConverter(configuration.GetFrameSrgbConverterParams()); + } + + ~PatternDetectionTests() + { + delete frameRgbConverter; + } +}; + +TEST_F(PatternDetectionTests, NoPattern_Pass) +{ + cv::Mat image = cv::imread("data/TestImages/Patterns/shapes.png"); + IrisFrame irisFrame(&image, frameRgbConverter->Convert(image), FrameData()); + FpsFrameManager frameManager{}; + + FlashDetection flashDetection(&configuration, 0, image.size(), &frameManager); + PatternDetection patternDetection(&configuration, 5, image.size(), &frameManager); + flashDetection.setLuminance(irisFrame); + + FrameData data; + for (int i = 0; i < 5; i++) + { + frameManager.AddFrame(data); + patternDetection.checkFrame(irisFrame, i, data); + } - FlashDetection flashDetection(&configuration, 0, image.size()); - PatternDetection patternDetection(&configuration, 5, image.size()); - flashDetection.setLuminance(irisFrame); + EXPECT_EQ(PatternResult::Pass, data.patternFrameResult); - FrameData data; - for (int i = 0; i < 5; i++) - { - patternDetection.checkFrame(irisFrame, i, data); - } + irisFrame.Release(); +} - EXPECT_EQ(PatternResult::Pass, data.patternFrameResult); - irisFrame.Release(); +TEST_F(PatternDetectionTests, Straight_Lines_Fail) +{ + cv::Mat image = cv::imread("data/TestImages/Patterns/20stripes.png"); + IrisFrame irisFrame(&image, frameRgbConverter->Convert(image), FrameData()); + FpsFrameManager frameManager{}; + + FlashDetection flashDetection(&configuration, 0, image.size(), &frameManager); + PatternDetection patternDetection(&configuration, 5, image.size(), &frameManager); + flashDetection.setLuminance(irisFrame); + + FrameData data; + for (int i = 0; i < 5; i++) + { + frameManager.AddFrame(data); + patternDetection.checkFrame(irisFrame, i, data); } + EXPECT_EQ(PatternResult::Fail, data.patternFrameResult); - TEST_F(PatternDetectionTests, Straight_Lines_Fail) + irisFrame.Release(); +} + +TEST_F(PatternDetectionTests, RealTime_NoPattern_Pass) +{ + cv::Mat image = cv::imread("data/TestImages/Patterns/shapes.png"); + IrisFrame irisFrame(&image, frameRgbConverter->Convert(image), FrameData()); + TimeFrameManager frameManager{}; + + FlashDetection flashDetection(&configuration, 0, image.size(), &frameManager); + PatternDetection patternDetection(&configuration, 5, image.size(), &frameManager); + flashDetection.setLuminance(irisFrame); + + FrameData data; + for (int i = 0; i < 5; i++) { - cv::Mat image = cv::imread("data/TestImages/Patterns/20stripes.png"); - IrisFrame irisFrame(&image, frameRgbConverter->Convert(image), FrameData()); + frameManager.AddFrame(data); + patternDetection.checkFrame(irisFrame, i, data); + data.TimeStampVal += 250; + } - FlashDetection flashDetection(&configuration, 0, image.size()); - PatternDetection patternDetection(&configuration, 5, image.size()); - flashDetection.setLuminance(irisFrame); + EXPECT_EQ(PatternResult::Pass, data.patternFrameResult); - FrameData data; - for (int i = 0; i < 5; i++) - { - patternDetection.checkFrame(irisFrame, i, data); - } + irisFrame.Release(); +} - EXPECT_EQ(PatternResult::Fail, data.patternFrameResult); - irisFrame.Release(); +TEST_F(PatternDetectionTests, RealTime_Straight_Lines_Fail) +{ + cv::Mat image = cv::imread("data/TestImages/Patterns/20stripes.png"); + IrisFrame irisFrame(&image, frameRgbConverter->Convert(image), FrameData()); + TimeFrameManager frameManager{}; + + FlashDetection flashDetection(&configuration, 0, image.size(), &frameManager); + PatternDetection patternDetection(&configuration, 5, image.size(), &frameManager); + flashDetection.setLuminance(irisFrame); + + FrameData data; + for (int i = 0; i < 5; i++) + { + frameManager.AddFrame(data); + patternDetection.checkFrame(irisFrame, i, data); + data.TimeStampVal += 250; } + EXPECT_EQ(PatternResult::Fail, data.patternFrameResult); + + irisFrame.Release(); +} + } \ No newline at end of file diff --git a/test/Iris.Tests/src/RedSaturationTests.cpp b/test/Iris.Tests/src/RedSaturationTests.cpp index 2102fb9..0d8637b 100644 --- a/test/Iris.Tests/src/RedSaturationTests.cpp +++ b/test/Iris.Tests/src/RedSaturationTests.cpp @@ -5,26 +5,38 @@ #include "RedSaturation.h" #include "IrisLibTest.h" #include +#include "FpsFrameManager.h" namespace iris::Tests { class RedSaturationTests : public IrisLibTest { protected: EA::EACC::Utils::FrameConverter* frameRgbConverter = nullptr; + IFrameManager* frameManager; + cv::Size size{ 100, 100 }; - void SetUp() override { + void SetUp() override + { IrisLibTest::SetUp(); frameRgbConverter = new EA::EACC::Utils::FrameConverter(configuration.GetFrameSrgbConverterParams()); + frameManager = new FpsFrameManager(); } - ~RedSaturationTests() override { + + RedSaturation GetRedSaturation(short fps, cv::Size size = {100, 100}) + { + return RedSaturation(fps, size, configuration.GetRedSaturationFlashParams(), frameManager); + } + + ~RedSaturationTests() override + { delete frameRgbConverter; + delete frameManager; } }; TEST_F(RedSaturationTests, Positive_FrameDifference) { - cv::Size size(100, 100); - RedSaturation redSaturation(0, size, configuration.GetRedSaturationFlashParams()); + RedSaturation redSaturation = GetRedSaturation(0); cv::Mat redImageBgr(size, CV_8UC3, red); cv::Mat* pRedSrgb = frameRgbConverter->Convert(redImageBgr); @@ -51,8 +63,7 @@ namespace iris::Tests TEST_F(RedSaturationTests, Negative_FrameDifference) { - cv::Size size(2000, 2000); - RedSaturation redSaturation(0, size, configuration.GetRedSaturationFlashParams()); + RedSaturation redSaturation = GetRedSaturation(0); cv::Mat redImageBgr(size, CV_8UC3, red); cv::Mat* pRedSrgb = frameRgbConverter->Convert(redImageBgr); @@ -79,8 +90,7 @@ namespace iris::Tests TEST_F(RedSaturationTests, Positive_FrameDifference_PartialRed) { - cv::Size size(100, 100); - RedSaturation redSaturation(0, size, configuration.GetRedSaturationFlashParams()); + RedSaturation redSaturation = GetRedSaturation(0); cv::Mat blackImageBgr(size, CV_8UC3, black); cv::Mat* pBlackSrgb = frameRgbConverter->Convert(blackImageBgr); @@ -111,8 +121,7 @@ namespace iris::Tests TEST_F(RedSaturationTests, Negative_FrameDifference_PartialRed) { - cv::Size size(100, 100); - RedSaturation redSaturation(0, size, configuration.GetRedSaturationFlashParams()); + RedSaturation redSaturation = GetRedSaturation(0); cv::Mat blackImageBgr(size, CV_8UC3, black); cv::Mat* pBlackSrgb = frameRgbConverter->Convert(blackImageBgr); @@ -144,12 +153,11 @@ namespace iris::Tests TEST_F(RedSaturationTests, CheckTransition_Positive_Value_To_Zero) { - RedSaturation redSaturation (5, cv::Size(), configuration.GetRedSaturationFlashParams()); + RedSaturation redSaturation = GetRedSaturation(5); float testLastAvg = 5.2f; //SameSign (positive) 0 case && !newTransition - Flash::CheckTransitionResult transitionResult = redSaturation.CheckTransition(0, testLastAvg); EXPECT_EQ(5.2f, transitionResult.lastAvgDiffAcc); @@ -158,13 +166,11 @@ namespace iris::Tests TEST_F(RedSaturationTests, CheckTransition_Positive_Value_Increment_NoTransition) { - RedSaturation redSaturation(5, cv::Size(), configuration.GetRedSaturationFlashParams()); - + RedSaturation redSaturation = GetRedSaturation(5); float testLastAvg = 5.2f; //SameSign (positive) && !newTransition - Flash::CheckTransitionResult transitionResult = redSaturation.CheckTransition(10.0f, testLastAvg); EXPECT_EQ(15.2f, transitionResult.lastAvgDiffAcc); @@ -173,13 +179,11 @@ namespace iris::Tests TEST_F(RedSaturationTests, CheckTransition_Positive_Value_Increment_Transition) { - RedSaturation redSaturation(5, cv::Size(), configuration.GetRedSaturationFlashParams()); - + RedSaturation redSaturation = GetRedSaturation(5); float testLastAvg = 15.2f; //SameSign (positive) && newTransition - Flash::CheckTransitionResult transitionResult = redSaturation.CheckTransition(5.0f, testLastAvg); EXPECT_EQ(20.2f, transitionResult.lastAvgDiffAcc); @@ -188,13 +192,11 @@ namespace iris::Tests TEST_F(RedSaturationTests, CheckTransition_Positive_Value_Decrement_NoTransition) { - RedSaturation redSaturation(5, cv::Size(), configuration.GetRedSaturationFlashParams()); - + RedSaturation redSaturation = GetRedSaturation(5); float testLastAvg = 20.2f; //SameSign (positive) && !newTransition (last was a transition) - Flash::CheckTransitionResult transitionResult = redSaturation.CheckTransition(10.3f, testLastAvg); EXPECT_EQ(30.5f, transitionResult.lastAvgDiffAcc); @@ -203,13 +205,11 @@ namespace iris::Tests TEST_F(RedSaturationTests, CheckTransition_ToNegative_Transition) { - RedSaturation redSaturation(5, cv::Size(), configuration.GetRedSaturationFlashParams()); - + RedSaturation redSaturation = GetRedSaturation(5); float testLastAvg = 30.5f; //!SameSign (negative) && newTransition - Flash::CheckTransitionResult transitionResult = redSaturation.CheckTransition(-20.0f, testLastAvg); EXPECT_EQ(-20.0f, transitionResult.lastAvgDiffAcc); @@ -218,13 +218,11 @@ namespace iris::Tests TEST_F(RedSaturationTests, CheckTransition_ToPositive_NoTransition) { - RedSaturation redSaturation(5, cv::Size(), configuration.GetRedSaturationFlashParams()); - + RedSaturation redSaturation = GetRedSaturation(5); float testLastAvg = -20.0f; //SameSign (positive) && !newTransition (last was a transition) - Flash::CheckTransitionResult transitionResult = redSaturation.CheckTransition(25.0f, testLastAvg); EXPECT_EQ(25.0f, transitionResult.lastAvgDiffAcc); @@ -233,13 +231,11 @@ namespace iris::Tests TEST_F(RedSaturationTests, CheckTransition_ToNegative_NoTransition) { - RedSaturation redSaturation(5, cv::Size(), configuration.GetRedSaturationFlashParams()); + RedSaturation redSaturation = GetRedSaturation(5); - float testLastAvg = 25.0f; //!SameSign (negative) && !newTransition - Flash::CheckTransitionResult transitionResult = redSaturation.CheckTransition(-10.0f, testLastAvg); EXPECT_EQ(-10.0f, transitionResult.lastAvgDiffAcc); @@ -248,13 +244,11 @@ namespace iris::Tests TEST_F(RedSaturationTests, CheckTransition_Negative_Value_To_Zero) { - RedSaturation redSaturation(5, cv::Size(), configuration.GetRedSaturationFlashParams()); + RedSaturation redSaturation = GetRedSaturation(5); - float testLastAvg = -10.0f; //SameSign (negative) 0 case && !newTransition - Flash::CheckTransitionResult transitionResult = redSaturation.CheckTransition(0.0f, testLastAvg); EXPECT_EQ(-10.0f, transitionResult.lastAvgDiffAcc); @@ -263,7 +257,7 @@ namespace iris::Tests TEST_F(RedSaturationTests, CheckTransition_Negative_Value_Decrement_Transition) { - RedSaturation redSaturation(5, cv::Size(), configuration.GetRedSaturationFlashParams()); + RedSaturation redSaturation = GetRedSaturation(5); float testLastAvg = -10.0f; @@ -276,13 +270,11 @@ namespace iris::Tests TEST_F(RedSaturationTests, CheckTransition_Negative_Value_Decrement_NoTransition) { - RedSaturation redSaturation(5, cv::Size(), configuration.GetRedSaturationFlashParams()); - + RedSaturation redSaturation = GetRedSaturation(5); float testLastAvg = -25.0f; //SameSign (negative) && !newTransition (last was a transition) - Flash::CheckTransitionResult transitionResult = redSaturation.CheckTransition(-30.6f, testLastAvg); EXPECT_EQ(-55.6f, transitionResult.lastAvgDiffAcc); @@ -291,14 +283,20 @@ namespace iris::Tests TEST_F(RedSaturationTests, CheckTransition_Negative_Decrements_NoTransition) { - RedSaturation redSaturation(2, cv::Size(), configuration.GetRedSaturationFlashParams()); + RedSaturation redSaturation = GetRedSaturation(2); + frameManager->AddFrame(FrameData{}); float testLastAvg = 0.0f; //SameSign (negative) && !newTransition (last was a transition) - + frameManager->AddFrame(FrameData{}); Flash::CheckTransitionResult transitionResult = redSaturation.CheckTransition(-25.6f, testLastAvg); + + + frameManager->AddFrame(FrameData{}); transitionResult = redSaturation.CheckTransition(-30.6f, transitionResult.lastAvgDiffAcc); + + frameManager->AddFrame(FrameData{}); transitionResult = redSaturation.CheckTransition(-10.6f, transitionResult.lastAvgDiffAcc); EXPECT_EQ(-41.2f, transitionResult.lastAvgDiffAcc); @@ -308,7 +306,7 @@ namespace iris::Tests TEST_F(RedSaturationTests, SafeArea_No_Change_Threshold) { cv::Size size(5, 5); - RedSaturation redSaturation(3, size, configuration.GetRedSaturationFlashParams()); + RedSaturation redSaturation = GetRedSaturation(3, size); cv::Mat imageBgr(size, CV_8UC3, red); cv::Mat* imageSbgr = frameRgbConverter->Convert(imageBgr); @@ -340,7 +338,7 @@ namespace iris::Tests }; cv::Mat frameDiff = cv::Mat(size, CV_32FC1, &frameDiffArray); - RedSaturation redSaturation(3, size, configuration.GetRedSaturationFlashParams()); + RedSaturation redSaturation = GetRedSaturation(3, size); cv::Mat imageBgr(size, CV_8UC3, blue); cv::Mat* imageSbgr = frameRgbConverter->Convert(imageBgr); @@ -363,7 +361,7 @@ namespace iris::Tests TEST_F(RedSaturationTests, SafeArea_100_Percent_Change_Threshold) { cv::Size size(5, 5); - RedSaturation redSaturation(3, size, configuration.GetRedSaturationFlashParams()); + RedSaturation redSaturation = GetRedSaturation(3, size); cv::Mat imageBgr(size, CV_8UC3, blue); cv::Mat* imageSbgr = frameRgbConverter->Convert(imageBgr); diff --git a/test/Iris.Tests/src/RelativeLuminanceTest.cpp b/test/Iris.Tests/src/RelativeLuminanceTest.cpp index 2a7a710..cf635cf 100644 --- a/test/Iris.Tests/src/RelativeLuminanceTest.cpp +++ b/test/Iris.Tests/src/RelativeLuminanceTest.cpp @@ -7,26 +7,38 @@ #include "RelativeLuminance.h" #include "IrisFrame.h" #include +#include "FpsFrameManager.h" namespace iris::Tests { class RelativeLuminanceTest : public IrisLibTest { protected: EA::EACC::Utils::FrameConverter* frameRgbConverter = nullptr; - void SetUp() override { - configuration.SetLuminanceType(Configuration::LuminanceType::RELATIVE); + IFrameManager* frameManager = nullptr; + cv::Size size = { 1280, 720 }; + + void SetUp() override + { IrisLibTest::SetUp(); frameRgbConverter = new EA::EACC::Utils::FrameConverter(configuration.GetFrameSrgbConverterParams()); + frameManager = new FpsFrameManager(); + } + + RelativeLuminance GetLuminance(short fps, cv::Size size = { 1280, 720 }) + { + return RelativeLuminance(fps, size, configuration.GetLuminanceFlashParams(), frameManager); } - ~RelativeLuminanceTest() override { + + ~RelativeLuminanceTest() override + { delete frameRgbConverter; + delete frameManager; } }; TEST_F(RelativeLuminanceTest, Luminance_When_WhiteFrame_Test) { - cv::Size size(1280, 720); - RelativeLuminance relativeLuminance(3, size, configuration.GetLuminanceFlashParams()); + RelativeLuminance relativeLuminance = GetLuminance(3); cv::Mat imageBgr(size, CV_8UC3, white); IrisFrame imagesRgb; @@ -42,8 +54,7 @@ namespace iris::Tests TEST_F(RelativeLuminanceTest, Luminance_WhenBlackFrame_Test) { - cv::Size size(1280, 720); - RelativeLuminance relativeLuminance(3, size, configuration.GetLuminanceFlashParams()); + RelativeLuminance relativeLuminance = GetLuminance(3); cv::Mat imageBgr(size, CV_8UC3, black); IrisFrame imagesRgb; @@ -59,8 +70,7 @@ namespace iris::Tests TEST_F(RelativeLuminanceTest, Luminance_When_GrayFrame_Test) { - cv::Size size(1280, 720); - RelativeLuminance relativeLuminance(3, size, configuration.GetLuminanceFlashParams()); + RelativeLuminance relativeLuminance = GetLuminance(3); cv::Mat imageBgr(size, CV_8UC3, gray); IrisFrame imagesRgb; @@ -77,8 +87,7 @@ namespace iris::Tests TEST_F(RelativeLuminanceTest, Luminance_When_BlueFrame_Test) { - cv::Size size(1280, 720); - RelativeLuminance relativeLuminance(3, size, configuration.GetLuminanceFlashParams()); + RelativeLuminance relativeLuminance = GetLuminance(3); cv::Mat imageBgr(size, CV_8UC3, blue); IrisFrame imagesRgb; @@ -95,8 +104,7 @@ namespace iris::Tests TEST_F(RelativeLuminanceTest, TransitionBlackWhite_FrameDifference_Test) { - cv::Size size(1280, 720); - RelativeLuminance relativeLuminance(3, size, configuration.GetLuminanceFlashParams()); + RelativeLuminance relativeLuminance = GetLuminance(3); cv::Mat imageWhiteBgr(size, CV_8UC3, white); IrisFrame pImageWhitesRgb; pImageWhitesRgb.sRgbFrame = frameRgbConverter->Convert(imageWhiteBgr); @@ -117,8 +125,7 @@ namespace iris::Tests TEST_F(RelativeLuminanceTest, TransitionWhiteBlack_FrameDifference_Test) { - cv::Size size(1280, 720); - RelativeLuminance relativeLuminance(3, size, configuration.GetLuminanceFlashParams()); + RelativeLuminance relativeLuminance = GetLuminance(3); cv::Mat imageWhiteBgr(size, CV_8UC3, white); IrisFrame pImageWhitesRgb; pImageWhitesRgb.sRgbFrame = frameRgbConverter->Convert(imageWhiteBgr); @@ -139,8 +146,7 @@ namespace iris::Tests TEST_F(RelativeLuminanceTest, TransitionWhiteBlackBlack_FrameDifference_Test) { - cv::Size size(1280, 720); - RelativeLuminance relativeLuminance(3, size, configuration.GetLuminanceFlashParams()); + RelativeLuminance relativeLuminance = GetLuminance(3); cv::Mat imageWhiteBgr(size, CV_8UC3, white); IrisFrame pImageWhitesRgb; pImageWhitesRgb.sRgbFrame = frameRgbConverter->Convert(imageWhiteBgr); @@ -162,7 +168,7 @@ namespace iris::Tests TEST_F(RelativeLuminanceTest,CheckTransition_WhenFalse_From_value_to_zero_Test) { - RelativeLuminance relativeLuminance(5, cv::Size(), configuration.GetLuminanceFlashParams()); + RelativeLuminance relativeLuminance = GetLuminance(5); float testLastAvg = 0.02f; //SameSign (positive) 0 case && !newTransition @@ -174,7 +180,7 @@ namespace iris::Tests TEST_F(RelativeLuminanceTest, CheckTransition_WhenFalse_From_value_to_value_Test) { - RelativeLuminance relativeLuminance(5, cv::Size(), configuration.GetLuminanceFlashParams()); + RelativeLuminance relativeLuminance = GetLuminance(5); float testLastAvg = 0.02f; //SameSign (positive) 0 case && !newTransition @@ -186,7 +192,7 @@ namespace iris::Tests TEST_F(RelativeLuminanceTest, CheckTransition_WhenTrue_From_value_to_value_Test) { - RelativeLuminance relativeLuminance(5, cv::Size(), configuration.GetLuminanceFlashParams()); + RelativeLuminance relativeLuminance = GetLuminance(5); float testLastAvg = 0.07f; //SameSign (positive) 0 case && !newTransition @@ -198,7 +204,7 @@ namespace iris::Tests TEST_F(RelativeLuminanceTest, CheckTransition_WhenFalse_From_threshold_value_to_value_Test) { - RelativeLuminance relativeLuminance(5, cv::Size(), configuration.GetLuminanceFlashParams()); + RelativeLuminance relativeLuminance = GetLuminance(5); float testLastAvg = 0.1f; //SameSign (positive) 0 case && !newTransition @@ -210,7 +216,7 @@ namespace iris::Tests TEST_F(RelativeLuminanceTest, CheckTransition_WhenTrue_From_value_to_negative_value_Test) { - RelativeLuminance relativeLuminance(5, cv::Size(), configuration.GetLuminanceFlashParams()); + RelativeLuminance relativeLuminance = GetLuminance(5); float testLastAvg = 0.2f; //SameSign (positive) 0 case && !newTransition @@ -222,7 +228,7 @@ namespace iris::Tests TEST_F(RelativeLuminanceTest, CheckTransition_WhenTrue_From_negative_value_to_value_Test) { - RelativeLuminance relativeLuminance(5, cv::Size(), configuration.GetLuminanceFlashParams()); + RelativeLuminance relativeLuminance = GetLuminance(5); float testLastAvg = -0.1f; //SameSign (positive) 0 case && !newTransition @@ -234,7 +240,7 @@ namespace iris::Tests TEST_F(RelativeLuminanceTest, CheckTransition_WhenFalse_From_value_to_negative_value_Test) { - RelativeLuminance relativeLuminance(5, cv::Size(), configuration.GetLuminanceFlashParams()); + RelativeLuminance relativeLuminance = GetLuminance(5); float testLastAvg = 0.1f; //SameSign (positive) 0 case && !newTransition @@ -246,7 +252,7 @@ namespace iris::Tests TEST_F(RelativeLuminanceTest, CheckTransition_WhenFalse_From_negative_value_to_zero_Test) { - RelativeLuminance relativeLuminance(5, cv::Size(), configuration.GetLuminanceFlashParams()); + RelativeLuminance relativeLuminance = GetLuminance(5); float testLastAvg = -0.05f; //SameSign (positive) 0 case && !newTransition @@ -258,7 +264,7 @@ namespace iris::Tests TEST_F(RelativeLuminanceTest, CheckTransition_WhenTrue_From_negative_value_to_negative_value_Test) { - RelativeLuminance relativeLuminance(5, cv::Size(), configuration.GetLuminanceFlashParams()); + RelativeLuminance relativeLuminance = GetLuminance(5); float testLastAvg = -0.05f; //SameSign (positive) 0 case && !newTransition @@ -270,7 +276,7 @@ namespace iris::Tests TEST_F(RelativeLuminanceTest, CheckTransition_WhenFalse_From_negative_threshold_value_to_negative_value_Test) { - RelativeLuminance relativeLuminance(5, cv::Size(), configuration.GetLuminanceFlashParams()); + RelativeLuminance relativeLuminance = GetLuminance(5); float testLastAvg = -0.11f; //SameSign (positive) 0 case && !newTransition @@ -282,24 +288,31 @@ namespace iris::Tests TEST_F(RelativeLuminanceTest, CheckTransition_WhenFalse_From_zero_to_negative_threshold_value_to_negative_threshold_value_Test) { - RelativeLuminance relativeLuminance(2, cv::Size(), configuration.GetLuminanceFlashParams()); + RelativeLuminance relativeLuminance = GetLuminance(2); + + frameManager->AddFrame(FrameData{}); float testLastAvg = 0; //SameSign (positive) 0 case && !newTransition + frameManager->AddFrame(FrameData{}); Flash::CheckTransitionResult transitionResult = relativeLuminance.CheckTransition(-0.11f, testLastAvg); testLastAvg = transitionResult.lastAvgDiffAcc; + + frameManager->AddFrame(FrameData{}); transitionResult = relativeLuminance.CheckTransition(-0.1f, testLastAvg); testLastAvg = transitionResult.lastAvgDiffAcc; + + frameManager->AddFrame(FrameData{}); transitionResult = relativeLuminance.CheckTransition(-0.1f, testLastAvg); EXPECT_FALSE(transitionResult.checkResult); EXPECT_EQ(-0.2f, Flash::roundoff(transitionResult.lastAvgDiffAcc, 2)); } - TEST_F(RelativeLuminanceTest, AverageLuminanca_WhenWhite_Test) + TEST_F(RelativeLuminanceTest, AverageLuminance_WhenWhite_Test) { - RelativeLuminance relativeLuminance(3, cv::Size(), configuration.GetLuminanceFlashParams()); - cv::Mat imageWhiteBgr(1280, 720, CV_8UC3, white); + RelativeLuminance relativeLuminance= GetLuminance(3); + cv::Mat imageWhiteBgr(size, CV_8UC3, white); IrisFrame pImageWhitesRgb; pImageWhitesRgb.sRgbFrame = frameRgbConverter->Convert(imageWhiteBgr); @@ -310,10 +323,10 @@ namespace iris::Tests pImageWhitesRgb.Release(); } - TEST_F(RelativeLuminanceTest, AverageLuminanca_WhenGray_Test) + TEST_F(RelativeLuminanceTest, AverageLuminance_WhenGray_Test) { - RelativeLuminance relativeLuminance(3, cv::Size(), configuration.GetLuminanceFlashParams()); - cv::Mat imageWhiteBgr(1280, 720, CV_8UC3, gray); + RelativeLuminance relativeLuminance = GetLuminance(3); + cv::Mat imageWhiteBgr(size, CV_8UC3, gray); IrisFrame pImageWhitesRgb; pImageWhitesRgb.sRgbFrame = frameRgbConverter->Convert(imageWhiteBgr); @@ -324,9 +337,9 @@ namespace iris::Tests pImageWhitesRgb.Release(); } - TEST_F(RelativeLuminanceTest, AverageLuminanca_WhenRealFrame_Test) + TEST_F(RelativeLuminanceTest, AverageLuminance_WhenRealFrame_Test) { - RelativeLuminance relativeLuminance(3, cv::Size(), configuration.GetLuminanceFlashParams()); + RelativeLuminance relativeLuminance = GetLuminance(3); cv::Mat frameBgr = cv::imread("data/TestImages/frames/FrameForTest.jpg"); IrisFrame pFramesRgb; pFramesRgb.sRgbFrame = frameRgbConverter->Convert(frameBgr); @@ -340,10 +353,10 @@ namespace iris::Tests TEST_F(RelativeLuminanceTest, SafeArea_No_Change_Threshold) { - cv::Size size(5, 5); - RelativeLuminance luminance(3, size, configuration.GetLuminanceFlashParams()); + cv::Size testSize(5, 5); + RelativeLuminance luminance = GetLuminance(3, testSize); - cv::Mat imageBgr(size, CV_8UC3, blue); + cv::Mat imageBgr(testSize, CV_8UC3, blue); cv::Mat* imageSbgr = frameRgbConverter->Convert(imageBgr); luminance.SetCurrentFrame(imageSbgr); @@ -362,7 +375,7 @@ namespace iris::Tests TEST_F(RelativeLuminanceTest, SafeArea_20_Percent_Change_Threshold) { - cv::Size size(5, 5); + cv::Size testSize(5, 5); float frameDiffArray[5][5] = { { 200, 200, 200, 0, 0 }, @@ -371,15 +384,15 @@ namespace iris::Tests { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } }; - cv::Mat frameDiff = cv::Mat(size, CV_32FC1, &frameDiffArray); + cv::Mat frameDiff = cv::Mat(testSize, CV_32FC1, &frameDiffArray); - RelativeLuminance luminance(3, size, configuration.GetLuminanceFlashParams()); + RelativeLuminance luminance = GetLuminance(3, testSize); - cv::Mat imageBgr(size, CV_8UC3, blue); + cv::Mat imageBgr(testSize, CV_8UC3, blue); cv::Mat* imageSbgr = frameRgbConverter->Convert(imageBgr); luminance.SetCurrentFrame(imageSbgr); - cv::Mat imageBgr2(size, CV_8UC3, white); + cv::Mat imageBgr2(testSize, CV_8UC3, white); cv::Mat* imageSbgr2 = frameRgbConverter->Convert(imageBgr2); luminance.SetCurrentFrame(imageSbgr2); @@ -395,14 +408,14 @@ namespace iris::Tests TEST_F(RelativeLuminanceTest, SafeArea_100_Percent_Change_Threshold) { - cv::Size size(5, 5); - RelativeLuminance luminance(3, size, configuration.GetLuminanceFlashParams()); + cv::Size testSize(5, 5); + RelativeLuminance luminance = GetLuminance(3, testSize); - cv::Mat imageBgr(size, CV_8UC3, blue); + cv::Mat imageBgr(testSize, CV_8UC3, blue); cv::Mat* imageSbgr = frameRgbConverter->Convert(imageBgr); luminance.SetCurrentFrame(imageSbgr); - cv::Mat imageBgr2(size, CV_8UC3, white); + cv::Mat imageBgr2(testSize, CV_8UC3, white); cv::Mat* imageSbgr2 = frameRgbConverter->Convert(imageBgr2); luminance.SetCurrentFrame(imageSbgr2); diff --git a/test/Iris.Tests/src/TransitionTrackerByFPSTests.cpp b/test/Iris.Tests/src/TransitionTrackerByFPSTests.cpp deleted file mode 100644 index 21feb52..0000000 --- a/test/Iris.Tests/src/TransitionTrackerByFPSTests.cpp +++ /dev/null @@ -1,247 +0,0 @@ -//Copyright (C) 2023 Electronic Arts, Inc. All rights reserved. - -#include "IrisLibTest.h" -#include -#include "TransitionTrackerByFPS.h" -#include "FrameData.h" - -namespace iris::Tests -{ - class TransitionTrackerByFPSTest : public IrisLibTest { - protected: - }; - - TEST_F(TransitionTrackerByFPSTest, Transition_WhenOnlyLuminance_Test) - { - //Only luminance transitions - FrameData testData = FrameData(); - TransitionTrackerByFPS transitionTracker(8, configuration.GetTransitionTrackerParams()); - - transitionTracker.SetTransitions(true, false, testData); - transitionTracker.SetTransitions(true, false, testData); - transitionTracker.SetTransitions(false, false, testData); - transitionTracker.SetTransitions(true, false, testData); - transitionTracker.SetTransitions(false, false, testData); - transitionTracker.SetTransitions(false, false, testData); - transitionTracker.SetTransitions(true, false, testData); - - EXPECT_EQ(4, testData.LuminanceTransitions); - EXPECT_EQ(0, testData.RedTransitions); - } - - TEST_F(TransitionTrackerByFPSTest, Transition_WhenOnlyRed_Test) - { - //Only luminance transitions - FrameData testData = FrameData(); - TransitionTrackerByFPS transitionTracker(8, configuration.GetTransitionTrackerParams()); - - transitionTracker.SetTransitions(false, false, testData); - transitionTracker.SetTransitions(false, true, testData); - transitionTracker.SetTransitions(false, false, testData); - transitionTracker.SetTransitions(false, true, testData); - transitionTracker.SetTransitions(false, false, testData); - transitionTracker.SetTransitions(false, true, testData); - transitionTracker.SetTransitions(false, true, testData); - - EXPECT_EQ(0, testData.LuminanceTransitions); - EXPECT_EQ(4, testData.RedTransitions); - } - - TEST_F(TransitionTrackerByFPSTest, Transition_WhenLuminanceAndRed_Test) - { - //Only luminance transitions - FrameData testData = FrameData(); - TransitionTrackerByFPS transitionTracker(8, configuration.GetTransitionTrackerParams()); - - transitionTracker.SetTransitions(false, false, testData); - transitionTracker.SetTransitions(true, true, testData); - transitionTracker.SetTransitions(false, false, testData); - transitionTracker.SetTransitions(false, true, testData); - transitionTracker.SetTransitions(true, false, testData); - transitionTracker.SetTransitions(false, true, testData); - transitionTracker.SetTransitions(true, true, testData); - - EXPECT_EQ(3, testData.LuminanceTransitions); - EXPECT_EQ(4, testData.RedTransitions); - } - - TEST_F(TransitionTrackerByFPSTest, EvaluateFrameMoment_WhenLuminanceFlashFail_Test) - { - //Only luminance transitions - FrameData testData = FrameData(); - TransitionTrackerByFPS transitionTracker(8, configuration.GetTransitionTrackerParams()); - - for (int i = 0; i < 8; i++) - { - transitionTracker.SetTransitions(true, false, testData); - } - transitionTracker.EvaluateFrameMoment(8, 8, testData); - EXPECT_TRUE(transitionTracker.getFlashFail()); - EXPECT_TRUE(transitionTracker.getLumFlashFail()); - EXPECT_EQ(FlashResult::FlashFail, testData.luminanceFrameResult); - EXPECT_EQ(1, transitionTracker.getLuminanceIncidents().flashFailFrames); - } - - TEST_F(TransitionTrackerByFPSTest, EvaluateFrameMoment_WhenRedFlashFail_Test) - { - //Only luminance transitions - FrameData testData = FrameData(); - TransitionTrackerByFPS transitionTracker(8, configuration.GetTransitionTrackerParams()); - - for (int i = 0; i < 8; i++) - { - transitionTracker.SetTransitions(false, true, testData); - } - transitionTracker.EvaluateFrameMoment(8, 8, testData); - EXPECT_TRUE(transitionTracker.getFlashFail()); - EXPECT_TRUE(transitionTracker.getRedFlashFail()); - EXPECT_EQ(FlashResult::FlashFail, testData.redFrameResult); - EXPECT_EQ(1, transitionTracker.getRedIncidents().flashFailFrames); - - } - - TEST_F(TransitionTrackerByFPSTest, EvaluateFrameMoment_WhenLuminanceAndRedFlashFail_Test) - { - //Only luminance transitions - FrameData testData = FrameData(); - TransitionTrackerByFPS transitionTracker(10, configuration.GetTransitionTrackerParams()); - - for (int i = 0; i < 2; i++) //add 2 luminance and red transitions - { - transitionTracker.SetTransitions(true, true, testData); - } - for (int i = 0; i < 3; i++) //add 3 red transitions - { - transitionTracker.SetTransitions(false, true, testData); - } - for (int i = 0; i < 5; i++) //add 5 luminance transitions - { - transitionTracker.SetTransitions(true, false, testData); - } - transitionTracker.EvaluateFrameMoment(10, 10, testData); - EXPECT_TRUE(transitionTracker.getFlashFail()); - EXPECT_TRUE(transitionTracker.getLumFlashFail()); - EXPECT_FALSE(transitionTracker.getRedFlashFail()); - - EXPECT_EQ(FlashResult::FlashFail, testData.luminanceFrameResult); - EXPECT_EQ(FlashResult::PassWithWarning, testData.redFrameResult); - EXPECT_EQ(1, transitionTracker.getLuminanceIncidents().flashFailFrames); - EXPECT_EQ(1, transitionTracker.getRedIncidents().passWithWarningFrames); - - } - - TEST_F(TransitionTrackerByFPSTest, EvaluateFrameMoment_WhenLuminanceFlashPass_Test) - { - //Only luminance transitions - FrameData testData = FrameData(); - TransitionTrackerByFPS transitionTracker(8, configuration.GetTransitionTrackerParams()); - - for (int i = 0; i < 3; i++) //add 3 luminance transitions - { - transitionTracker.SetTransitions(true, false, testData); - } - - for (int i = 0; i < 5; i++) //add 5 frames, no transitions - { - transitionTracker.SetTransitions(false, false, testData); - } - transitionTracker.EvaluateFrameMoment(8, 8, testData); - EXPECT_FALSE(transitionTracker.getFlashFail()); - EXPECT_EQ(FlashResult::Pass, testData.luminanceFrameResult); - EXPECT_EQ(FlashResult::Pass, testData.redFrameResult); - } - - TEST_F(TransitionTrackerByFPSTest, EvaluateFrameMoment_WhenRedFlashPass_Test) - { - //Only luminance transitions - FrameData testData = FrameData(); - TransitionTrackerByFPS transitionTracker(8, configuration.GetTransitionTrackerParams()); - - for (int i = 0; i < 3; i++) //add 3 red transitions - { - transitionTracker.SetTransitions(false, true, testData); - } - - for (int i = 0; i < 5; i++) //add 5 frames, no transitions - { - transitionTracker.SetTransitions(false, false, testData); - } - transitionTracker.EvaluateFrameMoment(8, 8, testData); - EXPECT_FALSE(transitionTracker.getFlashFail()); - EXPECT_EQ(FlashResult::Pass, testData.luminanceFrameResult); - EXPECT_EQ(FlashResult::Pass, testData.redFrameResult); - } - - TEST_F(TransitionTrackerByFPSTest, EvaluateFrameMoment_WhenLuminanceAndRedFlashPass_Test) - { - //Only luminance transitions - FrameData testData = FrameData(); - TransitionTrackerByFPS transitionTracker(8, configuration.GetTransitionTrackerParams()); - - for (int i = 0; i < 3; i++) //add 3 luminance and red transitions - { - transitionTracker.SetTransitions(true, true, testData); - } - - for (int i = 0; i < 5; i++) //add 5 frames, no transitions - { - transitionTracker.SetTransitions(false, false, testData); - } - transitionTracker.EvaluateFrameMoment(8, 8, testData); - EXPECT_FALSE(transitionTracker.getFlashFail()); - EXPECT_EQ(FlashResult::Pass, testData.luminanceFrameResult); - EXPECT_EQ(FlashResult::Pass, testData.redFrameResult); - } - - TEST_F(TransitionTrackerByFPSTest, EvaluateFrameMoment_WhenExtendedFailure_Test) - { - //Only luminance transitions - FrameData testData; - TransitionTrackerByFPS transitionTracker(5, configuration.GetTransitionTrackerParams()); - - for (int i = 0; i < 23; i++) //add luminance and red transitions - { - transitionTracker.SetTransitions(true, true, testData); - transitionTracker.EvaluateFrameMoment(i, 5, testData); - } - EXPECT_TRUE(transitionTracker.getExtendedFailure()); - EXPECT_TRUE(transitionTracker.getLumExtendedFailure()); - EXPECT_TRUE(transitionTracker.getRedExtendedFailure()); - EXPECT_EQ(FlashResult::ExtendedFail, testData.luminanceFrameResult); - EXPECT_EQ(FlashResult::ExtendedFail, testData.redFrameResult); - - EXPECT_EQ(0, transitionTracker.getLuminanceIncidents().flashFailFrames); - EXPECT_EQ(1, transitionTracker.getLuminanceIncidents().extendedFailFrames); - EXPECT_EQ(19, transitionTracker.getLuminanceIncidents().passWithWarningFrames); - EXPECT_EQ(0, transitionTracker.getRedIncidents().flashFailFrames); - EXPECT_EQ(1, transitionTracker.getRedIncidents().extendedFailFrames); - EXPECT_EQ(19, transitionTracker.getRedIncidents().passWithWarningFrames); - } - - TEST_F(TransitionTrackerByFPSTest, TotalTransictionCount_WhenLuminanceAndRed_Test) - { - //Only luminance transitions - FrameData testData = FrameData(); - TransitionTrackerByFPS transitionTracker(4, configuration.GetTransitionTrackerParams()); - - for (int i = 0; i < 5; i++) //add 5 luminance and red transitions - { - transitionTracker.SetTransitions(true, true, testData); - } - for (int i = 0; i < 3; i++) //add 3 frames, no transitions - { - transitionTracker.SetTransitions(false, false, testData); - } - for (int i = 0; i < 4; i++) //add 4 luminance transitions - { - transitionTracker.SetTransitions(true, false, testData); - } - for (int i = 0; i < 6; i++) //add 6 red transitions - { - transitionTracker.SetTransitions(false, true, testData); - } - - EXPECT_EQ(9, testData.LuminanceTransitions); - EXPECT_EQ(11, testData.RedTransitions); - } -} \ No newline at end of file diff --git a/test/Iris.Tests/src/TransitionTrackerByTimeTests.cpp b/test/Iris.Tests/src/TransitionTrackerByTimeTests.cpp deleted file mode 100644 index 724421b..0000000 --- a/test/Iris.Tests/src/TransitionTrackerByTimeTests.cpp +++ /dev/null @@ -1,369 +0,0 @@ -//Copyright (C) 2023 Electronic Arts, Inc. All rights reserved - -#include "IrisLibTest.h" -#include -#include "TransitionTrackerByTime.h" -#include "FrameData.h" - -namespace iris::Tests -{ - class TransitionTrackerByTimeTest : public IrisLibTest { - protected: - }; - - TEST_F(TransitionTrackerByTimeTest, Transition_WhenOnlyLuminance_Test) - { - //Only luminance transitions - FrameData testData = FrameData(); - TransitionTrackerByTime transitionTracker(8, configuration.GetTransitionTrackerParams()); - - transitionTracker.SetTransitions(true, false, testData); - transitionTracker.SetTransitions(true, false, testData); - transitionTracker.SetTransitions(false, false, testData); - transitionTracker.SetTransitions(true, false, testData); - transitionTracker.SetTransitions(false, false, testData); - transitionTracker.SetTransitions(false, false, testData); - transitionTracker.SetTransitions(true, false, testData); - - EXPECT_EQ(4, testData.LuminanceTransitions); - EXPECT_EQ(0, testData.RedTransitions); - } - - TEST_F(TransitionTrackerByTimeTest, Transition_WhenOnlyRed_Test) - { - //Only luminance transitions - FrameData testData = FrameData(); - TransitionTrackerByTime transitionTracker(8, configuration.GetTransitionTrackerParams()); - - transitionTracker.SetTransitions(false, false, testData); - transitionTracker.SetTransitions(false, true, testData); - transitionTracker.SetTransitions(false, false, testData); - transitionTracker.SetTransitions(false, true, testData); - transitionTracker.SetTransitions(false, false, testData); - transitionTracker.SetTransitions(false, true, testData); - transitionTracker.SetTransitions(false, true, testData); - - EXPECT_EQ(0, testData.LuminanceTransitions); - EXPECT_EQ(4, testData.RedTransitions); - } - - TEST_F(TransitionTrackerByTimeTest, Transition_WhenLuminanceAndRed_Test) - { - //Only luminance transitions - FrameData testData = FrameData(); - TransitionTrackerByTime transitionTracker(8, configuration.GetTransitionTrackerParams()); - - transitionTracker.SetTransitions(false, false, testData); - transitionTracker.SetTransitions(true, true, testData); - transitionTracker.SetTransitions(false, false, testData); - transitionTracker.SetTransitions(false, true, testData); - transitionTracker.SetTransitions(true, false, testData); - transitionTracker.SetTransitions(false, true, testData); - transitionTracker.SetTransitions(true, true, testData); - - EXPECT_EQ(3, testData.LuminanceTransitions); - EXPECT_EQ(4, testData.RedTransitions); - } - - TEST_F(TransitionTrackerByTimeTest, EvaluateFrameMoment_WhenLuminanceFlashFail_Test) - { - //Only luminance transitions - FrameData testData = FrameData(); - TransitionTrackerByTime transitionTracker(8, configuration.GetTransitionTrackerParams()); - - for (int i = 0; i < 8; i++) - { - transitionTracker.SetTransitions(true, false, testData); - } - transitionTracker.EvaluateFrameMoment(8, 8, testData); - EXPECT_TRUE(transitionTracker.getFlashFail()); - EXPECT_TRUE(transitionTracker.getLumFlashFail()); - EXPECT_EQ(FlashResult::FlashFail, testData.luminanceFrameResult); - EXPECT_EQ(1, transitionTracker.getLuminanceIncidents().flashFailFrames); - } - - TEST_F(TransitionTrackerByTimeTest, EvaluateFrameMoment_WhenRedFlashFail_Test) - { - //Only luminance transitions - FrameData testData = FrameData(); - TransitionTrackerByTime transitionTracker(8, configuration.GetTransitionTrackerParams()); - - for (int i = 0; i < 8; i++) - { - transitionTracker.SetTransitions(false, true, testData); - } - transitionTracker.EvaluateFrameMoment(8, 8, testData); - EXPECT_TRUE(transitionTracker.getFlashFail()); - EXPECT_TRUE(transitionTracker.getRedFlashFail()); - EXPECT_EQ(FlashResult::FlashFail, testData.redFrameResult); - EXPECT_EQ(1, transitionTracker.getRedIncidents().flashFailFrames); - - } - - TEST_F(TransitionTrackerByTimeTest, EvaluateFrameMoment_WhenLuminanceAndRedFlashFail_Test) - { - //Only luminance transitions - FrameData testData = FrameData(); - TransitionTrackerByTime transitionTracker(10, configuration.GetTransitionTrackerParams()); - - for (int i = 0; i < 2; i++) //add 2 luminance and red transitions - { - transitionTracker.SetTransitions(true, true, testData); - } - for (int i = 0; i < 3; i++) //add 3 red transitions - { - transitionTracker.SetTransitions(false, true, testData); - } - for (int i = 0; i < 5; i++) //add 5 luminance transitions - { - transitionTracker.SetTransitions(true, false, testData); - } - transitionTracker.EvaluateFrameMoment(10, 10, testData); - EXPECT_TRUE(transitionTracker.getFlashFail()); - EXPECT_TRUE(transitionTracker.getLumFlashFail()); - EXPECT_FALSE(transitionTracker.getRedFlashFail()); - - EXPECT_EQ(FlashResult::FlashFail, testData.luminanceFrameResult); - EXPECT_EQ(FlashResult::PassWithWarning, testData.redFrameResult); - EXPECT_EQ(1, transitionTracker.getLuminanceIncidents().flashFailFrames); - EXPECT_EQ(1, transitionTracker.getRedIncidents().passWithWarningFrames); - - } - - TEST_F(TransitionTrackerByTimeTest, EvaluateFrameMoment_WhenLuminanceFlashPass_Test) - { - //Only luminance transitions - FrameData testData = FrameData(); - TransitionTrackerByTime transitionTracker(8, configuration.GetTransitionTrackerParams()); - - for (int i = 0; i < 3; i++) //add 3 luminance transitions - { - transitionTracker.SetTransitions(true, false, testData); - } - - for (int i = 0; i < 5; i++) //add 5 frames, no transitions - { - transitionTracker.SetTransitions(false, false, testData); - } - transitionTracker.EvaluateFrameMoment(8, 8, testData); - EXPECT_FALSE(transitionTracker.getFlashFail()); - EXPECT_EQ(FlashResult::Pass, testData.luminanceFrameResult); - EXPECT_EQ(FlashResult::Pass, testData.redFrameResult); - } - - TEST_F(TransitionTrackerByTimeTest, EvaluateFrameMoment_WhenRedFlashPass_Test) - { - //Only luminance transitions - FrameData testData = FrameData(); - TransitionTrackerByTime transitionTracker(8, configuration.GetTransitionTrackerParams()); - - for (int i = 0; i < 3; i++) //add 3 red transitions - { - transitionTracker.SetTransitions(false, true, testData); - } - - for (int i = 0; i < 5; i++) //add 5 frames, no transitions - { - transitionTracker.SetTransitions(false, false, testData); - } - transitionTracker.EvaluateFrameMoment(8, 8, testData); - EXPECT_FALSE(transitionTracker.getFlashFail()); - EXPECT_EQ(FlashResult::Pass, testData.luminanceFrameResult); - EXPECT_EQ(FlashResult::Pass, testData.redFrameResult); - } - - TEST_F(TransitionTrackerByTimeTest, EvaluateFrameMoment_WhenLuminanceAndRedFlashPass_Test) - { - //Only luminance transitions - FrameData testData = FrameData(); - TransitionTrackerByTime transitionTracker(8, configuration.GetTransitionTrackerParams()); - - for (int i = 0; i < 3; i++) //add 3 luminance and red transitions - { - transitionTracker.SetTransitions(true, true, testData); - } - - for (int i = 0; i < 5; i++) //add 5 frames, no transitions - { - transitionTracker.SetTransitions(false, false, testData); - } - transitionTracker.EvaluateFrameMoment(8, 8, testData); - EXPECT_FALSE(transitionTracker.getFlashFail()); - EXPECT_EQ(FlashResult::Pass, testData.luminanceFrameResult); - EXPECT_EQ(FlashResult::Pass, testData.redFrameResult); - } - - //TEST_F(TransitionTrackerByTimeTest, EvaluateFrameMoment_WhenExtendedFailure_Test) - //{ - // //Only luminance transitions - // FrameData testData; - // TransitionTrackerByTime transitionTracker(5, configuration.GetTransitionTrackerParams()); - - // for (int i = 0; i < 23; i++) //add luminance and red transitions - // { - // testData.TimeStampVal += 200; - // transitionTracker.SetTransitions(true, true, testData); - // transitionTracker.EvaluateFrameMoment(i, 5, testData); - // } - // EXPECT_TRUE(transitionTracker.getExtendedFailure()); - // EXPECT_TRUE(transitionTracker.getLumExtendedFailure()); - // EXPECT_TRUE(transitionTracker.getRedExtendedFailure()); - // EXPECT_EQ(FlashResult::ExtendedFail, testData.luminanceFrameResult); - // EXPECT_EQ(FlashResult::ExtendedFail, testData.redFrameResult); - - // EXPECT_EQ(0, transitionTracker.getLuminanceIncidents().flashFailFrames); - // EXPECT_EQ(1, transitionTracker.getLuminanceIncidents().extendedFailFrames); - // EXPECT_EQ(19, transitionTracker.getLuminanceIncidents().passWithWarningFrames); - // EXPECT_EQ(0, transitionTracker.getRedIncidents().flashFailFrames); - // EXPECT_EQ(1, transitionTracker.getRedIncidents().extendedFailFrames); - // EXPECT_EQ(19, transitionTracker.getRedIncidents().passWithWarningFrames); - //} - - TEST_F(TransitionTrackerByTimeTest, TotalTransictionCount_WhenLuminanceAndRed_Test) - { - //Only luminance transitions - FrameData testData = FrameData(); - TransitionTrackerByTime transitionTracker(4, configuration.GetTransitionTrackerParams()); - - for (int i = 0; i < 5; i++) //add 5 luminance and red transitions - { - transitionTracker.SetTransitions(true, true, testData); - } - for (int i = 0; i < 3; i++) //add 3 frames, no transitions - { - transitionTracker.SetTransitions(false, false, testData); - } - for (int i = 0; i < 4; i++) //add 4 luminance transitions - { - transitionTracker.SetTransitions(true, false, testData); - } - for (int i = 0; i < 6; i++) //add 6 red transitions - { - transitionTracker.SetTransitions(false, true, testData); - } - - EXPECT_EQ(9, testData.LuminanceTransitions); - EXPECT_EQ(11, testData.RedTransitions); - } - - /*TEST_F(TransitionTrackerByTimeTest, EvaluateSecond_WhenTimesBeteewnFramesNotEqual_Test) - { - //Only luminance transitions - FrameData testData; - TransitionTrackerByTime transitionTracker(5, configuration.GetTransitionTrackerParams()); - - int frameNum = 0; - transitionTracker.SetTransitions(true, true, testData); - testData.TimeStampVal = 0; - transitionTracker.EvaluateFrameMoment(frameNum, 5, testData); - - transitionTracker.SetTransitions(true, true, testData); - testData.TimeStampVal = 150; - transitionTracker.EvaluateFrameMoment(frameNum++, 5, testData); - - transitionTracker.SetTransitions(true, true, testData); - testData.TimeStampVal = 500; - transitionTracker.EvaluateFrameMoment(frameNum++, 5, testData); - - transitionTracker.SetTransitions(true, true, testData); - testData.TimeStampVal = 750; - transitionTracker.EvaluateFrameMoment(frameNum++, 5, testData); - - transitionTracker.SetTransitions(true, true, testData); - testData.TimeStampVal = 1000; - transitionTracker.EvaluateFrameMoment(frameNum++, 5, testData); - - - - transitionTracker.SetTransitions(true, true, testData); - testData.TimeStampVal = 1150; - transitionTracker.EvaluateFrameMoment(frameNum++, 5, testData); - - transitionTracker.SetTransitions(true, true, testData); - testData.TimeStampVal = 1350; - transitionTracker.EvaluateFrameMoment(frameNum++, 5, testData); - - transitionTracker.SetTransitions(true, true, testData); - testData.TimeStampVal = 1600; - transitionTracker.EvaluateFrameMoment(frameNum++, 5, testData); - - transitionTracker.SetTransitions(true, true, testData); - testData.TimeStampVal = 1950; - transitionTracker.EvaluateFrameMoment(frameNum++, 5, testData); - - transitionTracker.SetTransitions(true, true, testData); - testData.TimeStampVal = 2000; - transitionTracker.EvaluateFrameMoment(frameNum++, 5, testData); - - - - transitionTracker.SetTransitions(true, true, testData); - testData.TimeStampVal = 2200; - transitionTracker.EvaluateFrameMoment(frameNum++, 5, testData); - - transitionTracker.SetTransitions(true, true, testData); - testData.TimeStampVal = 2450; - transitionTracker.EvaluateFrameMoment(frameNum++, 5, testData); - - transitionTracker.SetTransitions(true, true, testData); - testData.TimeStampVal = 2800; - transitionTracker.EvaluateFrameMoment(frameNum++, 5, testData); - - transitionTracker.SetTransitions(true, true, testData); - testData.TimeStampVal = 2900; - transitionTracker.EvaluateFrameMoment(frameNum++, 5, testData); - - transitionTracker.SetTransitions(true, true, testData); - testData.TimeStampVal = 3000; - transitionTracker.EvaluateFrameMoment(frameNum++, 5, testData); - - - transitionTracker.SetTransitions(true, true, testData); - testData.TimeStampVal = 3450; - transitionTracker.EvaluateFrameMoment(frameNum++, 5, testData); - - transitionTracker.SetTransitions(true, true, testData); - testData.TimeStampVal = 3800; - transitionTracker.EvaluateFrameMoment(frameNum++, 5, testData); - - transitionTracker.SetTransitions(true, true, testData); - testData.TimeStampVal = 3850; - transitionTracker.EvaluateFrameMoment(frameNum++, 5, testData); - - transitionTracker.SetTransitions(true, true, testData); - testData.TimeStampVal = 3950; - transitionTracker.EvaluateFrameMoment(frameNum++, 5, testData); - - transitionTracker.SetTransitions(true, true, testData); - testData.TimeStampVal = 4000; - transitionTracker.EvaluateFrameMoment(frameNum++, 5, testData); - - - - transitionTracker.SetTransitions(true, true, testData); - testData.TimeStampVal = 4250; - transitionTracker.EvaluateFrameMoment(frameNum++, 5, testData); - - transitionTracker.SetTransitions(true, true, testData); - testData.TimeStampVal = 4600; - transitionTracker.EvaluateFrameMoment(frameNum++, 5, testData); - - transitionTracker.SetTransitions(true, true, testData); - testData.TimeStampVal = 4850; - transitionTracker.EvaluateFrameMoment(frameNum++, 5, testData); - - - EXPECT_TRUE(transitionTracker.getExtendedFailure()); - EXPECT_TRUE(transitionTracker.getLumExtendedFailure()); - EXPECT_TRUE(transitionTracker.getRedExtendedFailure()); - EXPECT_EQ(FlashResult::ExtendedFail, testData.luminanceFrameResult); - EXPECT_EQ(FlashResult::ExtendedFail, testData.redFrameResult); - - EXPECT_EQ(0, transitionTracker.getLuminanceIncidents().flashFailFrames); - EXPECT_EQ(1, transitionTracker.getLuminanceIncidents().extendedFailFrames); - EXPECT_EQ(19, transitionTracker.getLuminanceIncidents().passWithWarningFrames); - EXPECT_EQ(0, transitionTracker.getRedIncidents().flashFailFrames); - EXPECT_EQ(1, transitionTracker.getRedIncidents().extendedFailFrames); - EXPECT_EQ(19, transitionTracker.getRedIncidents().passWithWarningFrames); - }*/ -} \ No newline at end of file diff --git a/test/Iris.Tests/src/TransitionTrackerTests.cpp b/test/Iris.Tests/src/TransitionTrackerTests.cpp new file mode 100644 index 0000000..1b2594a --- /dev/null +++ b/test/Iris.Tests/src/TransitionTrackerTests.cpp @@ -0,0 +1,519 @@ +//Copyright (C) 2023 Electronic Arts, Inc. All rights reserved. + +#include "IrisLibTest.h" +#include +#include "TransitionTracker.h" +#include "iris/FrameData.h" +#include "FpsFrameManager.h" +#include "TimeFrameManager.h" + +namespace iris::Tests +{ + +class TransitionTrackerTest : public IrisLibTest +{ + +protected: + IFrameManager* frameManager; + + void SetUp() override + { + IrisLibTest::SetUp(); + } + + TransitionTracker GetTransitionTracker(short fps, bool timeAnalys = false) + { + if (timeAnalys) frameManager = new TimeFrameManager(); + else frameManager = new FpsFrameManager(); + + return TransitionTracker(fps, configuration.GetTransitionTrackerParams(), frameManager); + } + + ~TransitionTrackerTest() override + { + delete frameManager; + } +}; + +TEST_F(TransitionTrackerTest, Transition_WhenOnlyLuminance_Test) +{ + //Only luminance transitions + FrameData testData = FrameData(); + TransitionTracker transitionTracker = GetTransitionTracker(8); + + transitionTracker.SetTransitions(true, false, testData); + transitionTracker.SetTransitions(true, false, testData); + transitionTracker.SetTransitions(false, false, testData); + transitionTracker.SetTransitions(true, false, testData); + transitionTracker.SetTransitions(false, false, testData); + transitionTracker.SetTransitions(false, false, testData); + transitionTracker.SetTransitions(true, false, testData); + + EXPECT_EQ(4, testData.LuminanceTransitions); + EXPECT_EQ(0, testData.RedTransitions); +} + +TEST_F(TransitionTrackerTest, Transition_WhenOnlyRed_Test) +{ + //Only luminance transitions + FrameData testData = FrameData(); + TransitionTracker transitionTracker = GetTransitionTracker(8); + + transitionTracker.SetTransitions(false, false, testData); + transitionTracker.SetTransitions(false, true, testData); + transitionTracker.SetTransitions(false, false, testData); + transitionTracker.SetTransitions(false, true, testData); + transitionTracker.SetTransitions(false, false, testData); + transitionTracker.SetTransitions(false, true, testData); + transitionTracker.SetTransitions(false, true, testData); + + EXPECT_EQ(0, testData.LuminanceTransitions); + EXPECT_EQ(4, testData.RedTransitions); +} + +TEST_F(TransitionTrackerTest, Transition_WhenLuminanceAndRed_Test) +{ + //Only luminance transitions + FrameData testData = FrameData(); + TransitionTracker transitionTracker = GetTransitionTracker(8); + + transitionTracker.SetTransitions(false, false, testData); + transitionTracker.SetTransitions(true, true, testData); + transitionTracker.SetTransitions(false, false, testData); + transitionTracker.SetTransitions(false, true, testData); + transitionTracker.SetTransitions(true, false, testData); + transitionTracker.SetTransitions(false, true, testData); + transitionTracker.SetTransitions(true, true, testData); + + EXPECT_EQ(3, testData.LuminanceTransitions); + EXPECT_EQ(4, testData.RedTransitions); +} + +TEST_F(TransitionTrackerTest, EvaluateFrameMoment_WhenLuminanceFlashFail_Test) +{ + //Only luminance transitions + FrameData testData = FrameData(); + TransitionTracker transitionTracker = GetTransitionTracker(8); + + for (int i = 0; i < 8; i++) + { + transitionTracker.SetTransitions(true, false, testData, i); + } + transitionTracker.EvaluateFrameMoment(testData); + EXPECT_TRUE(transitionTracker.getFlashFail()); + EXPECT_TRUE(transitionTracker.getLumFlashFail()); + EXPECT_EQ(FlashResult::FlashFail, testData.luminanceFrameResult); + EXPECT_EQ(1, transitionTracker.getLuminanceIncidents().flashFailFrames); +} + +TEST_F(TransitionTrackerTest, EvaluateFrameMoment_WhenRedFlashFail_Test) +{ + //Only luminance transitions + FrameData testData = FrameData(); + TransitionTracker transitionTracker = GetTransitionTracker(8); + + for (int i = 0; i < 8; i++) + { + transitionTracker.SetTransitions(false, true, testData, i); + } + transitionTracker.EvaluateFrameMoment(testData); + EXPECT_TRUE(transitionTracker.getFlashFail()); + EXPECT_TRUE(transitionTracker.getRedFlashFail()); + EXPECT_EQ(FlashResult::FlashFail, testData.redFrameResult); + EXPECT_EQ(1, transitionTracker.getRedIncidents().flashFailFrames); + +} + +TEST_F(TransitionTrackerTest, EvaluateFrameMoment_WhenLuminanceAndRedFlashFail_Test) +{ + //Only luminance transitions + FrameData testData = FrameData(); + TransitionTracker transitionTracker = GetTransitionTracker(10); + int frameNum = -1; + + for (int i = 0; i < 2; i++) //add 2 luminance and red transitions + { + transitionTracker.SetTransitions(true, true, testData, frameNum++); + } + for (int i = 0; i < 3; i++) //add 3 red transitions + { + transitionTracker.SetTransitions(false, true, testData, frameNum++); + } + for (int i = 0; i < 5; i++) //add 5 luminance transitions + { + transitionTracker.SetTransitions(true, false, testData, frameNum++); + } + transitionTracker.EvaluateFrameMoment(testData); + EXPECT_TRUE(transitionTracker.getFlashFail()); + EXPECT_TRUE(transitionTracker.getLumFlashFail()); + EXPECT_FALSE(transitionTracker.getRedFlashFail()); + + EXPECT_EQ(FlashResult::FlashFail, testData.luminanceFrameResult); + EXPECT_EQ(FlashResult::PassWithWarning, testData.redFrameResult); + EXPECT_EQ(1, transitionTracker.getLuminanceIncidents().flashFailFrames); + EXPECT_EQ(1, transitionTracker.getRedIncidents().passWithWarningFrames); + +} + +TEST_F(TransitionTrackerTest, EvaluateFrameMoment_WhenLuminanceFlashPass_Test) +{ + //Only luminance transitions + FrameData testData = FrameData(); + TransitionTracker transitionTracker = GetTransitionTracker(8); + int frameNum = -1; + + for (int i = 0; i < 3; i++) //add 3 luminance transitions + { + transitionTracker.SetTransitions(true, false, testData, frameNum++); + } + + for (int i = 0; i < 5; i++) //add 5 frames, no transitions + { + transitionTracker.SetTransitions(false, false, testData, frameNum++); + } + transitionTracker.EvaluateFrameMoment(testData); + EXPECT_FALSE(transitionTracker.getFlashFail()); + EXPECT_EQ(FlashResult::Pass, testData.luminanceFrameResult); + EXPECT_EQ(FlashResult::Pass, testData.redFrameResult); +} + +TEST_F(TransitionTrackerTest, EvaluateFrameMoment_WhenRedFlashPass_Test) +{ + //Only luminance transitions + FrameData testData = FrameData(); + TransitionTracker transitionTracker = GetTransitionTracker(8); + int frameNum = -1; + + for (int i = 0; i < 3; i++) //add 3 red transitions + { + transitionTracker.SetTransitions(false, true, testData, frameNum++); + } + + for (int i = 0; i < 5; i++) //add 5 frames, no transitions + { + transitionTracker.SetTransitions(false, false, testData, frameNum++); + } + transitionTracker.EvaluateFrameMoment(testData); + EXPECT_FALSE(transitionTracker.getFlashFail()); + EXPECT_EQ(FlashResult::Pass, testData.luminanceFrameResult); + EXPECT_EQ(FlashResult::Pass, testData.redFrameResult); +} + +TEST_F(TransitionTrackerTest, EvaluateFrameMoment_WhenLuminanceAndRedFlashPass_Test) +{ + //Only luminance transitions + FrameData testData = FrameData(); + TransitionTracker transitionTracker = GetTransitionTracker(8); + int frameNum = 0; + + for (int i = 0; i < 3; i++) //add 3 luminance and red transitions + { + transitionTracker.SetTransitions(true, true, testData, frameNum++); + } + + for (int i = 0; i < 5; i++) //add 5 frames, no transitions + { + transitionTracker.SetTransitions(false, false, testData, frameNum++); + } + transitionTracker.EvaluateFrameMoment(testData); + EXPECT_FALSE(transitionTracker.getFlashFail()); + EXPECT_EQ(FlashResult::Pass, testData.luminanceFrameResult); + EXPECT_EQ(FlashResult::Pass, testData.redFrameResult); +} + +TEST_F(TransitionTrackerTest, EvaluateFrameMoment_WhenExtendedFailure_Test) +{ + //Only luminance transitions + FrameData testData; + TransitionTracker transitionTracker = GetTransitionTracker(5); + + for (int i = 0; i < 23; i++) //add luminance and red transitions + { + frameManager->AddFrame(testData); + transitionTracker.SetTransitions(true, true, testData, i); + transitionTracker.EvaluateFrameMoment(testData); + } + EXPECT_TRUE(transitionTracker.getExtendedFailure()); + EXPECT_TRUE(transitionTracker.getLumExtendedFailure()); + EXPECT_TRUE(transitionTracker.getRedExtendedFailure()); + EXPECT_EQ(FlashResult::ExtendedFail, testData.luminanceFrameResult); + EXPECT_EQ(FlashResult::ExtendedFail, testData.redFrameResult); + + EXPECT_EQ(0, transitionTracker.getLuminanceIncidents().flashFailFrames); + EXPECT_EQ(1, transitionTracker.getLuminanceIncidents().extendedFailFrames); + EXPECT_EQ(19, transitionTracker.getLuminanceIncidents().passWithWarningFrames); + EXPECT_EQ(0, transitionTracker.getRedIncidents().flashFailFrames); + EXPECT_EQ(1, transitionTracker.getRedIncidents().extendedFailFrames); + EXPECT_EQ(19, transitionTracker.getRedIncidents().passWithWarningFrames); +} + +TEST_F(TransitionTrackerTest, TotalTransictionCount_WhenLuminanceAndRed_Test) +{ + //Only luminance transitions + FrameData testData = FrameData(); + TransitionTracker transitionTracker = GetTransitionTracker(4); + + for (int i = 0; i < 5; i++) //add 5 luminance and red transitions + { + transitionTracker.SetTransitions(true, true, testData); + } + for (int i = 0; i < 3; i++) //add 3 frames, no transitions + { + transitionTracker.SetTransitions(false, false, testData); + } + for (int i = 0; i < 4; i++) //add 4 luminance transitions + { + transitionTracker.SetTransitions(true, false, testData); + } + for (int i = 0; i < 6; i++) //add 6 red transitions + { + transitionTracker.SetTransitions(false, true, testData); + } + + EXPECT_EQ(9, testData.LuminanceTransitions); + EXPECT_EQ(11, testData.RedTransitions); +} + +TEST_F(TransitionTrackerTest, RealTime_EvaluateFrameMoment_WhenLuminanceAndRedFlashFail) +{ + //Only luminance transitions + FrameData testData = FrameData(); + TransitionTracker transitionTracker = GetTransitionTracker(10, true); + int frameNum = -1; + + for (int i = 0; i < 2; i++) //add 2 luminance and red transitions + { + frameManager->AddFrame(testData); + transitionTracker.SetTransitions(true, true, testData, frameNum++); + } + for (int i = 0; i < 3; i++) //add 3 red transitions + { + frameManager->AddFrame(testData); + transitionTracker.SetTransitions(false, true, testData, frameNum++); + } + for (int i = 0; i < 5; i++) //add 5 luminance transitions + { + frameManager->AddFrame(testData); + transitionTracker.SetTransitions(true, false, testData, frameNum++); + } + transitionTracker.EvaluateFrameMoment(testData); + EXPECT_TRUE(transitionTracker.getFlashFail()); + EXPECT_TRUE(transitionTracker.getLumFlashFail()); + EXPECT_FALSE(transitionTracker.getRedFlashFail()); + + EXPECT_EQ(FlashResult::FlashFail, testData.luminanceFrameResult); + EXPECT_EQ(FlashResult::PassWithWarning, testData.redFrameResult); + EXPECT_EQ(1, transitionTracker.getLuminanceIncidents().flashFailFrames); + EXPECT_EQ(1, transitionTracker.getRedIncidents().passWithWarningFrames); + +} + +TEST_F(TransitionTrackerTest, RealTime_EvaluateSecond_ExtendedFailWhenTimesBeteewnFramesNotEqual) +{ + //Only luminance transitions + FrameData testData; + TransitionTracker transitionTracker = GetTransitionTracker(5, true); + + int frameNum = 0; + testData.TimeStampVal = 0; + frameManager->AddFrame(testData); + + transitionTracker.SetTransitions(true, true, testData, frameNum); + transitionTracker.EvaluateFrameMoment(testData); + + for (int i = 0; i < 4; i++) + { + testData.TimeStampVal += 200; + frameManager->AddFrame(testData); + transitionTracker.SetTransitions(true, true, testData, frameNum++); + transitionTracker.EvaluateFrameMoment(testData); + + testData.TimeStampVal += 300; + frameManager->AddFrame(testData); + transitionTracker.SetTransitions(true, true, testData, frameNum++); + transitionTracker.EvaluateFrameMoment(testData); + + testData.TimeStampVal += 100; + frameManager->AddFrame(testData); + transitionTracker.SetTransitions(true, true, testData, frameNum++); + transitionTracker.EvaluateFrameMoment(testData); + + testData.TimeStampVal += 250; + frameManager->AddFrame(testData); + transitionTracker.SetTransitions(true, true, testData, frameNum++); + transitionTracker.EvaluateFrameMoment(testData); + + testData.TimeStampVal += 150; + frameManager->AddFrame(testData); + transitionTracker.SetTransitions(true, true, testData, frameNum++); + transitionTracker.EvaluateFrameMoment(testData); + } + + testData.TimeStampVal += 200; + frameManager->AddFrame(testData); + transitionTracker.SetTransitions(true, true, testData, frameNum++); + transitionTracker.EvaluateFrameMoment(testData); + + testData.TimeStampVal += 300; + frameManager->AddFrame(testData); + transitionTracker.SetTransitions(true, true, testData, frameNum++); + transitionTracker.EvaluateFrameMoment(testData); + + + EXPECT_TRUE(transitionTracker.getExtendedFailure()); + EXPECT_TRUE(transitionTracker.getLumExtendedFailure()); + EXPECT_TRUE(transitionTracker.getRedExtendedFailure()); + EXPECT_EQ(FlashResult::ExtendedFail, testData.luminanceFrameResult); + EXPECT_EQ(FlashResult::ExtendedFail, testData.redFrameResult); + + EXPECT_EQ(0, transitionTracker.getLuminanceIncidents().flashFailFrames); + EXPECT_EQ(1, transitionTracker.getLuminanceIncidents().extendedFailFrames); + EXPECT_EQ(19, transitionTracker.getLuminanceIncidents().passWithWarningFrames); + EXPECT_EQ(0, transitionTracker.getRedIncidents().flashFailFrames); + EXPECT_EQ(1, transitionTracker.getRedIncidents().extendedFailFrames); + EXPECT_EQ(19, transitionTracker.getRedIncidents().passWithWarningFrames); +} + +TEST_F(TransitionTrackerTest, RealTime_EvaluateSecond_ExtendedFailFramerateFluctuations) +{ + //Only luminance transitions + FrameData testData; + TransitionTracker transitionTracker = GetTransitionTracker(5, true); + int frameNum = 0; + + //1st 1s window (5 transitions - 4 FPS) + //First frame should not set any transition/evaluate moment (analysis by time) + testData.TimeStampVal = 0; + frameManager->AddFrame(testData); + + for (int i = 0; i < 4; i++) + { + testData.TimeStampVal += 250; + frameManager->AddFrame(testData); + transitionTracker.SetTransitions(true, true, testData, frameNum++); + transitionTracker.EvaluateFrameMoment(testData); + } + + //2nd 1s window (1 transition - 1FPS) + testData.TimeStampVal += 1000; + frameManager->AddFrame(testData); + transitionTracker.SetTransitions(true, true, testData, frameNum++); + transitionTracker.EvaluateFrameMoment(testData); + + + //3th 1s window (5 transitions - 6 FPS) + for (int i = 0; i < 2; i++) + { + testData.TimeStampVal += 200; + frameManager->AddFrame(testData); + transitionTracker.SetTransitions(true, true, testData, frameNum++); + transitionTracker.EvaluateFrameMoment(testData); + + testData.TimeStampVal += 100; + frameManager->AddFrame(testData); + transitionTracker.SetTransitions(true, true, testData, frameNum++); + transitionTracker.EvaluateFrameMoment(testData); + } + + testData.TimeStampVal += 400; + frameManager->AddFrame(testData); + transitionTracker.SetTransitions(true, true, testData, frameNum++); + transitionTracker.EvaluateFrameMoment(testData); + + //4th 1s window (4 transitions - 5 FPS) + testData.TimeStampVal += 100; + frameManager->AddFrame(testData); + transitionTracker.SetTransitions(true, true, testData, frameNum++); + transitionTracker.EvaluateFrameMoment(testData); + + testData.TimeStampVal += 150; + frameManager->AddFrame(testData); + transitionTracker.SetTransitions(true, true, testData, frameNum++); + transitionTracker.EvaluateFrameMoment(testData); + + testData.TimeStampVal += 250; + frameManager->AddFrame(testData); + transitionTracker.SetTransitions(true, true, testData, frameNum++); + transitionTracker.EvaluateFrameMoment(testData); + + testData.TimeStampVal += 500; + frameManager->AddFrame(testData); + transitionTracker.SetTransitions(true, true, testData, frameNum++); + transitionTracker.EvaluateFrameMoment(testData); + + //5th 1s window (5 transitions - 6 FPS) + + testData.TimeStampVal += 200; + frameManager->AddFrame(testData); + transitionTracker.SetTransitions(true, true, testData, frameNum++); + transitionTracker.EvaluateFrameMoment(testData); + + testData.TimeStampVal += 100; + frameManager->AddFrame(testData); + transitionTracker.SetTransitions(true, true, testData, frameNum++); + transitionTracker.EvaluateFrameMoment(testData); + + testData.TimeStampVal += 100; + frameManager->AddFrame(testData); + transitionTracker.SetTransitions(true, true, testData, frameNum++); + transitionTracker.EvaluateFrameMoment(testData); + + testData.TimeStampVal += 300; + frameManager->AddFrame(testData); + transitionTracker.SetTransitions(true, true, testData, frameNum++); + transitionTracker.EvaluateFrameMoment(testData); + + testData.TimeStampVal += 300; + frameManager->AddFrame(testData); + transitionTracker.SetTransitions(true, true, testData, frameNum++); + transitionTracker.EvaluateFrameMoment(testData); + + //6th 1s window (4 transitions - 5 FPS) + testData.TimeStampVal += 200; + frameManager->AddFrame(testData); + transitionTracker.SetTransitions(true, true, testData, frameNum++); + transitionTracker.EvaluateFrameMoment(testData); + + testData.TimeStampVal += 100; + frameManager->AddFrame(testData); + transitionTracker.SetTransitions(true, true, testData, frameNum++); + transitionTracker.EvaluateFrameMoment(testData); + + testData.TimeStampVal += 300; + frameManager->AddFrame(testData); + transitionTracker.SetTransitions(true, true, testData, frameNum++); + transitionTracker.EvaluateFrameMoment(testData); + + testData.TimeStampVal += 400; + frameManager->AddFrame(testData); + transitionTracker.SetTransitions(true, true, testData, frameNum++); + transitionTracker.EvaluateFrameMoment(testData); + + + //7th 1s window (3 transitions to trigger the ExtendedFail) + + testData.TimeStampVal += 150; + frameManager->AddFrame(testData); + transitionTracker.SetTransitions(true, true, testData, frameNum++); + transitionTracker.EvaluateFrameMoment(testData); + + testData.TimeStampVal += 300; + frameManager->AddFrame(testData); + transitionTracker.SetTransitions(true, true, testData, frameNum++); + transitionTracker.EvaluateFrameMoment(testData); + + EXPECT_TRUE(transitionTracker.getExtendedFailure()); + EXPECT_TRUE(transitionTracker.getLumExtendedFailure()); + EXPECT_TRUE(transitionTracker.getRedExtendedFailure()); + EXPECT_EQ(FlashResult::ExtendedFail, testData.luminanceFrameResult); + EXPECT_EQ(FlashResult::ExtendedFail, testData.redFrameResult); + + EXPECT_EQ(0, transitionTracker.getLuminanceIncidents().flashFailFrames); + EXPECT_EQ(1, transitionTracker.getLuminanceIncidents().extendedFailFrames); + EXPECT_EQ(18, transitionTracker.getLuminanceIncidents().passWithWarningFrames); + EXPECT_EQ(0, transitionTracker.getRedIncidents().flashFailFrames); + EXPECT_EQ(1, transitionTracker.getRedIncidents().extendedFailFrames); + EXPECT_EQ(18, transitionTracker.getRedIncidents().passWithWarningFrames); +} + +} \ No newline at end of file diff --git a/test/Iris.Tests/src/VideoAnalysisTests.cpp b/test/Iris.Tests/src/VideoAnalysisTests.cpp index f812e6c..e183495 100644 --- a/test/Iris.Tests/src/VideoAnalysisTests.cpp +++ b/test/Iris.Tests/src/VideoAnalysisTests.cpp @@ -5,26 +5,35 @@ #include #include #include -#include "FrameData.h" +#include "iris/FrameData.h" namespace iris::Tests { class VideoAnalysisTests : public IrisLibTest { protected: - void SetUp() override { - configuration.SetLuminanceType(Configuration::LuminanceType::RELATIVE); + void SetUp() override + { IrisLibTest::SetUp(); } - void TestVideoAnalysis(VideoAnalyser& videoAnalyser, cv::VideoCapture& video, const char* sourceLog) + void TestVideoAnalysis(VideoAnalyser& videoAnalyser, cv::VideoCapture& video, const char* sourceLog, bool timeAnalysis = false) { std::ifstream logFile; logFile.open(sourceLog); std::string line; std::getline(logFile, line); //discard first line - std::string testVideo = "testVideo"; - videoAnalyser.Init(testVideo); + std::string testVideo = "./testVideo.mp4"; + + if (timeAnalysis) + { + cv::Size size = videoAnalyser.GetVideoInfo().frameSize; + videoAnalyser.RealTimeInit(size); + } + else + { + videoAnalyser.Init(testVideo); + } cv::Mat frame; video.read(frame); unsigned int numFrames = 0; @@ -32,7 +41,6 @@ namespace iris::Tests while (!frame.empty()) { FrameData data(numFrames + 1, 1000.0 * (double)numFrames / video.get(cv::CAP_PROP_FPS)); - //FrameData data(numFrames + 1, video.get(cv::CAP_PROP_FRAME_COUNT)); videoAnalyser.AnalyseFrame(frame, numFrames, data); video.read(frame); //obtain new frame @@ -58,46 +66,30 @@ namespace iris::Tests logFrameData.push_back(substr); } - EXPECT_EQ(std::stoi(logFrameData[0]), data.Frame) << "Frame: " << data.Frame << " Expected: " << std::stoi(logFrameData[0]); - - EXPECT_TRUE(CompareFloat(std::stof(logFrameData[2]), data.LuminanceAverage)) - << "Frame: " << data.Frame << " Expected: " << std::stof(logFrameData[2]) << " Actual: " << data.LuminanceAverage; - std::string str = data.proportionToPercentage(std::stof(logFrameData[3])); - EXPECT_EQ(str, data.LuminanceFlashArea) - << "Frame: " << data.Frame << " Expected: " << str << " Actual: " << data.LuminanceFlashArea; - EXPECT_TRUE(CompareFloat(std::stof(logFrameData[4]), data.AverageLuminanceDiff)) - << "Frame: " << data.Frame << " Expected: " << std::stof(logFrameData[4]) << " Actual: " << data.AverageLuminanceDiff; - EXPECT_TRUE(CompareFloat(std::stof(logFrameData[5]), data.AverageLuminanceDiffAcc)) - << "Frame: " << data.Frame << " Expected: " << std::stof(logFrameData[5]) << " Actual: " << data.AverageLuminanceDiffAcc; + EXPECT_EQ(std::stoi(logFrameData[0]), data.Frame) << "Frame: " << data.Frame << '\n'; + + EXPECT_TRUE(CompareFloat(std::stof(logFrameData[2]), data.LuminanceAverage)) << "Frame: " << data.Frame << '\n'; + std::string str = data.proportionToPercentage(std::stof(logFrameData[3])); + EXPECT_EQ(str, data.LuminanceFlashArea) << "Frame: " << data.Frame << '\n'; + EXPECT_TRUE(CompareFloat(std::stof(logFrameData[4]), data.AverageLuminanceDiff)) << "Frame: " << data.Frame << '\n'; + EXPECT_TRUE(CompareFloat(std::stof(logFrameData[5]), data.AverageLuminanceDiffAcc)) << "Frame: " << data.Frame << '\n'; - EXPECT_TRUE(CompareFloat(std::stof(logFrameData[6]), data.RedAverage)) - << "Frame: " << data.Frame << " Expected: " << std::stof(logFrameData[6]) << " Actual: " << data.RedAverage; - str = data.proportionToPercentage(std::stof(logFrameData[7])); - EXPECT_EQ(str, data.RedFlashArea) - << "Frame: " << data.Frame << " Expected: " << str << " Actual: " << data.RedFlashArea; - EXPECT_TRUE(CompareFloat(std::stof(logFrameData[8]), data.AverageRedDiff)) - << "Frame: " << data.Frame << " Expected: " << std::stof(logFrameData[8]) << " Actual: " << data.AverageRedDiff; - EXPECT_TRUE(CompareFloat(std::stof(logFrameData[9]), data.AverageRedDiffAcc)) - << "Frame: " << data.Frame << " Expected: " << std::stof(logFrameData[9]) << " Actual: " << data.AverageRedDiffAcc; - - EXPECT_EQ(std::stof(logFrameData[10]), data.PatternRisk) - << "Frame: " << data.Frame << " Expected: " << std::stof(logFrameData[10]) << " Actual: " << data.PatternRisk; - - EXPECT_EQ(std::stoi(logFrameData[11]), data.LuminanceTransitions) - << "Frame: " << data.Frame << " Expected: " << std::stoi(logFrameData[11]) << " Actual: " << data.LuminanceTransitions; - EXPECT_EQ(std::stoi(logFrameData[12]), data.RedTransitions) - << "Frame: " << data.Frame << " Expected: " << std::stoi(logFrameData[12]) << " Actual: " << data.RedTransitions; - EXPECT_EQ(std::stoi(logFrameData[13]), data.LuminanceExtendedFailCount) - << "Frame: " << data.Frame << " Expected: " << std::stoi(logFrameData[13]) << " Actual: " << data.LuminanceExtendedFailCount; - EXPECT_EQ(std::stoi(logFrameData[14]), data.RedExtendedFailCount) - << "Frame: " << data.Frame << " Expected: " << std::stoi(logFrameData[14]) << " Actual: " << data.RedExtendedFailCount; - - EXPECT_EQ(std::stoi(logFrameData[15]), (int)data.luminanceFrameResult) - << "Frame: " << data.Frame << " Expected: " << std::stoi(logFrameData[15]) << " Actual: " << (int)data.luminanceFrameResult; - EXPECT_EQ(std::stoi(logFrameData[16]), (int)data.redFrameResult) - << "Frame: " << data.Frame << " Expected: " << std::stoi(logFrameData[16]) << " Actual: " << (int)data.redFrameResult; - EXPECT_EQ(std::stoi(logFrameData[17]), (int)data.patternFrameResult) - << "Frame: " << data.Frame << " Expected: " << std::stoi(logFrameData[17]) << " Actual: " << (int)data.patternFrameResult; + EXPECT_TRUE(CompareFloat(std::stof(logFrameData[6]), data.RedAverage)) << "Frame: " << data.Frame << '\n'; + str = data.proportionToPercentage(std::stof(logFrameData[7])); + EXPECT_EQ(str, data.RedFlashArea) << "Frame: " << data.Frame << '\n'; + EXPECT_TRUE(CompareFloat(std::stof(logFrameData[8]), data.AverageRedDiff)) << "Frame: " << data.Frame << '\n'; + EXPECT_TRUE(CompareFloat(std::stof(logFrameData[9]), data.AverageRedDiffAcc)) << "Frame: " << data.Frame << '\n'; + + EXPECT_EQ(std::stof(logFrameData[10]), data.PatternRisk) << "Frame: " << data.Frame << '\n'; + + EXPECT_EQ(std::stoi(logFrameData[11]), data.LuminanceTransitions) << "Frame: " << data.Frame << '\n'; + EXPECT_EQ(std::stoi(logFrameData[12]), data.RedTransitions) << "Frame: " << data.Frame << '\n'; + EXPECT_EQ(std::stoi(logFrameData[13]), data.LuminanceExtendedFailCount) << "Frame: " << data.Frame << '\n'; + EXPECT_EQ(std::stoi(logFrameData[14]), data.RedExtendedFailCount) << "Frame: " << data.Frame << '\n'; + + EXPECT_EQ(std::stoi(logFrameData[15]), (int)data.luminanceFrameResult) << "Frame: " << data.Frame << '\n'; + EXPECT_EQ(std::stoi(logFrameData[16]), (int)data.redFrameResult) << "Frame: " << data.Frame << '\n'; + EXPECT_EQ(std::stoi(logFrameData[17]), (int)data.patternFrameResult) << "Frame: " << data.Frame << '\n'; } }; @@ -107,7 +99,7 @@ namespace iris::Tests VideoAnalyser videoAnalyser(&configuration); cv::VideoCapture video(sourceVideo); - if (videoAnalyser.VideoIsOpen(sourceVideo, video, nullptr)) + if (videoAnalyser.VideoIsOpen(sourceVideo, video)) { TestVideoAnalysis(videoAnalyser, video, "data/ExpectedVideoLogFiles/2Hz_5s_RELATIVE.csv"); } @@ -119,7 +111,7 @@ namespace iris::Tests VideoAnalyser videoAnalyser(&configuration); cv::VideoCapture video(sourceVideo); - if (videoAnalyser.VideoIsOpen(sourceVideo, video, nullptr)) + if (videoAnalyser.VideoIsOpen(sourceVideo, video)) { TestVideoAnalysis(videoAnalyser, video, "data/ExpectedVideoLogFiles/2Hz_6s_RELATIVE.csv"); } @@ -131,7 +123,7 @@ namespace iris::Tests VideoAnalyser videoAnalyser(&configuration); cv::VideoCapture video(sourceVideo); - if (videoAnalyser.VideoIsOpen(sourceVideo, video, nullptr)) + if (videoAnalyser.VideoIsOpen(sourceVideo, video)) { TestVideoAnalysis(videoAnalyser, video, "data/ExpectedVideoLogFiles/3Hz_6s_RELATIVE.csv"); } @@ -143,7 +135,7 @@ namespace iris::Tests VideoAnalyser videoAnalyser(&configuration); cv::VideoCapture video(sourceVideo); - if (videoAnalyser.VideoIsOpen(sourceVideo, video, nullptr)) + if (videoAnalyser.VideoIsOpen(sourceVideo, video)) { TestVideoAnalysis(videoAnalyser, video, "data/ExpectedVideoLogFiles/extendedFLONG_RELATIVE.csv"); } @@ -155,7 +147,7 @@ namespace iris::Tests VideoAnalyser videoAnalyser(&configuration); cv::VideoCapture video(sourceVideo); - if (videoAnalyser.VideoIsOpen(sourceVideo, video, nullptr)) + if (videoAnalyser.VideoIsOpen(sourceVideo, video)) { TestVideoAnalysis(videoAnalyser, video, "data/ExpectedVideoLogFiles/GradualRedIncrease_RELATIVE.csv"); } @@ -167,7 +159,7 @@ namespace iris::Tests VideoAnalyser videoAnalyser(&configuration); cv::VideoCapture video(sourceVideo); - if (videoAnalyser.VideoIsOpen(sourceVideo, video, nullptr)) + if (videoAnalyser.VideoIsOpen(sourceVideo, video)) { TestVideoAnalysis(videoAnalyser, video, "data/ExpectedVideoLogFiles/gray_RELATIVE.csv"); } @@ -179,9 +171,93 @@ namespace iris::Tests VideoAnalyser videoAnalyser(&configuration); cv::VideoCapture video(sourceVideo); - if (videoAnalyser.VideoIsOpen(sourceVideo, video, nullptr)) + if (videoAnalyser.VideoIsOpen(sourceVideo, video)) { TestVideoAnalysis(videoAnalyser, video, "data/ExpectedVideoLogFiles/intermitentEF_RELATIVE.csv"); } } + + TEST_F(VideoAnalysisTests, RealTime_2Hz_5s_Video_Test) + { + const char* sourceVideo = "data/TestVideos/2Hz_5s.mp4"; + VideoAnalyser videoAnalyser(&configuration); + + cv::VideoCapture video(sourceVideo); + if (videoAnalyser.VideoIsOpen(sourceVideo, video)) + { + TestVideoAnalysis(videoAnalyser, video, "data/ExpectedVideoLogFiles/2Hz_5s_RELATIVE.csv", true); + } + } + + TEST_F(VideoAnalysisTests, RealTime_2Hz_6s_Video_Test) + { + const char* sourceVideo = "data/TestVideos/2Hz_6s.mp4"; + VideoAnalyser videoAnalyser(&configuration); + + cv::VideoCapture video(sourceVideo); + if (videoAnalyser.VideoIsOpen(sourceVideo, video)) + { + TestVideoAnalysis(videoAnalyser, video, "data/ExpectedVideoLogFiles/2Hz_6s_RELATIVE.csv", true); + } + } + + TEST_F(VideoAnalysisTests, RealTime_3Hz_6s_Video_Test) + { + const char* sourceVideo = "data/TestVideos/3Hz_6s.mp4"; + VideoAnalyser videoAnalyser(&configuration); + + cv::VideoCapture video(sourceVideo); + if (videoAnalyser.VideoIsOpen(sourceVideo, video)) + { + TestVideoAnalysis(videoAnalyser, video, "data/ExpectedVideoLogFiles/3Hz_6s_RELATIVE.csv", true); + } + } + + TEST_F(VideoAnalysisTests, RealTime_extendedFLONG_Video_Test) + { + const char* sourceVideo = "data/TestVideos/extendedFLONG.mp4"; + VideoAnalyser videoAnalyser(&configuration); + + cv::VideoCapture video(sourceVideo); + if (videoAnalyser.VideoIsOpen(sourceVideo, video)) + { + TestVideoAnalysis(videoAnalyser, video, "data/ExpectedVideoLogFiles/extendedFLONG_RELATIVE.csv", true); + } + } + + TEST_F(VideoAnalysisTests, RealTime_GradualRedIncrease_Video_Test) + { + const char* sourceVideo = "data/TestVideos/GradualRedIncrease.mp4"; + VideoAnalyser videoAnalyser(&configuration); + + cv::VideoCapture video(sourceVideo); + if (videoAnalyser.VideoIsOpen(sourceVideo, video)) + { + TestVideoAnalysis(videoAnalyser, video, "data/ExpectedVideoLogFiles/GradualRedIncrease_RELATIVE.csv", true); + } + } + + TEST_F(VideoAnalysisTests, RealTime_gray_Video_Test) + { + const char* sourceVideo = "data/TestVideos/gray.mp4"; + VideoAnalyser videoAnalyser(&configuration); + + cv::VideoCapture video(sourceVideo); + if (videoAnalyser.VideoIsOpen(sourceVideo, video)) + { + TestVideoAnalysis(videoAnalyser, video, "data/ExpectedVideoLogFiles/gray_RELATIVE.csv", true); + } + } + + TEST_F(VideoAnalysisTests, RealTime_intermitentEF_Video_Test) + { + const char* sourceVideo = "data/TestVideos/intermitentEF.mp4"; + VideoAnalyser videoAnalyser(&configuration); + + cv::VideoCapture video(sourceVideo); + if (videoAnalyser.VideoIsOpen(sourceVideo, video)) + { + TestVideoAnalysis(videoAnalyser, video, "data/ExpectedVideoLogFiles/intermitentEF_RELATIVE.csv", true); + } + } } \ No newline at end of file diff --git a/utils/include/utils/BaseLog.h b/utils/include/utils/BaseLog.h index b7370ce..d7846de 100644 --- a/utils/include/utils/BaseLog.h +++ b/utils/include/utils/BaseLog.h @@ -40,7 +40,7 @@ namespace EA::EACC::Utils RotatingFileSinkParams(const char* fileName) : fileName(fileName){} const char* fileName = nullptr; - std::size_t max_size = 1024 * 1024; + std::size_t max_size = -1; //set max_size to -1 to allow for unlimited file size std::size_t max_files = 5; bool rotate_on_open = true; };