About 1 in 4,000 people in the world are affected by photosensitive epilepsy, and general photosensitivity affects even more than that. While the UK has guidelines to prevent bright flashing in television broadcasts, this isn't true of the rest of the world.
A Harding test is a type of program that tries to automatically detect when a video can cause seizures from flashing lights and patterns. Nopelepsy is a type of Harding test, but with a twist: Nopelepsy also has the ability to automatically edit video frames to remove the flashes it detects.
Nopelepsy isn't complete, and isn't perfect, but it's a start in the right direction. It's also experimental, so use at your own risk.
You will need nlohmann::json and the ffmpeg libraries to build. You will need to put the headers in an
external\ or your compiler's default search directory. Static OpenCL libs go in a
lib\ directory, or your default one.
To build, open cmd and run
shell.bat to set the temporary cl.exe env variables. Then run
compile.bat. The generated exe will be in
To begin using, you must generate a settings file for Nopelepsy to use. Do this with
To use the generated settings file, give the arguments
-s [settings-file] to the program.
Before running Nopelepsy on any videos, run
nopelepsy -s [settings-file] -test
and observe the output. If there are any failures, then something has gone horribly wrong, and you shouldn't try to use it.
At this moment, only webm video files are supported by Nopelepsy. To invoke the cli tool, make sure the Nopelepsy executable is in your PATH or current working directory and do
nopelepsy -s [settings-file] [path/to/webm/video]
Here's an explanation some of the settings fields:
percentage_thresh(float): The percentage of a 10 degree field of view that needs to be flashing concurrently in order to trigger the detector. Default is 0.25, and should probably never exceed 0.5.
luminance_thresh(float): The change in brightness of a flash that needs to occur in order to trigger the detector. Default is 0.1.
reduction_iters(int): The maximum amount of iterations to spend minimizing the amount of screen space to change. This number does not effect the safety of the program, but does effect the performance. Higher numbers result in higher quality, but are less performant, and -1 stands for no upper bound.
max_flash_size(float): The size, in seconds, of the maximum detectable flash. Lower numbers increase performance, but also increase risk. See below for more details. Default is 1.0.
block_size(int): Size of local buckets to process together. If you want to increase performance of Nopelepsy, increase this number first. This should not effect the safety of the program.
display_frames(bool): Whether or not to display the output frames. This actually decreases the efficiency of the program by a significant amount.
other fields will have documentation added later.
max_flash_size are the only ones above that should affect the safety of the software. The default settings for the first two come from this W3C spec. The
luminance_thresh value may have to change, depending on the brightness of your TV/monitor.
The default for the
max_flash_size is by far the most personal field. The default value comes from me playing around with the number and consulting with someone who is very sensitive to flashes. For most situations, the default setting of 1.0 is overkill, and 0.4 works well and has a higher-quality output. However other situations, like this harry potter scene seem to require a setting of at least 0.75 to get rid of all flashes.
However, there are other people for which flashes aren't as painful, and so a much lower number like 0.2 (max 5-frame flash at 24fps) might be acceptable. Keep in mind that videos have framerates, and that the detector is limited by the Nyquist frequency, and so the minimum effective parameter is
2/framerate, which is usually either 0.09 or 0.03 for 24fps and 60fps video respectively.
A standalone C++ API will be coming later.
Questions I haven't been asked yet, but I forsee being asked
Why are all flashes getting removed, and not just strobes?
For one thing, it's much easier this way. It's a whole other can of worms to try to find out what flashes constitute "near each other" in order to remove them.
Also, many people who are photosensitve and/or epileptic feel physical pain when seeing a flash of light, even if it's not enough to cause a seizure. If it's easier to fix both the seizures and the pain than it is to fix just the seizures, then why not do both?
I plan on adding functionality at some point to be able to switch to only multiple flash detection. But again, bigger fish to fry.
I used Nopelepsy to remove the flashes from a Star Wars movie, and there were still painful red flashes! What gives?
Yeah, so.... That's a known issue, but I don't know how to fix that.
The W3C spec defines flashes to happen in the presence of general light, and separately in the presence of saturated reds. The problem is that certain types of motion are definitely flashes, but aren't bright enough or red enough to qualify. It's possible that a future motion detector might do the trick, but I haven't been able to get it to work.
Does this software detect and remove saturated red flashes? What about harmful patters, like moving stripes of polka dots?
Not yet. Haven't gotten around to implementing either of those.
Why are you using the W3C spec instead of the Ofcom guidelines?
The W3C spec is more useful. It gives the parameters in terms of steradians and percentages, instead of areas of the screen. This extends well to different sized TVs and monitors.
One annoying thing about the W3C spec though is that it references a paper by Harding that supposedly lays out these guidelines, but I can't for the life of me find a copy of it anywhere.
Where do I begin? In no particular order:
- OSX and Linux builds. (if there's any otool wranglers out there willing to help with the OSX build, please get in touch)
- Red/other color flash detection (this will require more research)
- Cleaning algorithm
- Dynamic block sizes
- Dual brightness modification
- Or better yet, correction using motion and object tracking instead
- Different modes
- Only multiple flashes
- Reactive/predictive mode