Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
otb
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Antoine Belvire
otb
Commits
7474a1cc
Commit
7474a1cc
authored
19 years ago
by
Caroline Ruffel
Browse files
Options
Downloads
Patches
Plain Diff
nomsg
parent
c63cab75
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
Code/FeatureExtraction/otbLineCorrelationDetector.h
+176
-0
176 additions, 0 deletions
Code/FeatureExtraction/otbLineCorrelationDetector.h
Code/FeatureExtraction/otbLineCorrelationDetector.txx
+367
-0
367 additions, 0 deletions
Code/FeatureExtraction/otbLineCorrelationDetector.txx
with
543 additions
and
0 deletions
Code/FeatureExtraction/otbLineCorrelationDetector.h
0 → 100755
+
176
−
0
View file @
7474a1cc
/*=========================================================================
Programme : OTB (ORFEO ToolBox)
Auteurs : CS - C.Ruffel
Language : C++
Date : 14 mars 2006
Role : Filter of detection of linear features
$Id$
=========================================================================*/
#ifndef __otbLineCorrelationDetector_h
#define __otbLineCorrelationDetector_h
#include
"itkBSplineInterpolateImageFunction.h"
#include
"itkImageToImageFilter.h"
#include
"itkImage.h"
#include
"itkNumericTraits.h"
#define MIN(_A,_B) ((_A) < (_B) ? (_A) : (_B))
#define MAX(_A,_B) ((_A) > (_B) ? (_A) : (_B))
#define ROTATION(_x,_y,_theta,_xout,_yout) \
(_xout) = (_x)*cos(_theta) - (_y)*sin(_theta); \
(_yout) = (_x)*sin(_theta) + (_y)*cos(_theta)
namespace
otb
{
/** \class LineCorrelationDetector
* \brief Application of the filter of detection of linear features
*
* This class implements the Tupin's detector D2 used to detect
* two parallel lines, based on a new edge detector.
*
* The region is devided in three zones to delimite two parallel lines.
* The size of one zone is defined by the product of the width
* of the linear feature by its length.
*
* For each vertical line, we calculate the cross correlation coefficient
* \rho_{ij} between regions i and j.
* \[\rho_{ij}=\fract{1}{1+(n_{i}+n_{j})\fract{n_{i}\gamma_{i}^{2}\bar{c}_{ij}^{2}}{n_{i}n_{j}(\bar{c}_{ij}-1)^{2}} \]
*
* where n_{i} is the pixel number in region i, \bar{c}_{ij} = \fract{\mu_{i}}{\mu_{j}}
* is the empiraical contrast between regions i and j, and \gamma_{i} is the varaition
* coefficient (ratio of standard deviation and mean) that measures homogeneity in
* radar imagery scenes.
*
* The intensity of detection in the three other directions \rho(\theta_{i})
* is determined by rotation of the pixels of each zone around the
* pixel central of the region considered. By default, the pixel location after
* rotation is determined by the Spline interpolator.
*
* Finally, the intensity of detection formed by the two parallel lines
* is determined by the minimum response of a ration edge detector on both sides
* of the linear structure:
* \[\rho = \min(\rho_{12};\rho_{13}) \]
* where \rho_{12} and \rho_{13} are the maximum response of the ratio edge
* detector of \rho(\theta_{i}).
*
* The exit is an image of intensity of detection.
*
*
*/
template
<
class
TInputImage
,
class
TOutputImage
,
class
InterpolatorType
=
itk
::
BSplineInterpolateImageFunction
<
TInputImage
>
>
class
LineCorrelationDetector
:
public
itk
::
ImageToImageFilter
<
TInputImage
,
TOutputImage
>
{
public:
/** Extract dimensions as well of the images of entry of exit. */
itkStaticConstMacro
(
InputImageDimension
,
unsigned
int
,
TInputImage
::
ImageDimension
);
itkStaticConstMacro
(
OutputImageDimension
,
unsigned
int
,
TOutputImage
::
ImageDimension
);
typedef
TInputImage
InputImageType
;
typedef
TOutputImage
OutputImageType
;
/** typedef for the classes standards. */
typedef
LineCorrelationDetector
Self
;
typedef
itk
::
ImageToImageFilter
<
InputImageType
,
OutputImageType
>
Superclass
;
typedef
itk
::
SmartPointer
<
Self
>
Pointer
;
typedef
itk
::
SmartPointer
<
const
Self
>
ConstPointer
;
/** Method for management of the "object factory". */
itkNewMacro
(
Self
);
/** Return the nale of the class. */
itkTypeMacro
(
LineCorrelationDetector
,
ImageToImageFilter
);
/** Typedefs to describe and access Interpolator */
typedef
typename
InterpolatorType
::
Pointer
InterpolatorPointer
;
typedef
typename
InterpolatorType
::
CoordRepType
CoordRepType
;
typedef
typename
InputImageType
::
PointType
TPoint
;
/** Definition of the input and output images */
typedef
typename
InputImageType
::
PixelType
InputPixelType
;
typedef
typename
OutputImageType
::
PixelType
OutputPixelType
;
typedef
typename
InputImageType
::
RegionType
InputImageRegionType
;
typedef
typename
OutputImageType
::
RegionType
OutputImageRegionType
;
/** Definition of the size of the images. */
typedef
typename
InputImageType
::
SizeType
SizeType
;
/** Set the length of the linear feature. */
itkSetMacro
(
LengthLine
,
unsigned
int
);
/** Get the length of the linear feature. */
itkGetConstReferenceMacro
(
LengthLine
,
unsigned
int
);
/** Set the width of the linear feature. */
itkSetMacro
(
WidthLine
,
unsigned
int
);
/** Get the length of the linear feature. */
itkGetConstReferenceMacro
(
WidthLine
,
unsigned
int
);
/** Set the radius of one zone. */
itkSetMacro
(
Radius
,
SizeType
);
/** Get the radius of one zone. */
itkGetConstReferenceMacro
(
Radius
,
SizeType
);
virtual
void
GenerateInputRequestedRegion
()
throw
(
itk
::
InvalidRequestedRegionError
);
protected:
LineCorrelationDetector
();
virtual
~
LineCorrelationDetector
()
{};
void
PrintSelf
(
std
::
ostream
&
os
,
itk
::
Indent
indent
)
const
;
/** LineCorrelationDetector can be implemented for a treatment of filter multithreaded.
* Thus, the ThreadedGenerateData() method is called for each thread process.
* The data image are allocated automatically by the mother class by calling the
* ThreadedGenerateData() method. ThreadedGenerateData can only write the portion
* of the image specified by the parameter "outputRegionForThread"
*
* \sa ImageToImageFilter::ThreadedGenerateData(),
* ImageToImageFilter::GenerateData() */
void
ThreadedGenerateData
(
const
OutputImageRegionType
&
outputRegionForThread
,
int
threadId
);
private
:
LineCorrelationDetector
(
const
Self
&
);
//purposely not implemented
void
operator
=
(
const
Self
&
);
//purposely not implemented
/** Length of the linear feature = 2*m_LengthLine+1 */
unsigned
int
m_LengthLine
;
/** Width of the linear feature = 2*m_WidthLine+1 */
unsigned
int
m_WidthLine
;
/** Radius of the region*/
SizeType
m_Radius
;
/** Size of the facelist*/
SizeType
m_FaceList
;
InterpolatorPointer
m_Interpolator
;
};
}
// end namespace otb
#ifndef OTB_MANUAL_INSTANTIATION
#include
"otbLineCorrelationDetector.txx"
#endif
#endif
This diff is collapsed.
Click to expand it.
Code/FeatureExtraction/otbLineCorrelationDetector.txx
0 → 100755
+
367
−
0
View file @
7474a1cc
/*=========================================================================
Programme : OTB (ORFEO ToolBox)
Auteurs : CS - C.Ruffel
Language : C++
Date : 14 mars 2006
Role : Filter of detection of linear features
$Id$
=========================================================================*/
#ifndef __otbLineCorrelationDetector_txx
#define __otbLineCorrelationDetector_txx
#include "otbLineCorrelationDetector.h"
#include "itkDataObject.h"
#include "itkExceptionObject.h"
#include "itkConstNeighborhoodIterator.h"
#include "itkNeighborhoodInnerProduct.h"
#include "itkImageRegionIterator.h"
#include "itkNeighborhoodAlgorithm.h"
#include "itkZeroFluxNeumannBoundaryCondition.h"
#include "itkProgressReporter.h"
#include <math.h>
#define M_PI 3.14159265358979323846
namespace otb
{
/**
*
*/
template <class TInputImage, class TOutputImage, class InterpolatorType >
LineCorrelationDetector<TInputImage, TOutputImage, InterpolatorType>::LineCorrelationDetector()
{
m_Radius.Fill(1);
m_LengthLine = 1;
m_WidthLine = 0;
m_FaceList.Fill(0);
m_Interpolator = InterpolatorType::New();
}
template <class TInputImage, class TOutputImage, class InterpolatorType>
void LineCorrelationDetector<TInputImage, TOutputImage, InterpolatorType>::GenerateInputRequestedRegion() throw (itk::InvalidRequestedRegionError)
{
// call the superclass' implementation of this method
Superclass::GenerateInputRequestedRegion();
// get pointers to the input and output
typename Superclass::InputImagePointer inputPtr = const_cast< TInputImage * >( this->GetInput() );
typename Superclass::OutputImagePointer outputPtr = this->GetOutput();
if ( !inputPtr || !outputPtr )
{
return;
}
// get a copy of the input requested region (should equal the output
// requested region)
typename TInputImage::RegionType inputRequestedRegion;
inputRequestedRegion = inputPtr->GetRequestedRegion();
// Define the size of the region by the radius
m_Radius[0] = static_cast<unsigned int>(3*m_WidthLine + 2);
m_Radius[1] = m_LengthLine ;
// Define the size of the facelist by taking into account the rotation of the region
m_FaceList[0] = static_cast<unsigned int>( sqrt((m_Radius[0]*m_Radius[0])+ (m_Radius[1]*m_Radius[1]))+1 );
m_FaceList[1] = m_FaceList[0];
// pad the input requested region by the operator radius
inputRequestedRegion.PadByRadius( m_Radius );
// crop the input requested region at the input's largest possible region
if ( inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion()) )
{
inputPtr->SetRequestedRegion( inputRequestedRegion );
return;
}
else
{
// Couldn't crop the region (requested region is outside the largest
// possible region). Throw an exception.
// store what we tried to request (prior to trying to crop)
inputPtr->SetRequestedRegion( inputRequestedRegion );
// build an exception
itk::InvalidRequestedRegionError e(__FILE__, __LINE__);
itk::OStringStream msg;
msg << static_cast<const char *>(this->GetNameOfClass())
<< "::GenerateInputRequestedRegion()";
e.SetLocation(msg.str().c_str());
e.SetDescription("Requested region is (at least partially) outside the largest possible region.");
e.SetDataObject(inputPtr);
throw e;
}
}
template< class TInputImage, class TOutputImage, class InterpolatorType>
void LineCorrelationDetector< TInputImage, TOutputImage, InterpolatorType>
::ThreadedGenerateData(
const OutputImageRegionType& outputRegionForThread,
int threadId
)
{
unsigned int i;
itk::ZeroFluxNeumannBoundaryCondition<InputImageType> nbc;
itk::ConstNeighborhoodIterator<InputImageType> bit;
typename itk::ConstNeighborhoodIterator<InputImageType>::OffsetType off;
itk::ImageRegionIterator<OutputImageType> it;
// Allocate output
typename OutputImageType::Pointer output = this->GetOutput();
typename InputImageType::ConstPointer input = this->GetInput();
m_Interpolator->SetInputImage(input);
// Find the data-set boundary "faces"
typename itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<InputImageType>::FaceListType faceList;
typename itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<InputImageType>::FaceListType::iterator fit;
itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<InputImageType> bC;
faceList = bC(input, outputRegionForThread, m_FaceList);
// support progress methods/callbacks
itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
typename TInputImage::IndexType bitIndex;
typename InterpolatorType::ContinuousIndexType Index;
// --------------------------------------------------------------------------
// Number of direction
const int NB_DIR = 4;
// Number of zone
const int NB_ZONE = 3;
// Definition of the 4 directions
double Theta[NB_DIR];
Theta[0] = 0.;
Theta[1] = M_PI / 4. ;
Theta[2] = M_PI / 2. ;
Theta[3] = 3*M_PI / 4. ;
// Number of the zone
unsigned int zone;
// Pixel numbers in each zone
const int NbPixelZone = (2*m_WidthLine+1)*(2*m_LengthLine+1);
double InvNbPixel = static_cast<double>(1. / NbPixelZone);
// Contains for the 4 directions the sum of the pixels belonging to each zone
double Sum[NB_DIR][NB_ZONE];
double Sum2[NB_DIR][NB_ZONE];
// Mean of zone 1, 2 and 3
double M1, M2, M3;
// Standard deviation
double sigma1, sigma2, sigma3;
// Result of the filter for each direction
double rho12_theta[NB_DIR];
double rho13_theta[NB_DIR];
// Result in one direction
double rho12, rho13;
// Intensity of the linear feature
double rho;
// Pixel location in the input image
int X, Y;
// Value of the pixel
double ValXY = 0.;
// Pixel location after rotation in the system axis of the region
double xout, yout;
// Pixel location in the input image after rotation
TPoint point;
// location of the pixel central in the input image
int Xc, Yc;
// location of the pixel central between zone 1 and 2 and between zone 1 and 3
int Xc12, Xc13;
//---------------------------------------------------------------------------
// Process each of the boundary faces. These are N-d regions which border
// the edge of the buffer.
for (fit=faceList.begin(); fit != faceList.end(); ++fit)
{
bit = itk::ConstNeighborhoodIterator<InputImageType>(m_Radius, input, *fit);
unsigned int neighborhoodSize = bit.Size();
it = itk::ImageRegionIterator<OutputImageType>(output, *fit);
bit.OverrideBoundaryCondition(&nbc);
bit.GoToBegin();
while ( ! bit.IsAtEnd() )
{
//std::cout << "Xc,Yc " << bit.GetIndex() << std::endl;
// Initialisations
for (int dir=0; dir<NB_DIR; dir++)
{
for (int z=0; z<NB_ZONE; z++)
{
Sum[dir][z] = 0.;
Sum2[dir][z] = 0.;
}
}
// Location of the central pixel of the region
bitIndex = bit.GetIndex();
Xc = bitIndex[0];
Yc = bitIndex[1];
// Location of the central pixel between zone 1 and zone 2
Xc12 = Xc - m_WidthLine - 1;
// Location of the central pixel between zone 1 and zone 3
Xc13 = Xc + m_WidthLine + 1;
// Loop on the region
for (i = 0; i < neighborhoodSize; ++i)
{
//std::cout << "---"<< i <<" "<< bit.GetIndex(i)<< std::endl;
//std::cout << "val(X,Y) "<< static_cast<double>(bit.GetPixel(i)) << " " << std::endl;
bitIndex = bit.GetIndex(i);
X = bitIndex[0];
Y = bitIndex[1];
// We determine in the vertical direction with which zone the pixel belongs.
if ( X < Xc12 )
zone = 1;
else if ( ( Xc12 < X ) && ( X < Xc13 ) )
zone = 0;
else if ( X < Xc13 )
zone = 2;
ValXY = static_cast<double>(bit.GetPixel(i));
Sum[0][zone] += ValXY;
Sum2[0][zone] += ValXY*ValXY;
// Loop on the 3 other directions
for ( int dir=1; dir<NB_DIR; dir++ )
{
ROTATION( (X-Xc), (Y-Yc), Theta[dir], xout, yout);
Index[0] = static_cast<CoordRepType>(xout + Xc);
Index[1] = static_cast<CoordRepType>(yout + Yc);
//std::cout << "X' Y' "<< (xout + Xc) << " " << (yout + Yc) << std::endl;
//std::cout << "val(X',Y') "<< static_cast<double>(m_Interpolator->EvaluateAtContinuousIndex( Index )) << std::endl;
ValXY = static_cast<double>(m_Interpolator->EvaluateAtContinuousIndex( Index ));
Sum[dir][zone] += ValXY;
Sum2[dir][zone] += ValXY*ValXY;
}
} // end of the loop on the pixels of the region
rho12 = -1.;
rho13 = -1.;
double NbPixel = static_cast<double>(NbPixelZone);
// Loop on the 4 directions
for ( int dir=0; dir<NB_DIR; dir++ )
{
// Calculation of the mean for the 3 zones
M1 = Sum[dir][0] * InvNbPixel;
M2 = Sum[dir][1] * InvNbPixel;
M3 = Sum[dir][2] * InvNbPixel;
// Calculation of the standard deviation for the 3 zones
sigma1 = sqrt( (Sum2[dir][0] - NbPixel*M1*M1) * InvNbPixel );
sigma2 = sqrt( (Sum2[dir][1] - NbPixel*M2*M2) * InvNbPixel );
sigma3 = sqrt( (Sum2[dir][2] - NbPixel*M3*M3) * InvNbPixel );
// Calculation of the cross correlation coefficient
double d1 = 0.;
double d2 = 0.;
double d3 = 0.;
// rho12
if ( M2 != 0. )
d1 = NbPixel*pow(sigma1,2)*pow(M1/M2,2);
d2 = NbPixel*pow(sigma2,2);
if ( M2 != 0. )
d3 = NbPixel*NbPixel*pow(((M1/M2)-1.),2);
if ( ( M1 != M2 ) )
rho12_theta[dir] = static_cast<double>( 1. / ( 1. + ( 2.*NbPixel*(d1+d2)/d3 ) ) );
else
rho12_theta[dir] = 0.;
// rho13
if ( M3 != 0. )
d1 = NbPixel*pow(sigma1,2)*pow(M1/M3,2);
d2 = NbPixel*pow(sigma3,2);
if ( M3 != 0. )
d3 = NbPixel*NbPixel*pow(((M1/M3)-1.),2);
if ( ( M1 != M3 ) )
rho13_theta[dir] = static_cast<double>( 1. / ( 1. + ( 2.*NbPixel*(d1+d2)/d3 ) ) );
else
rho13_theta[dir] = 0.;
// Determination of the maximum cross correlation coefficients
rho12 = static_cast<double>( MAX( rho12, rho12_theta[dir] ) );
rho13 = static_cast<double>( MAX( rho13, rho13_theta[dir] ) );
} // end of the loop on the directions
// Intensity of the linear feature
rho = MIN ( rho12, rho13 );
// Assignment of this value to the output pixel
it.Set( static_cast<OutputPixelType>(rho) );
++bit;
++it;
progress.CompletedPixel();
}
}
}
/**
* Standard "PrintSelf" method
*/
template <class TInputImage, class TOutput, class InterpolatorType>
void
LineCorrelationDetector<TInputImage, TOutput, InterpolatorType>::PrintSelf(std::ostream& os, itk::Indent indent) const
{
Superclass::PrintSelf( os, indent );
os << indent << "Radius: " << m_Radius << std::endl;
}
} // end namespace otb
#endif
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment