Fawkes API  Fawkes Development Version
threshold.h
1 /***************************************************************************
2  * threshold.h - Determine whether a given YUV chroma value is "similar" to
3  * a certain reference color, according to defined chroma and saturation
4  * thresholds.
5  *
6  * The algorithm is ported from the VLC colorthreshold filter written by
7  * Sigmund Augdal and Antoine Cellerier. Cf.
8  * modules/video_filter/colorthres.c in the VLC source tree.
9  *
10  * Initially ported in 2014 by Victor MatarĂ©.
11  *
12  * The original code is licensed under GPL 2.1, so we do the same.
13  ****************************************************************************/
14 
15 /* This program is free software; you can redistribute it and/or modify
16  * it under the terms of the GNU General Public License as published by
17  * the Free Software Foundation; either version 2 of the License, or
18  * (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23  * GNU Library General Public License for more details.
24  *
25  * Read the full text in the LICENSE.GPL file in the doc directory.
26  */
27 
28 #ifndef _FIREVISION_UTILS_COLOR_THRESHOLD_H_
29 #define _FIREVISION_UTILS_COLOR_THRESHOLD_H_
30 
31 #include <sys/types.h>
32 
33 #include <cmath>
34 
35 namespace firevision {
36 
37 /** Determine if two colors are similar - ATTENTION:
38  * All u/v values have to be normalized to -127..128, NOT the usual 0..255!
39  * Otherwise the similarity calculation won't work.
40  * @param u YUV observed color U value
41  * @param v YUV observed color V value
42  * @param ref_u YUV reference color U value
43  * @param ref_v YUV reference color V value
44  * @param ref_length Length of the (rev_u, ref_v) vector in 2D chroma space.
45  * Caller should precompute this for performance reasons (pythagoras!).
46  * @param chroma_thresh Maximum chroma difference
47  * @param sat_thresh Minimum saturation
48  * @return true if color (u, v) is similar to (ref_u, ref_v), false otherwise.
49  */
50 inline bool
51 is_similar(int u, int v, int ref_u, int ref_v, int ref_length, int chroma_thresh, int sat_thresh)
52 {
53  int length = sqrt(u * u + v * v);
54 
55  int diffu, diffv;
56  int64_t difflen2, thres;
57 
58  diffu = ref_u * length - u * ref_length;
59  diffv = ref_v * length - v * ref_length;
60  difflen2 = diffu * diffu + diffv * diffv;
61  thres = (int64_t)length * ref_length;
62  thres *= thres;
63 
64  return (length > sat_thresh) && (difflen2 * chroma_thresh < thres);
65 }
66 
67 inline bool
68 is_similar_y(int y,
69  int u,
70  int v,
71  int ref_y,
72  int ref_u,
73  int ref_v,
74  int ref_length,
75  int chroma_thresh,
76  int sat_thresh,
77  int y_thresh)
78 {
79  return is_similar(u, v, ref_u, ref_v, ref_length, chroma_thresh, sat_thresh)
80 #if defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || (__GNUC__ > 4))
81  && std::abs(y - ref_y) < (255 - y_thresh);
82 #else
83  && ((y - ref_y) < 0 ? -1 * (y - ref_y) : (y - ref_y)) < (255 - y_thresh);
84 #endif
85 }
86 } // namespace firevision
87 
88 #endif /* FIREVISION_UTILS_COLOR_THRESHOLD_H__ */