Fawkes API Fawkes Development Version
hv_search.cpp
1
2/***************************************************************************
3 * hv_search.cpp - Implementation of horizontal- and vertical-search filter
4 *
5 * Created: Tue Jul 12 14:40:40 2005
6 * Copyright 2005-2007 Tim Niemueller [www.niemueller.de]
7 * 2005 Yuxiao Hu (Yuxiao.Hu@rwth-aachen.de)
8 *
9 ****************************************************************************/
10
11/* This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version. A runtime exception applies to
15 * this software (see LICENSE.GPL_WRE file mentioned below for details).
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Library General Public License for more details.
21 *
22 * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
23 */
24
25#include <fvfilters/hv_search.h>
26#include <fvutils/color/yuv.h>
27
28#include <cstddef>
29#include <cstring>
30
31namespace firevision {
32
33/** @class FilterHVSearch <fvfilters/hv_search.h>
34 * Horizontal/vertical search filter.
35 * This filter works similar to the horizontal search filter, but additionally
36 * it search for color changes in vertical direction.
37 * @author Yuxiao Hu
38 * @author Tim Niemueller
39 */
40
41/** Constructor.
42 * @param cm color model to use to determine the color change
43 * @param what what to look for, this color is considered as foreground,
44 * all other colors are background.
45 */
46FilterHVSearch::FilterHVSearch(ColorModel *cm, color_t what) : Filter("FilterHVSearch")
47{
48 this->cm = cm;
49 this->what = what;
50}
51
52void
54{
55 unsigned int h = 0;
56 unsigned int w = 0;
57
58 unsigned int width = src_roi[0]->width <= dst_roi->width ? src_roi[0]->width : dst_roi->width;
59
60 // Here use array to avoid overhead of dynamic mem allocation.
61 unsigned int top[width];
62 unsigned int bottom[width];
63 bool vflag[width];
64
65 // y-plane
66 unsigned char *yp = src[0] + (src_roi[0]->start.y * src_roi[0]->line_step)
67 + (src_roi[0]->start.x * src_roi[0]->pixel_step);
68 // u-plane
69 unsigned char *up =
70 YUV422_PLANAR_U_PLANE(src[0], src_roi[0]->image_width, src_roi[0]->image_height)
71 + ((src_roi[0]->start.y * src_roi[0]->line_step) / 2
72 + (src_roi[0]->start.x * src_roi[0]->pixel_step) / 2);
73 // v-plane
74 unsigned char *vp =
75 YUV422_PLANAR_V_PLANE(src[0], src_roi[0]->image_width, src_roi[0]->image_height)
76 + ((src_roi[0]->start.y * src_roi[0]->line_step) / 2
77 + (src_roi[0]->start.x * src_roi[0]->pixel_step) / 2);
78
79 // destination y-plane
80 unsigned char *dyp =
82
83 // line starts
84 unsigned char *lyp = yp; // y-plane
85 unsigned char *lup = up; // u-plane
86 unsigned char *lvp = vp; // v-plane
87 unsigned char *ldyp = dyp; // destination y-plane
88
89 // left and right boundary of the current line
90 unsigned int left;
91 unsigned int right;
92 bool flag;
93
94 // Confidence threshold for a line as "what" inside.
95 const unsigned int MIN_INTERIA = 9;
96 unsigned int num_what;
97
98 // Remember the widest orange line,
99 // and if the following lines shrink dramatically,
100 // we stop searching. This help eliminate reflextion.
101 const unsigned int MAX_SHRINK = 16;
102 unsigned int max_width = 0;
103 bool not_reflect = true;
104
105 memset(top, 0, width * sizeof(unsigned int));
106 memset(bottom, 0, width * sizeof(unsigned int));
107 memset(vflag, 0, width * sizeof(bool));
108
109 for (h = 0; (h < src_roi[0]->height) && (h < dst_roi->height); ++h) {
110 flag = false;
111 left = right = 0;
112 num_what = 0;
113 for (w = 0; (w < src_roi[0]->width) && (w < dst_roi->width); ++w) {
114 if ((cm->determine(*yp++, *up, *vp) == what)) {
115 right = w;
116 if (not_reflect)
117 bottom[w] = h;
118 flag = true;
119 vflag[w] = true;
120 ++num_what;
121 } else {
122 left = flag ? left : w;
123 if (!vflag[w])
124 top[w] = h;
125 }
126 if ((cm->determine(*yp++, *up++, *vp++) == what)) {
127 right = ++w;
128 if (not_reflect)
129 bottom[w] = h;
130 flag = true;
131 vflag[w] = true;
132 ++num_what;
133 } else {
134 ++w;
135 left = flag ? left : w;
136 if (!vflag[w])
137 top[w] = h;
138 }
139 }
140
141 // clear the dst buffer for this line
142 memset(ldyp, 0, dst_roi->width);
143
144 if (num_what * MIN_INTERIA > right - left) {
145 if (right - left > max_width)
146 max_width = right - left;
147 if (not_reflect) {
148 if (right - left < max_width / MAX_SHRINK) {
149 // cout << "In line:" << h << " \tleft = " << left
150 // << " \tright = " << right << " \tmax_width = "
151 // << max_width << endl;
152 not_reflect = false; // the reflection begins from here
153 }
154
155 // set the left- and right-most pixel to white
156 // but if the pixel is at the boundary, we ignore it
157 // in order to eliminate a straight line at the border.
158 if (left != 0 && left < dst_roi->width - 1) {
159 ldyp[left] = 255;
160 // ldyp[left+1] = 255;
161 }
162 if (right != 0 && right < dst_roi->width - 1) {
163 ldyp[right] = 255;
164 // ldyp[right-1] = 255;
165 }
166 }
167 }
168
169 lyp += src_roi[0]->line_step;
170 lup += src_roi[0]->line_step / 2;
171 lvp += src_roi[0]->line_step / 2;
172 ldyp += dst_roi->line_step;
173 yp = lyp;
174 up = lup;
175 vp = lvp;
176 dyp = ldyp;
177 }
178 for (w = 0; w < dst_roi->width; w++) {
179 if (top[w] != 0 && top[w] != dst_roi->height - 1)
180 *(dst + ((dst_roi->start.y + top[w]) * dst_roi->line_step)
181 + ((dst_roi->start.x + w) * dst_roi->pixel_step)) = 255;
182 if (bottom[w] != 0 && bottom[w] != dst_roi->height - 1)
183 *(dst + ((dst_roi->start.y + bottom[w]) * dst_roi->line_step)
184 + ((dst_roi->start.x + w) * dst_roi->pixel_step)) = 255;
185 }
186}
187
188} // end namespace firevision
Color model interface.
Definition: colormodel.h:32
virtual color_t determine(unsigned int y, unsigned int u, unsigned int v) const =0
Determine classification of YUV pixel.
virtual void apply()
Apply the filter.
Definition: hv_search.cpp:53
FilterHVSearch(ColorModel *cm, color_t what)
Constructor.
Definition: hv_search.cpp:46
Filter interface.
Definition: filter.h:33
ROI ** src_roi
Source ROIs, dynamically allocated by Filter ctor.
Definition: filter.h:66
unsigned char ** src
Source buffers, dynamically allocated by Filter ctor.
Definition: filter.h:61
unsigned char * dst
Destination buffer.
Definition: filter.h:63
ROI * dst_roi
Destination ROI.
Definition: filter.h:68
unsigned int height
ROI height.
Definition: roi.h:119
fawkes::upoint_t start
ROI start.
Definition: roi.h:115
unsigned int line_step
line step
Definition: roi.h:125
unsigned int width
ROI width.
Definition: roi.h:117
unsigned int pixel_step
pixel step
Definition: roi.h:127
unsigned int x
x coordinate
Definition: types.h:36
unsigned int y
y coordinate
Definition: types.h:37