195 lines
5.4 KiB
C++
195 lines
5.4 KiB
C++
|
|
//************************************************************************
|
||
|
|
/*
|
||
|
|
************************************************************************
|
||
|
|
// Copyright (C) 2003-2006, LPReditor SARL, all rights reserved.
|
||
|
|
// author : Raphael Poulenard.
|
||
|
|
************************************************************************
|
||
|
|
// Line.h: interface for the C_Line class.
|
||
|
|
//
|
||
|
|
This program is free software : you can redistribute itand /or modify
|
||
|
|
it under the terms of the GNU General Public License as published by
|
||
|
|
the Free Software Foundation, either version 3 of the License, or
|
||
|
|
(at your option) any later version.
|
||
|
|
This program is distributed in the hope that it will be useful,
|
||
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
|
||
|
|
GNU General Public License for more details.
|
||
|
|
//////////////////////////////////////////////////////////////////////
|
||
|
|
*/
|
||
|
|
// Line.cpp: implementation of the C_Line class.
|
||
|
|
//
|
||
|
|
//////////////////////////////////////////////////////////////////////
|
||
|
|
#include "Line.h"
|
||
|
|
#ifdef _WINDOWS
|
||
|
|
#endif //_WINDOWS
|
||
|
|
//////////////////////////////////////////////////////////////////////
|
||
|
|
// Construction/Destruction
|
||
|
|
//////////////////////////////////////////////////////////////////////
|
||
|
|
C_Line::C_Line():a(0.0f),b(0.0f)
|
||
|
|
{
|
||
|
|
}
|
||
|
|
//constructeur a partir de deux pts
|
||
|
|
C_Line::C_Line(const cv::Point2f& A,const cv::Point2f& B)
|
||
|
|
{
|
||
|
|
#ifdef _DEBUG
|
||
|
|
//assert(A.x!=B.x);
|
||
|
|
#endif //_DEBUG
|
||
|
|
if(fabsf(A.x-B.x)<FLT_EPSILON) {
|
||
|
|
a=(A.y-B.y)/(A.x-B.x+FLT_EPSILON);
|
||
|
|
b=0.0f;
|
||
|
|
}
|
||
|
|
else {a=(A.y-B.y)/(A.x-B.x);
|
||
|
|
b=A.y-(a*A.x);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
C_Line::C_Line(const C_Line & line_)
|
||
|
|
{
|
||
|
|
a=line_.a;
|
||
|
|
b=line_.b;
|
||
|
|
}
|
||
|
|
C_Line::C_Line(const float & a_,const float & b_):a(a_),b(b_)
|
||
|
|
{
|
||
|
|
}
|
||
|
|
C_Line::~C_Line()
|
||
|
|
{
|
||
|
|
}
|
||
|
|
//retourne le pt d'inter de C_Line avec la dte horiz y=ordonnee
|
||
|
|
float C_Line::get_abs(const int ordonnee) const
|
||
|
|
{
|
||
|
|
#ifdef _DEBUG
|
||
|
|
assert(a!=0.0f);
|
||
|
|
#endif //_DEBUG
|
||
|
|
return (ordonnee-b)/a;
|
||
|
|
}
|
||
|
|
float C_Line::get_abs(const float ordonnee) const
|
||
|
|
{
|
||
|
|
#ifdef _DEBUG
|
||
|
|
assert(a!=0.0f);
|
||
|
|
#endif //_DEBUG
|
||
|
|
return (ordonnee-b)/a;
|
||
|
|
}
|
||
|
|
//retourne l'image de abscisse par la fonction affi,e definie par la droite
|
||
|
|
int C_Line::get_image_entiere(const int abscisse) const
|
||
|
|
{
|
||
|
|
float ordonnee(a*abscisse+b);
|
||
|
|
int ordonne_floor=static_cast<int>(floorf(ordonnee));
|
||
|
|
if (ordonnee-ordonne_floor>0.5f) {
|
||
|
|
//le point le plus proche de la droite est situe au dessus.
|
||
|
|
ordonne_floor++;
|
||
|
|
#ifdef _DEBUG
|
||
|
|
assert(ordonne_floor-ordonnee<0.5f);
|
||
|
|
#endif //_DEBUG
|
||
|
|
}
|
||
|
|
return ordonne_floor;
|
||
|
|
}
|
||
|
|
//retourne l'image de abscisse par la fonction affi,e definie par la droite
|
||
|
|
float C_Line::get_image(const float & abscisse) const
|
||
|
|
{
|
||
|
|
return a*abscisse+b;
|
||
|
|
}
|
||
|
|
//retourne l'image de abscisse par la fonction affi,e definie par la droite
|
||
|
|
float C_Line::get_image(const int abscisse) const
|
||
|
|
{
|
||
|
|
return a*abscisse+b;
|
||
|
|
}
|
||
|
|
bool C_Line::is_nearly_the_same(const C_Line & right_op) const
|
||
|
|
{
|
||
|
|
return (fabs(a-right_op.a)<FLT_EPSILON
|
||
|
|
&& fabs(b-right_op.b)<FLT_EPSILON);
|
||
|
|
}
|
||
|
|
bool C_Line::is_nearly_horiz() const
|
||
|
|
{
|
||
|
|
return (a+0.000001>0.0 && a<0.000001);
|
||
|
|
}
|
||
|
|
void C_Line::reset()
|
||
|
|
{
|
||
|
|
a=0.0f;b=0.0f;
|
||
|
|
}
|
||
|
|
float C_Line::dist_y(const cv::Point& pt) const
|
||
|
|
{
|
||
|
|
//true if the line doesnot have too large slope and not large ordonnee a l'origine
|
||
|
|
if (is_valid()) {
|
||
|
|
return fabsf(pt.y - a * static_cast<float>(pt.x) - b);
|
||
|
|
}
|
||
|
|
else return .0f;
|
||
|
|
}
|
||
|
|
float C_Line::dist_y(const cv::Point2f& pt) const
|
||
|
|
{
|
||
|
|
//true if the line doesnot have too large slope and not large ordonnee a l'origine
|
||
|
|
if (is_valid()) {
|
||
|
|
return fabsf(pt.y - a * static_cast<float>(pt.x) - b);
|
||
|
|
}
|
||
|
|
else return .0f;
|
||
|
|
}
|
||
|
|
//retourne la distance du point
|
||
|
|
// sa projection verticale de la droite
|
||
|
|
float C_Line::difference_y(const cv::Point2f& pt) const
|
||
|
|
{
|
||
|
|
return (pt.y - a * pt.x - b);
|
||
|
|
}
|
||
|
|
//returns the distance of the center point of a box from its vertical projection on the line
|
||
|
|
float C_Line::dist_y_from_center(const cv::Rect& box) const
|
||
|
|
{
|
||
|
|
cv::Point2f pt(box.x + box.width / 2.0f, box.y + box.height / 2.0f);
|
||
|
|
return dist_y(pt);
|
||
|
|
}
|
||
|
|
float C_Line::difference_y_from_center(const cv::Rect& box) const
|
||
|
|
{
|
||
|
|
cv::Point2f pt(box.x + box.width / 2.0f, box.y + box.height / 2.0f);
|
||
|
|
return difference_y(pt);
|
||
|
|
}
|
||
|
|
float C_Line::dist_y_from_center(const std::list<cv::Rect>& boxes) const
|
||
|
|
{
|
||
|
|
float dist = 0.0f;
|
||
|
|
std::list<cv::Rect>::const_iterator it(boxes.begin());
|
||
|
|
while (it != boxes.end()) {
|
||
|
|
dist += dist_y_from_center(*it);
|
||
|
|
it++;
|
||
|
|
}
|
||
|
|
return dist;
|
||
|
|
}
|
||
|
|
float C_Line::difference_y_from_center(const std::list<cv::Rect>& boxes) const
|
||
|
|
{
|
||
|
|
float dist = 0.0f;
|
||
|
|
std::list<cv::Rect>::const_iterator it(boxes.begin());
|
||
|
|
while (it != boxes.end()) {
|
||
|
|
dist += difference_y_from_center(*it);
|
||
|
|
it++;
|
||
|
|
}
|
||
|
|
return dist;
|
||
|
|
}
|
||
|
|
//returns sum of distances of a list of points from their vertical projections on the line
|
||
|
|
float C_Line::dist_y(const std::list<cv::Point2f>& points) const
|
||
|
|
{
|
||
|
|
float dist = 0.0f;
|
||
|
|
std::list<cv::Point2f>::const_iterator it(points.begin());
|
||
|
|
while (it != points.end()) {
|
||
|
|
dist += dist_y(*it);
|
||
|
|
it++;
|
||
|
|
}
|
||
|
|
return dist;
|
||
|
|
}
|
||
|
|
float C_Line::dist_y(const std::list<cv::Point>& points) const
|
||
|
|
{
|
||
|
|
float dist = 0.0f;
|
||
|
|
std::list<cv::Point>::const_iterator it(points.begin());
|
||
|
|
while (it != points.end()) {
|
||
|
|
dist += dist_y(*it);
|
||
|
|
it++;
|
||
|
|
}
|
||
|
|
return dist;
|
||
|
|
}
|
||
|
|
float C_Line::error(const std::list<cv::Rect>& boxes) const
|
||
|
|
{
|
||
|
|
if (boxes.size()) {
|
||
|
|
return dist_y_from_center(boxes) / static_cast<float>(boxes.size());
|
||
|
|
}
|
||
|
|
else return 0.0f;
|
||
|
|
}
|
||
|
|
float C_Line::error(const std::list<cv::Point2f>& points) const
|
||
|
|
{
|
||
|
|
if (points.size()) {
|
||
|
|
return dist_y(points) / static_cast<float>(points.size());
|
||
|
|
}
|
||
|
|
else return 0.0f;
|
||
|
|
}
|