Пример #1
0
// Functions of class Retinex
Plane_FL &Retinex::Kernel(Plane_FL &dst, const Plane_FL &src)
{
    const size_t scount = para.sigmaVector.size();
    size_t s;

    for (s = 0; s < scount; ++s)
    {
        if (para.sigmaVector[s] > 0) break;
    }
    if (s >= scount)
    {
        dst = src;
        return dst;
    }

    PCType i, j, upper;
    PCType height = src.Height();
    PCType width = src.Width();
    PCType stride = src.Stride();

    Plane_FL gauss(src, false);

    if (scount == 1 && para.sigmaVector[0] > 0) // single-scale Gaussian filter
    {
        RecursiveGaussian GFilter(para.sigmaVector[0], true);
        Plane_FL gauss = GFilter(src);

        for (j = 0; j < height; ++j)
        {
            i = j * stride;
            for (upper = i + width; i < upper; ++i)
            {
                dst[i] = gauss[i] <= 0 ? 0 : log(src[i] / gauss[i] + 1);
            }
        }
    }
    else // multi-scale Gaussian filter
    {
        if (dst.data() == src.data())
        {
            DEBUG_FAIL("Retinex::Kernel: Data of Plane_FL \"dst\" and Plane_FL \"src\" can not be of the same address for multi-scale.");
        }

        dst.InitValue(1);

        for (s = 0; s < scount; ++s)
        {
            if (para.sigmaVector[s] > 0)
            {
                RecursiveGaussian GFilter(para.sigmaVector[s], true);
                GFilter.Filter(gauss, src);

                for (j = 0; j < height; ++j)
                {
                    i = j * stride;
                    for (upper = i + width; i < upper; ++i)
                    {
                        if (gauss[i] > 0)
                        {
                            dst[i] *= src[i] / gauss[i] + 1;
                        }
                    }
                }
            }
            else
            {
                for (j = 0; j < height; ++j)
                {
                    i = j * stride;
                    for (upper = i + width; i < upper; ++i)
                    {
                        dst[i] *= FLType(2);
                    }
                }
            }
        }

        FLType scountRec = 1 / static_cast<FLType>(scount);

        for (j = 0; j < height; ++j)
        {
            i = j * stride;
            for (upper = i + width; i < upper; ++i)
            {
                dst[i] = log(dst[i]) * scountRec;
            }
        }
    }

    return dst;
}
Пример #2
0
// Implementation of O(1) cross/joint Bilateral filter algorithm from "Qingxiong Yang, Kar-Han Tan, Narendra Ahuja - Real-Time O(1) Bilateral Filtering"
Plane &Bilateral2D_1(Plane &dst, const Plane &src, const Plane &ref, const Bilateral2D_Data &d, int plane)
{
    int i, j, upper;
    int k;

    int height = ref.Height();
    int width = ref.Width();
    int stride = ref.Width();
    int pcount = ref.PixelCount();

    double sigmaS = d.sigmaS[plane];
    double sigmaR = d.sigmaR[plane];
    int PBFICnum = d.PBFICnum[plane];

    const LUT<FLType> &GR_LUT = d.GR_LUT[plane];

    // Value range of Plane "ref"
    DType rLower, rUpper, rRange;

    rLower = ref.Floor();
    rUpper = ref.Ceil();
    rRange = rUpper - rLower;

    // Generate quantized PBFICs' parameters
    DType * PBFICk = new DType[PBFICnum];

    for (k = 0; k < PBFICnum; ++k)
    {
        PBFICk[k] = static_cast<DType>(static_cast<double>(rRange)*k / (PBFICnum - 1) + rLower + 0.5);
    }

    // Generate recursive Gaussian filter object
    RecursiveGaussian GFilter(sigmaS, true);

    // Generate quantized PBFICs
    Plane_FL * PBFIC = new Plane_FL[PBFICnum];
    Plane_FL Wk(ref, false);
    Plane_FL Jk(ref, false);
    
    for (k = 0; k < PBFICnum; ++k)
    {
        PBFIC[k] = Plane_FL(ref, false);

        for (j = 0; j < height; ++j)
        {
            i = stride * j;
            for (upper = i + width; i < upper; ++i)
            {
                Wk[i] = Gaussian_Distribution2D_Range_LUT_Lookup(GR_LUT, PBFICk[k], ref[i]);
                Jk[i] = Wk[i] * src[i];
            }
        }

        GFilter(Wk, Wk);
        GFilter(Jk, Jk);

        for (j = 0; j < height; ++j)
        {
            i = stride * j;
            for (upper = i + width; i < upper; ++i)
            {
                PBFIC[k][i] = Wk[i] == 0 ? 0 : Jk[i] / Wk[i];
            }
        }
    }

    // Generate filtered result from PBFICs using linear interpolation
    for (j = 0; j < height; ++j)
    {
        i = stride * j;
        for (upper = i + width; i < upper; ++i)
        {
            for (k = 0; k < PBFICnum - 2; ++k)
            {
                if (ref[i] < PBFICk[k + 1] && ref[i] >= PBFICk[k]) break;
            }

            dst[i] = dst.Quantize(((PBFICk[k + 1] - ref[i])*PBFIC[k][i] + (ref[i] - PBFICk[k])*PBFIC[k + 1][i]) / (PBFICk[k + 1] - PBFICk[k]));
        }
    }

    // Clear and output
    delete[] PBFIC;
    delete[] PBFICk;

    return dst;
}