Per-platform colour-border sensitivity (Teams violet, Meet glow)
Cross-platform research (Grant) flagged that the colour-border cue differs by app; checking the real brand colours against the detector found a concrete bug: the global 0.5 saturation threshold MISSES Teams' violet ring (#6264A7 ≈ 0.41, light variants ~0.27) entirely and Meet's lighter blue glow (#8ab4f8 ≈ 0.44). Those adapters would have detected nothing. - FrameSampler.saturatedPoints: add a tunable threshold + optional hue-band gate (degrees) so a lowered threshold doesn't pick up warm video. - GridCallAnalyzer.Config: colorSaturation / colorMinBrightness / colorHueRange, plumbed to the colour-border path (defaults preserve prior behaviour). - MeetAdapter sat→0.35 (catch the glow); TeamsAdapter sat→0.22 + hue 215–275° (catch the faint violet, reject other colours); ZoomAdapter sat 0.45 + hue 40–150° (vivid green/yellow). Values are first-pass pending real-fixture calibration; the hue gate is the main calibration lever. Tests: Teams now detects the faint violet ring and rejects a green one; Meet/Zoom vivid cases still pass. 27/27 XCTest.
This commit is contained in:
@@ -117,6 +117,24 @@ final class GridCallAnalyzerTests: XCTestCase {
|
||||
XCTAssertEqual(speaking, ["ALEX"])
|
||||
}
|
||||
|
||||
func testTeamsDetectsFaintVioletRing() {
|
||||
// Teams' brand violet #6264A7 is only ~0.41 saturation — below the 0.5
|
||||
// default that Meet/Zoom inherited. The Teams adapter lowers the threshold,
|
||||
// so it must still pick the ring.
|
||||
let violet = CGColor(red: 0.384, green: 0.392, blue: 0.655, alpha: 1)
|
||||
let obs = TeamsAdapter().analyze(cgImage: coloredFrame(speakingIndex: 2, border: violet), at: 0) // DMITRI
|
||||
let speaking = Set(obs.filter { $0.speaking }.map { $0.name })
|
||||
XCTAssertEqual(speaking, ["DMITRI"])
|
||||
}
|
||||
|
||||
func testTeamsHueGateRejectsWrongColourBorder() {
|
||||
// A green border (wrong hue for Teams) must NOT register — the violet hue
|
||||
// gate is what keeps the lowered threshold from catching warm/other content.
|
||||
let green = CGColor(red: 0.2, green: 0.85, blue: 0.3, alpha: 1)
|
||||
let obs = TeamsAdapter().analyze(cgImage: coloredFrame(speakingIndex: 0, border: green), at: 0)
|
||||
XCTAssertTrue(obs.filter { $0.speaking }.isEmpty)
|
||||
}
|
||||
|
||||
func testWhiteBorderDetectorIgnoresColouredBorder() {
|
||||
// Signal looks only for the white border, so a coloured (Meet) border must
|
||||
// not register as a Signal speaker.
|
||||
|
||||
Reference in New Issue
Block a user