diff --git a/Code/ChangeDetection/otbBinaryFunctorNeighborhoodImageFilter.txx b/Code/ChangeDetection/otbBinaryFunctorNeighborhoodImageFilter.txx index 3776864e49323e9aa09845969902fd4674e95d80..59842a04b02b4492dadaaa4f757959f5def1e54b 100755 --- a/Code/ChangeDetection/otbBinaryFunctorNeighborhoodImageFilter.txx +++ b/Code/ChangeDetection/otbBinaryFunctorNeighborhoodImageFilter.txx @@ -126,7 +126,7 @@ BinaryFunctorNeighborhoodImageFilter<TInputImage1, TInputImage2, TOutputImage, T { neighInputIt1 = itk::ConstNeighborhoodIterator<TInputImage1>(r1, inputPtr1, *fit1); neighInputIt2 = itk::ConstNeighborhoodIterator<TInputImage2>(r1, inputPtr2, *fit2); - outputIt = itk::ImageRegionIterator<TOutputImage>(outputPtr, outputRegionForThread); + // outputIt = itk::ImageRegionIterator<TOutputImage>(outputPtr, outputRegionForThread); outputIt = itk::ImageRegionIterator<TOutputImage>(outputPtr, *fit1); neighInputIt1.OverrideBoundaryCondition(&nbc1); diff --git a/Code/FeatureExtraction/otbNeighborhoodScalarProductFilter.h b/Code/FeatureExtraction/otbNeighborhoodScalarProductFilter.h index 7819b5072feadaa34d90029fb59e2c7b1ac5d4ab..4ec97740e71f75068cfe1cff1da39acfe0347418 100644 --- a/Code/FeatureExtraction/otbNeighborhoodScalarProductFilter.h +++ b/Code/FeatureExtraction/otbNeighborhoodScalarProductFilter.h @@ -23,8 +23,25 @@ PURPOSE. See the above copyright notices for more information. namespace otb { /** \class NeighborhoodScalarProductFilter - * \brief + * \brief This filter is designed to be part of a pipeline aiming at linear feature extraction, such as roads. * + * This filter takes as input a two-band image resulting from a gradient operator. The first channel contains + * the gradient value in the first image direction, the second contains the gradient value in the second image direction. + * + * Assuming that the linear feature we want to detect is darker than its surrounding environnement, we can deduce that + * the gradient direction will be opposite on each side of the road. Therefore, we compute for each pixel to compute the scalar + * product of the gradient vector for each opposite pixels in the neighborhood of radius 1 of the pixel to compute. + * + * The lower negativ scalar product value along these four pairs of pixel gives us the direction in which there is most + * likely a linear feature. + * + * This filters has two outputs : + * - The first output (from the GetOutput() method) gives the modulus of the lower negativ scalar product value for this pixel. + * - The second output (from the GetOutputDirection() method) gives the direction in radian of this linear feature. + * + * Please note that there are only 8 possible values for the direction image, corresponding to two directions for each pair of opposite + * pixels. In our conventions, negatives angle values represent opposite gradient vectors, whereas positive angle values represent convergent + * gradient vectors. * \ingroup Streamed * \ingroup Threaded */ diff --git a/Code/FeatureExtraction/otbNeighborhoodScalarProductFilter.txx b/Code/FeatureExtraction/otbNeighborhoodScalarProductFilter.txx index 9b4e80e7325228898bca84c2d59f71f0646f24df..2806b8bc653251c4f3a0917c1e46a2127a2adc4d 100644 --- a/Code/FeatureExtraction/otbNeighborhoodScalarProductFilter.txx +++ b/Code/FeatureExtraction/otbNeighborhoodScalarProductFilter.txx @@ -72,8 +72,8 @@ NeighborhoodScalarProductFilter<TInputImage,TOutputModulus,TOutputDirection> for (fit=faceList.begin(); fit != faceList.end(); ++fit) { NeighborhoodIteratorType neighInputIt(r, inputPtr, *fit); - OutputIteratorType outputIt(outputPtr,outputRegionForThread); - OutputDirectionIteratorType outputDirIt(outputDirPtr,outputRegionForThread); + OutputIteratorType outputIt(outputPtr,*fit); + OutputDirectionIteratorType outputDirIt(outputDirPtr,*fit); neighInputIt.GoToBegin(); outputIt.GoToBegin(); outputDirIt.GoToBegin(); @@ -122,7 +122,7 @@ NeighborhoodScalarProductFilter<TInputImage,TOutputModulus,TOutputDirection> InputPixelType pixel2 = neighInputIt.GetPixel(offset2); // Compute the scalar product - scalarCurrentValue = - (pixel1[0]*pixel2[0]+pixel1[1]*pixel2[1]); + scalarCurrentValue = -(pixel1[0]*pixel2[0]+pixel1[1]*pixel2[1]); // If the value is upper than the current max value if (scalarCurrentValue > scalarMaxValue) diff --git a/Testing/Code/FeatureExtraction/CMakeLists.txt b/Testing/Code/FeatureExtraction/CMakeLists.txt index 2e2623b9a4b262a6d7775c99e57760be14f6406a..0e0c0ab189db95250095b20d23812368a36eae34 100755 --- a/Testing/Code/FeatureExtraction/CMakeLists.txt +++ b/Testing/Code/FeatureExtraction/CMakeLists.txt @@ -493,11 +493,11 @@ ADD_TEST(feTuNeighborhoodScalarProductFilterNew ${FEATUREEXTRACTION_TESTS} otbNeighborhoodScalarProductFilterNew) ADD_TEST(feTvNeighborhoodScalarProductFilter ${FEATUREEXTRACTION_TESTS} -# --compare-n-images ${EPSILON} 2 -# ${BASELINE}/feTvNeigborhoodScalarProductModulusOutput.hdr -# ${TEMP}/feTvNeigborhoodScalarProductModulusOutput.hdr -# ${BASELINE}/feTvNeigborhoodScalarProductDirectionOutput.hdr -# ${TEMP}/feTvNeigborhoodScalarProductDirectionOutput.hdr + --compare-n-images ${EPSILON} 2 + ${BASELINE}/feTvNeigborhoodScalarProductModulusOutput.hdr + ${TEMP}/feTvNeigborhoodScalarProductModulusOutput.hdr + ${BASELINE}/feTvNeigborhoodScalarProductDirectionOutput.hdr + ${TEMP}/feTvNeigborhoodScalarProductDirectionOutput.hdr otbNeighborhoodScalarProductFilter ${INPUTDATA}/Line.png ${TEMP}/feTvNeigborhoodScalarProductModulusOutput.hdr diff --git a/Testing/Code/FeatureExtraction/otbNeighborhoodScalarProductFilter.cxx b/Testing/Code/FeatureExtraction/otbNeighborhoodScalarProductFilter.cxx index 65caf10d42c0393ed595251fd5387416585f0d75..693c7c86b450df356533bc4f0d44a94661070c1d 100644 --- a/Testing/Code/FeatureExtraction/otbNeighborhoodScalarProductFilter.cxx +++ b/Testing/Code/FeatureExtraction/otbNeighborhoodScalarProductFilter.cxx @@ -40,6 +40,7 @@ int otbNeighborhoodScalarProductFilter(int argc, char * argv[]) typedef otb::NeighborhoodScalarProductFilter<VectorImageType,ImageType,ImageType> FilterType; typedef otb::ImageFileReader<ImageType> ReaderType; typedef otb::ImageFileWriter<ImageType> WriterType; + typedef otb::ImageFileWriter<VectorImageType> TempWriter; typedef itk::GradientRecursiveGaussianImageFilter<ImageType,VectorImageType> GradientFilterType; @@ -60,6 +61,11 @@ int otbNeighborhoodScalarProductFilter(int argc, char * argv[]) writer->SetFileName(diroutfname); writer->SetInput(filter->GetOutputDirection()); writer->Update(); + + TempWriter::Pointer tmpwriter = TempWriter::New(); + tmpwriter->SetInput(gradient->GetOutput()); + tmpwriter->SetFileName("gradient.hdr"); + tmpwriter->Update(); } catch( itk::ExceptionObject & err )