26 #include <fvmodels/shape/rht_circle.h> 34 #define TEST_IF_IS_A_PIXEL(x) ((x)>230) 36 #define TBY_SQUARED_DIST(x1,y1,x2,y2) \ 37 (((x1)-(x2))*((x1)-(x2))+((y1)-(y2))*((y1)-(y2))) 38 #define TBY_RADIUS_DIFF(x1, y1, x2, y2, r) \ 39 (sqrt(((x1)-(x2))*((x1)-(x2))+((y1)-(y2))*((y1)-(y2))-(r)*(r))) 47 const float RhtCircleModel::RHT_MIN_RADIUS = 40.0;
48 const float RhtCircleModel::RHT_MAX_RADIUS = 500.0;
55 RhtCircleModel::RhtCircleModel(
void)
61 RhtCircleModel::~RhtCircleModel(
void)
72 RhtCircleModel::parseImage(
unsigned char* buf,
79 vector<upoint_t> pixels;
80 struct timeval start, end;
89 const int RHT_MAX_TIME = 10000;
90 const int RHT_MAX_ITER = 1000;
93 const float RHT_MIN_VOTE_RATE = 0.0f;
96 const int RHT_XY_SCALE = 8;
97 const int RHT_RADIUS_SCALE= 8;
101 const float RHT_FITTING_DIST_DIFF = 15.0f;
104 const float ROI_HOLLOW_RATE = 0.70f;
106 const unsigned int roi_hollow_top = (int)(roi->
height * ((1.0f - ROI_HOLLOW_RATE) / 2));
107 const unsigned int roi_hollow_bottom = roi->
height - roi_hollow_top;
108 const unsigned int roi_hollow_left = (int)(roi->
width * ((1.0f - ROI_HOLLOW_RATE) / 2));
109 const unsigned int roi_hollow_right = roi->
width - roi_hollow_left;
114 unsigned char *line_start = buffer;
116 gettimeofday(&start, NULL);
117 end.tv_usec = start.tv_usec;
120 for (y = 0; y < roi_hollow_top; ++y) {
121 for (x = 0; x < roi->
width; ++x) {
122 if (TEST_IF_IS_A_PIXEL(*buffer)) {
124 pixels.push_back(pt);
133 for (y = roi_hollow_top; y < roi_hollow_bottom; ++y) {
134 for (x = 0; x < roi_hollow_left; ++x) {
135 if (TEST_IF_IS_A_PIXEL(*buffer)) {
137 pixels.push_back(pt);
142 buffer+=(roi_hollow_right - roi_hollow_left);
143 for (x = roi_hollow_right; x < roi->
width; ++x) {
144 if (TEST_IF_IS_A_PIXEL(*buffer)) {
146 pixels.push_back(pt);
155 for (y = roi_hollow_bottom; y < roi->
height; ++y) {
156 for (x = 0; x < roi->
width; ++x) {
157 if (TEST_IF_IS_A_PIXEL(*buffer)) {
159 pixels.push_back(pt);
172 vector< upoint_t >::iterator pos;
174 int num_points = (int) pixels.size();
175 if (num_points == 0) {
180 while( (num_iter++ < RHT_MAX_ITER) &&
181 ( ((end.tv_usec - start.tv_usec) < RHT_MAX_TIME) ||
182 ((end.tv_usec + 1000000 - start.tv_usec) < RHT_MAX_TIME) )
187 for (
int i=0; i < 3; ++i) {
188 int ri = rand() % num_points;
189 pos = pixels.begin() + ri;
195 calcCircle(p[0], p[1], p[2], center, radius);
198 if (radius > RHT_MIN_RADIUS && radius < RHT_MAX_RADIUS) {
199 accumulator.accumulate((
int)(center.
x / RHT_XY_SCALE),
200 (
int)(center.
y / RHT_XY_SCALE),
201 (
int)(radius / RHT_RADIUS_SCALE));
204 gettimeofday(&end, NULL);
208 int max, x_max, y_max, r_max;
209 max = accumulator.getMax(x_max, y_max, r_max);
211 cout <<
"Max vote is with " << max <<
" of the " << num_iter <<
" ones." << endl;
214 if (max > num_iter * RHT_MIN_VOTE_RATE)
217 center.
x = (float)(x_max * RHT_XY_SCALE + RHT_XY_SCALE/2);
218 center.
y = (float)(y_max * RHT_XY_SCALE + RHT_XY_SCALE/2);
219 float c_r = (float)(r_max * RHT_RADIUS_SCALE + RHT_RADIUS_SCALE/2);
222 for(vector< upoint_t >::iterator pos = pixels.begin(); pos != pixels.end(); )
224 if (TBY_RADIUS_DIFF(pos->x, pos->y, center.
x, center.
y, c_r)
225 > RHT_FITTING_DIST_DIFF)
238 m_Circles.push_back(c);
256 RhtCircleModel::getShapeCount(
void)
const 258 return m_Circles.size();
262 RhtCircleModel::getShape(
int id)
const 264 if (
id < 0 || (
unsigned int)
id >= m_Circles.size()) {
267 return const_cast<Circle*
>(&m_Circles[id]);
273 RhtCircleModel::getMostLikelyShape(
void)
const 275 if (m_Circles.size() == 0) {
277 }
else if (m_Circles.size() == 1) {
278 return const_cast<Circle*
>(&m_Circles[0]);
281 for (
unsigned int i=1; i < m_Circles.size(); ++i) {
282 if (m_Circles[i].count > m_Circles[cur].count) {
286 return const_cast<Circle*
>(&m_Circles[cur]);
292 RhtCircleModel::calcCircle(
302 const int &x1=p1.
x, &y1=p1.
y, &x2=p2.
x, &y2=p2.
y, &x3=p3.
x, &y3=p3.
y;
304 int div = 2*((x2-x1)*(y3-y1)-(x3-x1)*(y2-y1));
312 center.
x = ((float)((x2*x2+y2*y2-x1*x1-y1*y1)*(y3-y1)
313 -(x3*x3+y3*y3-x1*x1-y1*y1)*(y2-y1))
315 center.
y = ((float)((x2-x1)*(x3*x3+y3*y3-x1*x1-y1*y1)
316 -(x3-x1)*(x2*x2+y2*y2-x1*x1-y1*y1))
320 radius = (float)sqrt(dx*dx+dy*dy);
Fawkes library namespace.
unsigned int y
y coordinate
unsigned int x
x coordinate
unsigned int width
ROI width.
unsigned char * get_roi_buffer_start(unsigned char *buffer) const
Get ROI buffer start.
Point with cartesian coordinates as unsigned integers.
void fitCircle(std::vector< fawkes::upoint_t > &points)
Fit circle.
unsigned int height
ROI height.
unsigned int line_step
line step
int count
Number of pixels.