예제 #1
0
/**
 * @brief weightFunction computes weight functions for x in [0,1].
 * @param x is an input value in [0, 1].
 * @param type is the type of the function.
 * @return It returns a weight for x.
 */
PIC_INLINE float weightFunction(float x, CRF_WEIGHT type)
{
    switch(type) {

    case CW_ROBERTSON: {
        // w(x) = exp(-4*(x*255 - 127.5)^2/(127.5)^2) = exp(-16.0 * (x - 0.5)^2)
        // (according to the paper it should be scaled and shifted s.t. w(0) = w(255) = 0 and w(127.5) = 1)
        static const double shift    = exp(-4);
        static const double scaleDiv = (1.0 - shift);
        const double t = x - 0.5;
        return float((exp(-16.0 * (t * t) ) - shift) / scaleDiv);
    }
    break;

    case CW_HAT: {
        float val = (2.0f * x - 1.0f);
        float val_squared = val * val;
        float val_quartic = val_squared * val_squared;
        return (1.0f - val_quartic * val_quartic * val_quartic);
    }
    break;

    case CW_DEB97: {
        static const float Zmin = 0.0f;
        static const float Zmax = 1.0f;
        static const float tr = (Zmin + Zmax) / 2.0f;

        if(x <= tr) {
            return x - Zmin;
        } else {
            return Zmax - x;
        }
    }
    break;

    case CW_DEB97p01: {
        static const float Zmin = 0.01f;
        static const float Zmax = 0.99f;
        float tr = (Zmin + Zmax) / 2.0f;

        if(x <= tr) {
            return CLAMPi(x - Zmin, 0.0f, 1.0f);
        } else {
            return CLAMPi(Zmax - x, 0.0f, 1.0f);
        }
    }
    break;

    default: {
        return 1.0f;
    }
    break;
    }

    return 1.0f;
}
예제 #2
0
    /**
     * @brief convertToLDR
     * @param exposure
     * @param gammaCor
     * @return
     */
    Color3 convertToLDR(float exposure = 1.0f, float gammaCor = 2.2f)
    {
        Color3 ret(x * exposure, y * exposure, z * exposure);
        ret.gamma(1.0f / gammaCor);

        ret.x = CLAMPi(ret.x, 0.0f, 1.0f);
        ret.y = CLAMPi(ret.y, 0.0f, 1.0f);
        ret.z = CLAMPi(ret.z, 0.0f, 1.0f);

        return ret;
    }
예제 #3
0
/**
 * @brief MSE computes the mean square error (MSE) between two HDR images with given exposure and gamma.
 * @param ori is the original image.
 * @param cmp is the distorted image.
 * @param gamma is the encoding gamma.
 * @param fstop is the f-stop value of the image.
 * @param nBit is the number of bits used for the discretization.
 * @return It returns the MSE value between ori and cmp.
 */
PIC_INLINE double MSE(Image *ori, Image *cmp, float gamma = 2.2f, float fstop = 0.0f, int nBit = 8)
{
    if(ori == NULL || cmp == NULL) {
        return -2.0;
    }

    if(!ori->isValid() || !cmp->isValid()) {
        return -4.0;
    }

    if(!ori->isSimilarType(cmp)) {
        return -1.0;
    }

    float invGamma = 1.0f / gamma;
    float exposure = powf(2.0f, fstop);

    int area = ori->width * ori->height;
    int size = area * ori->channels;

    unsigned long long acc = 0;

    int nValues = (1 << nBit) - 1;
    float nValuesf = float(nValues);

    for(int i = 0; i < size; i++) {
        int oriLDR = int(nValuesf * (powf(ori->data[i] * exposure, invGamma)));
        int cmpLDR = int(nValuesf * (powf(cmp->data[i] * exposure, invGamma)));

        oriLDR = CLAMPi(oriLDR, 0, nValues);
        cmpLDR = CLAMPi(cmpLDR, 0, nValues);

        int delta = cmpLDR - oriLDR;

        acc += delta * delta;
    }

    return (double(acc) / double(area));
}
예제 #4
0
    /**
     * @brief ProcessBBox
     * @param dst
     * @param src
     * @param box
     */
    void ProcessBBox(Image *dst, ImageVec src, BBox *box)
    {
        int tmpChannel = CLAMPi(channel, 0, src[0]->channels);

        for(int p = box->z0; p < box->z1; p++) {
            for(int j = box->y0; j < box->y1; j++) {
                for(int i = box->x0; i < box->x1; i++) {

                    float *dst_data =	(*dst)(i, j, p);
                    float *data =	 (*src[0])(i, j, p);

                    dst_data[0] = data[tmpChannel];
                }
            }
        }
    }