Exemplo n.º 1
0
void ImageProximityFFT::MulAndScaleSpectrums(Image& Source, Image& Template, Image& Dest, float scale)
{
   CheckSameSize(Source, Template);
   CheckSameSize(Source, Dest);

   // Verify image types
   if (Source.DataType() != SImage::F32 || Template.DataType() != SImage::F32 || Dest.DataType() != SImage::F32)
      throw cl::Error(CL_IMAGE_FORMAT_NOT_SUPPORTED, "The function works only with F32 images");

   // Verify image types
   if (Source.NbChannels() != 2 || Template.NbChannels() != 2 || Dest.NbChannels() != 2)
      throw cl::Error(CL_IMAGE_FORMAT_NOT_SUPPORTED, "The function works only with 2 channel images");

   Kernel(mulAndScaleSpectrums, Source, Template, Dest, Source.Step(), Template.Step(), Dest.Step(), Source.Width(), Source.Height(), scale);
}
Exemplo n.º 2
0
void Integral::IntegralScan(IImage& Source, IImage& Dest)
{
   PrepareFor(Source);

   CheckSameSize(Source, Dest);
   CheckFloat(Dest);

   uint Width = Source.Width();
   uint Height = Source.Height();

   Kernel(scan1, Source, Dest, Width, Height);

   if (GetNbGroupsW(Source) > 1)
   {
      make_kernel<Image2D, Image2D>(SelectProgram(Dest), "scan2")
         (EnqueueArgs(*m_CL, NDRange(GetNbGroupsW(Source) - 1, Source.Height())), Dest, *m_VerticalJunctions);
   }

#undef KERNEL_RANGE
#define KERNEL_RANGE(src_img) src_img.FullRange()

   Kernel(scan3, In(Dest, *m_VerticalJunctions), Dest);

   if (GetNbGroupsH(Source) > 1)
   {
      make_kernel<Image2D, Image2D>(SelectProgram(Dest), "scan4")
         (EnqueueArgs(*m_CL, NDRange(Source.Width(), GetNbGroupsH(Source) - 1)), Dest, *m_HorizontalJunctions);
   }

   Kernel(scan5, In(Dest, *m_HorizontalJunctions), Dest);
}
Exemplo n.º 3
0
void ImageProximityFFT::SqrDistance_Norm(Image& Source, Image& Template, Image& Dest)
{
   CheckFloat(Dest);
   CheckSameNbChannels(Source, Template);
   CheckSameNbChannels(Source, Dest);
   CheckSameSize(Source, Dest);

   // Verify image size
   if (Template.Width() > Source.Width() || Template.Height() > Source.Height())
      throw cl::Error(CL_IMAGE_FORMAT_NOT_SUPPORTED, "The template image must be smaller than source image.");

   // Verify image types
   if(!SameType(Source, Template))
      throw cl::Error(CL_IMAGE_FORMAT_MISMATCH, "The source image and the template image must be same type.");

   PrepareFor(Source, Template);

   m_integral.SqrIntegral(Source, *m_image_sqsums);

   double templ_sqsum[4] = {0};
   m_statistics.SumSqr(Template, templ_sqsum);

   CrossCorr(Source, Template, Dest);
   MatchSquareDiffNorm(Template.Width(), Template.Height(), *m_image_sqsums, templ_sqsum, Dest);
}
Exemplo n.º 4
0
void Blob::ComputeLabels(IImage& Source, ImageBuffer& Labels, int ConnectType)
{
   if (ConnectType != 4 && ConnectType != 8)
      throw cl::Error(CL_INVALID_VALUE, "Wrong connect type in Blob::ComputeLabels");

   if (Labels.Depth() != 32 || Labels.IsFloat())
      throw cl::Error(CL_INVALID_VALUE, "Wrong Labels image type in Blob::ComputeLabels - Labels must be 32 bit integer");

   if (m_TempBuffer == nullptr)
      PrepareFor(Source);

   CheckSameSize(Source, Labels);
   CheckCompatibility(Labels, *m_TempBuffer);

   m_BlobInfo.Init(ConnectType);

   m_InfoBuffer.Send();

   // Initialize the label image
   Kernel(init_label, Source, Out(Labels, *m_TempBuffer), Labels.Step(), m_TempBuffer->Step(), m_InfoBuffer);

   // These two labeling steps need to be executed at least twice each
   int i = 0;
   while (i <= m_BlobInfo.LastUsefulIteration)
   {
      i++;

      Kernel(label_step1, Labels, *m_TempBuffer, Labels.Step(), m_TempBuffer->Step(), m_InfoBuffer, i);
      Kernel(label_step2, Labels, *m_TempBuffer, Labels.Step(), m_TempBuffer->Step(), m_InfoBuffer, i);

      if (i >= 2)
         m_InfoBuffer.Read(true);
   }

}
Exemplo n.º 5
0
void CheckCompatibility(const ImageBase& Img1, const ImageBase& Img2)
{
   CheckSameSize(Img1, Img2);

   if (Img1.IsFloat() != Img2.IsFloat())
      throw cl::Error(CL_INVALID_VALUE, "Different image types used");

   if (Img1.IsUnsigned() != Img2.IsUnsigned())
     throw cl::Error(CL_INVALID_VALUE, "Different image types used");
}
Exemplo n.º 6
0
void ImageProximityFFT::Convolve(Image& Source, Image& Template, Image& Dest)
{
   CheckSameSize(Source, Dest);

   PrepareFor(Source, Template);

   // Fill these images with black
   m_transform.SetAll(*m_bigger_template, 0);
   m_transform.SetAll(*m_bigger_source, 0);

   for (uint i = 1; i <= Source.NbChannels(); i++)
   {
      // Copy the data from Source and Template in images that are F32 and are big enough
      Kernel(copy_offset, In(Source), Out(*m_bigger_source), Source.Step(), m_bigger_source->Step(),
         int(Template.Width()) / 2, int(Template.Height()) / 2, m_bigger_source->Width(), m_bigger_source->Height(), i);

      Kernel(copy_offset, In(Template), Out(*m_bigger_template), Template.Step(), m_bigger_template->Step(),
         0, 0, m_bigger_template->Width(), m_bigger_template->Height(), i);


      // Forward FFT of Source and Template
      m_fft.Forward(*m_bigger_source, *m_source_spect);
      m_fft.Forward(*m_bigger_template, *m_templ_spect);


      // We need to divide the values by the FFT area to get the proper 
      float Area = float(m_bigger_source->Width() * m_bigger_source->Height());

      // Do the convolution using pointwise product of the spectrums
      // See information here : http://en.wikipedia.org/wiki/Convolution_theorem
      MulAndScaleSpectrums(*m_source_spect, *m_templ_spect, *m_result_spect, 1 / Area);


      // Inverse FFT to get the result of the convolution
      m_fft.Inverse(*m_result_spect, *m_bigger_source);  // Reuse m_bigger_source image for the convolution result


      // Copy the result to Dest
      Kernel_(*m_CL, SelectProgram(Dest), copy_result, m_bigger_source->FullRange(), LOCAL_RANGE,
         In(*m_bigger_source), Out(Dest), m_bigger_source->Step(), Dest.Step(), Dest.Width(), Dest.Height(), i);
   }

}
Exemplo n.º 7
0
void ImageProximityFFT::CrossCorr(Image& Source, Image& Template, Image& Dest)
{
   CheckFloat(Dest);
   CheckSameNbChannels(Source, Template);
   CheckSameNbChannels(Source, Dest);
   CheckSameSize(Source, Dest);

   // Verify image size
   if (Template.Width() > Source.Width() || Template.Height() > Source.Height())
      throw cl::Error(CL_IMAGE_FORMAT_NOT_SUPPORTED, "The template image must be smaller than source image.");

   // Verify image types
   if(!SameType(Source, Template))
      throw cl::Error(CL_IMAGE_FORMAT_MISMATCH, "The source image and the template image must be same type.");

   PrepareFor(Source, Template);

   Convolve(Source, Template, Dest);   // Computes the cross correlation using FFT
}
Exemplo n.º 8
0
void Conversions::Convert(Image& Source, Image& Dest)
{
   CheckSameSize(Source, Dest);

   if (SameType(Source, Dest))
   {
      Copy(Source, Dest);
      return;
   }

   switch (Dest.DataType())
   {
   case SImage::U8:
      Kernel(to_uchar, Source, Dest, Source.Step(), Dest.Step());
      break;
   case SImage::S8:
      Kernel(to_char, Source, Dest, Source.Step(), Dest.Step());
      break;
   case SImage::U16:
      Kernel(to_ushort, Source, Dest, Source.Step(), Dest.Step());
      break;
   case SImage::S16:
      Kernel(to_short, Source, Dest, Source.Step(), Dest.Step());
      break;
   case SImage::U32:
      Kernel(to_uint, Source, Dest, Source.Step(), Dest.Step());
      break;
   case SImage::S32:
      Kernel(to_int, Source, Dest, Source.Step(), Dest.Step());
      break;
   case SImage::F32:
      Kernel(to_float, Source, Dest, Source.Step(), Dest.Step());
      break;
   case SImage::F64:
      Kernel(to_double, Source, Dest, Source.Step(), Dest.Step());
      break;
   case SImage::NbDataTypes:
   default:
      throw cl::Error(CL_IMAGE_FORMAT_NOT_SUPPORTED, "Unsupported data type");
   }
   
}
Exemplo n.º 9
0
void Conversions::Scale(Image& Source, Image& Dest)
{
   CheckSameSize(Source, Dest);

   double SrcRange = GetTypeRange(Source);
   double DstRange = GetTypeRange(Dest);

   double SrcMin = GetTypeMin(Source);
   double DstMin = GetTypeMin(Dest);

   if (SrcRange == DstRange && SrcMin == DstMin)
   {
      Convert(Source, Dest);
      return;
   }

   float Ratio = static_cast<float>(DstRange / SrcRange);
   int Offset = static_cast<int>(-SrcMin * Ratio + DstMin);

   Scale(Source, Dest, Offset, Ratio);
}
Exemplo n.º 10
0
void Conversions::Scale(Image& Source, Image& Dest, int Offset, float Ratio)
{
   CheckSameSize(Source, Dest);

   switch (Dest.DataType())
   {
   case SImage::U8:
      Kernel(scale_to_uchar, Source, Dest, Source.Step(), Dest.Step(), Offset, Ratio);
      break;
   case SImage::S8:
      Kernel(scale_to_char, Source, Dest, Source.Step(), Dest.Step(), Offset, Ratio);
      break;
   case SImage::U16:
      Kernel(scale_to_ushort, Source, Dest, Source.Step(), Dest.Step(), Offset, Ratio);
      break;
   case SImage::S16:
      Kernel(scale_to_short, Source, Dest, Source.Step(), Dest.Step(), Offset, Ratio);
      break;
   case SImage::U32:
      Kernel(scale_to_uint, Source, Dest, Source.Step(), Dest.Step(), Offset, Ratio);
      break;
   case SImage::S32:
      Kernel(scale_to_int, Source, Dest, Source.Step(), Dest.Step(), Offset, Ratio);
      break;
   case SImage::F32:
      Kernel(scale_to_float, Source, Dest, Source.Step(), Dest.Step(), Offset, Ratio);
      break;
   case SImage::F64:
      Kernel(scale_to_double, Source, Dest, Source.Step(), Dest.Step(), Offset, Ratio);
      break;
   case SImage::NbDataTypes:
   default:
      throw cl::Error(CL_IMAGE_FORMAT_NOT_SUPPORTED, "Unsupported data type");
   }

}