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 <cmath>
32 #include <sys/types.h>
33 
34 namespace firevision {
35 
36 /** Determine if two colors are similar - ATTENTION:
37  * All u/v values have to be normalized to -127..128, NOT the usual 0..255!
38  * Otherwise the similarity calculation won't work.
39  * @param u YUV observed color U value
40  * @param v YUV observed color V value
41  * @param ref_u YUV reference color U value
42  * @param ref_v YUV reference color V value
43  * @param ref_length Length of the (rev_u, ref_v) vector in 2D chroma space.
44  * Caller should precompute this for performance reasons (pythagoras!).
45  * @param chroma_thresh Maximum chroma difference
46  * @param sat_thresh Minimum saturation
47  * @return true if color (u, v) is similar to (ref_u, ref_v), false otherwise.
48  */
49 inline bool is_similar(int u, int v, int ref_u, int ref_v, int ref_length, int chroma_thresh, int sat_thresh) {
50  int length = sqrt(u * u + v * v);
51 
52  int diffu, diffv;
53  int64_t difflen2, thres;
54 
55  diffu = ref_u * length - u * ref_length;
56  diffv = ref_v * length - v * ref_length;
57  difflen2 = diffu * diffu + diffv * diffv;
58  thres = length * ref_length;
59  thres *= thres;
60 
61  return (length > sat_thresh) && (difflen2 * chroma_thresh < thres);
62 }
63 
64 inline bool is_similar_y(int y, int u, int v,
65  int ref_y, int ref_u, int ref_v,
66  int ref_length, int chroma_thresh, int sat_thresh, int y_thresh) {
67 
68  return is_similar(u, v, ref_u, ref_v, ref_length, chroma_thresh, sat_thresh)
69 #if defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || (__GNUC__ > 4))
70  && std::abs(y - ref_y) < (255 - y_thresh);
71 #else
72  && ((y-ref_y) < 0 ? -1*(y-ref_y) : (y-ref_y)) < (255 - y_thresh);
73 #endif
74 }
75 }
76 
77 #endif /* __FIREVISION_UTILS_COLOR_THRESHOLD_H_ */