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); }
void ImageProximityFFT::PrepareFor(ImageBase& Source, Image& Template) { SSize size; size.Width = Source.Width(); size.Height = Source.Height(); if (m_image_sqsums == nullptr || m_image_sqsums->Width() < size.Width || m_image_sqsums->Height() < size.Height) m_image_sqsums = std::make_shared<TempImage>(*m_CL, size, SImage::F32, Source.NbChannels()); // Size of the FFT input and output size.Width = Source.Width() + Template.Width() / 2; size.Height = Source.Height() + Template.Height() / 2; // Search for a size supported by clFFT while (!m_fft.IsSupportedLength(size.Width)) size.Width++; while (!m_fft.IsSupportedLength(size.Height)) size.Height++; if (m_bigger_source == nullptr || m_bigger_source->Width() != size.Width || m_bigger_source->Height() != size.Height) m_bigger_source = std::make_shared<TempImage>(*m_CL, size, SImage::F32, 1); if (m_bigger_template == nullptr || m_bigger_template->Width() < size.Width || m_bigger_template->Height() < size.Height) m_bigger_template = std::make_shared<TempImage>(*m_CL, size, SImage::F32, 1); // Size of the spectral images size.Width = size.Width / 2 + 1; if (m_templ_spect == nullptr || m_templ_spect->Width() < size.Width || m_templ_spect->Height() < size.Height) m_templ_spect = std::make_shared<TempImage>(*m_CL, size, SImage::F32, 2); if (m_source_spect == nullptr || m_source_spect->Width() != size.Width || m_source_spect->Height() != size.Height) m_source_spect = std::make_shared<TempImage>(*m_CL, size, SImage::F32, 2); if (m_result_spect == nullptr || m_result_spect->Width() < size.Width || m_result_spect->Height() < size.Height) m_result_spect = std::make_shared<TempImage>(*m_CL, size, SImage::F32, 2); m_integral.PrepareFor(Source); m_statistics.PrepareFor(Template); m_transform.PrepareFor(Source); m_fft.PrepareFor(*m_bigger_source, *m_source_spect); SelectProgram(Source).Build(); SelectProgram(*m_source_spect).Build(); }
void Statistics::InitAbs(Image& Source) { Source.SendIfNeeded(); cl::make_kernel<cl::Buffer, cl::Buffer>(SelectProgram(Source), "init_abs") (cl::EnqueueArgs(*m_CL, cl::NDRange(1, 1, 1)), Source, m_ResultBuffer); }
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); } }
void VectorProgram::PrepareFor(const ImageBase& Source) { SelectProgram(Source).Build(); }
Program& ImageProgram::SelectProgram(const ImageBase& Img1, const ImageBase&, const ImageBase&, const ImageBase&) { // Only Img1 is used to select the program return SelectProgram(Img1); }