OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. | |
3 * | |
4 * Use of this source code is governed by a BSD-style license | |
5 * that can be found in the LICENSE file in the root of the source | |
6 * tree. An additional intellectual property rights grant can be found | |
7 * in the file PATENTS. All contributing project authors may | |
8 * be found in the AUTHORS file in the root of the source tree. | |
9 */ | |
10 | |
11 #include "webrtc/modules/video_processing/brightness_detection.h" | |
12 | |
13 #include <math.h> | |
14 | |
15 #include "webrtc/modules/video_processing/include/video_processing.h" | |
16 | |
17 namespace webrtc { | |
18 | |
19 VPMBrightnessDetection::VPMBrightnessDetection() { | |
20 Reset(); | |
21 } | |
22 | |
23 VPMBrightnessDetection::~VPMBrightnessDetection() {} | |
24 | |
25 void VPMBrightnessDetection::Reset() { | |
26 frame_cnt_bright_ = 0; | |
27 frame_cnt_dark_ = 0; | |
28 } | |
29 | |
30 int32_t VPMBrightnessDetection::ProcessFrame( | |
31 const VideoFrame& frame, | |
32 const VideoProcessing::FrameStats& stats) { | |
33 if (frame.IsZeroSize()) { | |
34 return VPM_PARAMETER_ERROR; | |
35 } | |
36 int width = frame.width(); | |
37 int height = frame.height(); | |
38 | |
39 if (!VideoProcessing::ValidFrameStats(stats)) { | |
40 return VPM_PARAMETER_ERROR; | |
41 } | |
42 | |
43 const uint8_t frame_cnt_alarm = 2; | |
44 | |
45 // Get proportion in lowest bins. | |
46 uint8_t low_th = 20; | |
47 float prop_low = 0; | |
48 for (uint32_t i = 0; i < low_th; i++) { | |
49 prop_low += stats.hist[i]; | |
50 } | |
51 prop_low /= stats.num_pixels; | |
52 | |
53 // Get proportion in highest bins. | |
54 unsigned char high_th = 230; | |
55 float prop_high = 0; | |
56 for (uint32_t i = high_th; i < 256; i++) { | |
57 prop_high += stats.hist[i]; | |
58 } | |
59 prop_high /= stats.num_pixels; | |
60 | |
61 if (prop_high < 0.4) { | |
62 if (stats.mean < 90 || stats.mean > 170) { | |
63 // Standard deviation of Y | |
64 const uint8_t* buffer = frame.buffer(kYPlane); | |
65 float std_y = 0; | |
66 for (int h = 0; h < height; h += (1 << stats.sub_sampling_factor)) { | |
67 int row = h * width; | |
68 for (int w = 0; w < width; w += (1 << stats.sub_sampling_factor)) { | |
69 std_y += | |
70 (buffer[w + row] - stats.mean) * (buffer[w + row] - stats.mean); | |
71 } | |
72 } | |
73 std_y = sqrt(std_y / stats.num_pixels); | |
74 | |
75 // Get percentiles. | |
76 uint32_t sum = 0; | |
77 uint32_t median_y = 140; | |
78 uint32_t perc05 = 0; | |
79 uint32_t perc95 = 255; | |
80 float pos_perc05 = stats.num_pixels * 0.05f; | |
81 float pos_median = stats.num_pixels * 0.5f; | |
82 float posPerc95 = stats.num_pixels * 0.95f; | |
83 for (uint32_t i = 0; i < 256; i++) { | |
84 sum += stats.hist[i]; | |
85 if (sum < pos_perc05) | |
86 perc05 = i; // 5th perc. | |
87 if (sum < pos_median) | |
88 median_y = i; // 50th perc. | |
89 if (sum < posPerc95) | |
90 perc95 = i; // 95th perc. | |
91 else | |
92 break; | |
93 } | |
94 | |
95 // Check if image is too dark | |
96 if ((std_y < 55) && (perc05 < 50)) { | |
97 if (median_y < 60 || stats.mean < 80 || perc95 < 130 || | |
98 prop_low > 0.20) { | |
99 frame_cnt_dark_++; | |
100 } else { | |
101 frame_cnt_dark_ = 0; | |
102 } | |
103 } else { | |
104 frame_cnt_dark_ = 0; | |
105 } | |
106 | |
107 // Check if image is too bright | |
108 if ((std_y < 52) && (perc95 > 200) && (median_y > 160)) { | |
109 if (median_y > 185 || stats.mean > 185 || perc05 > 140 || | |
110 prop_high > 0.25) { | |
111 frame_cnt_bright_++; | |
112 } else { | |
113 frame_cnt_bright_ = 0; | |
114 } | |
115 } else { | |
116 frame_cnt_bright_ = 0; | |
117 } | |
118 } else { | |
119 frame_cnt_dark_ = 0; | |
120 frame_cnt_bright_ = 0; | |
121 } | |
122 } else { | |
123 frame_cnt_bright_++; | |
124 frame_cnt_dark_ = 0; | |
125 } | |
126 | |
127 if (frame_cnt_dark_ > frame_cnt_alarm) { | |
128 return VideoProcessing::kDarkWarning; | |
129 } else if (frame_cnt_bright_ > frame_cnt_alarm) { | |
130 return VideoProcessing::kBrightWarning; | |
131 } else { | |
132 return VideoProcessing::kNoWarning; | |
133 } | |
134 } | |
135 | |
136 } // namespace webrtc | |
OLD | NEW |