std::vector<Shape2> FieldAlgorithms::localizePOIExample(const MultiArray<2, float> &image,  MultiArray<2, RGBValue<UInt8> > &rgb_array)
{
    std::vector<Shape2> pois(30);
    float thld = image[argMax(image)] * 0.2;
    for (int i = 0; i < pois.size(); i++)
    {
        int v1 = std::rand() % image.size() -1;         // v1 in the range 0 to image.size()
        Shape2 poi(image.scanOrderIndexToCoordinate(v1));
        poi = localizeByFollowingLocalMaxima(image, poi);
        if (image[poi] > thld)
        {
            pois[i] = poi;
            MultiArrayView<2, RGBValue<UInt8> > markAsStep(rgb_array.subarray(Shape2(poi[0] - 5, poi[1] -5), Shape2(poi[0] +5, poi[1] +5)));
            for (RGBValue<UInt8> & val : markAsStep)
            {
                val.setRed(200);
            }
        }
        else
        {
            i--;
        }
    }
    return pois;

}
   MultiArray<2, float > FieldAlgorithms::matchGradients(MultiArray<2, TinyVector<float, 2> > &imageGradients, MultiArray<2, TinyVector<float, 2> > &mask)
{
    MultiArray<2, float >  dest(imageGradients.shape());
    dest = 0;
    //to make sure, that the mask is always fully within the image, consider the mask shape
    int diff = (mask.width() -1) / 2;
    for (int x = diff; x + diff < imageGradients.width(); x ++) 
    {
        for (int y = diff; y + diff < imageGradients.height(); y++)
        {
            //The masks center is at point x,y now
            //Every vector of the image currently 'covered' by the mask, is compared to its corresponding vector in the mask.
            float vals = 0;
            for (int xM = 0; xM < mask.width(); xM++)
            {
                for (int yM = 0; yM < mask.height(); yM++)
                {
                    TinyVector<float, 2> imageVal = imageGradients((x - diff) + xM, (y - diff) + yM);
                    TinyVector<float, 2> maskVal = mask(xM, yM);
                    vals += compareVectors(imageVal, maskVal);
                }
            }
            int res = vals / (mask.size());
            dest(x,y) = res;
        }
    }
    return dest;
};
void FieldAlgorithms::threshold(MultiArray<2, float> &basis, MultiArray<2, float> &target, float threshold)
{
    for (int j = 0; j < basis.size(); j++)
    {
        if (basis[j] < threshold)
        {
            target[j] = 0;
        }
    }
};
   void FieldAlgorithms::thresholdGrad(MultiArray<2, float> &basis, MultiArray<2, TinyVector<float, 2>> &target, float threshold)
{
    for (int j = 0; j < basis.size(); j++)
    {
        if (basis[j] < threshold)
        {
            target[j][0] = 0;
            target[j][1] = 0;
        }
    }
};
std::vector<Shape2> FieldAlgorithms::localizePOI(MultiArray<2, float> &image)
{
    std::vector<Shape2> pois(1);
    for (int i = 0; i < pois.size(); i++)
    {
        int v1 = std::rand() % image.size() -1; 
         //int maxIndex = argMax(box);
         //Shape2 max(box.scanOrderIndexToCoordinate(maxIndex));
         //image.scanOrderIndexToCoordinate(v1)
        Shape2 poi = localizeByFollowingLocalMaxima(image, Shape2(image.width()/2, image.height()/2));
        pois[i] = poi;
    }
    return pois;

}