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::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); }
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); } }
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 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 }