Beispiel #1
0
/* Tonemap operator, tonemaps the hdr image and stores the
 * tonemapped image in result.  Use the value key as the 
 * key of the photograph.  This function should:
 * 1) Calculate the log-average luminance, Lavg
 * 2) Calculate the tonemapped image using the equation
 *    L(x,y) = L_w(x,y) * key / Lavg;
 *    C_tm(x,y) = L(x,y) / (1 + L(x,y));
 * 3) Store those tonemapped values to the result image,
 *    scaling appropriately.
 */
void tonemap(STHDRImage* hdr, float key, STImage* result) {
    float logAverageLuminance = 0;
    float delta = 0.001;
    
    for (int i=0;i<hdr->GetWidth();i++)
    {
        for (int j=0;j<hdr->GetHeight();j++)
        {
            STColor3f currentPixel = hdr->GetPixel(i, j);
            logAverageLuminance += logf(currentPixel.r*0.299 + currentPixel.g*0.587 +currentPixel.b*0.114 + delta);
        }
    }
    logAverageLuminance /= (hdr->GetWidth()*hdr->GetHeight());
    logAverageLuminance = expf(logAverageLuminance);
    
    for (int i=0;i<hdr->GetWidth();i++)
    {
        for (int j=0;j<hdr->GetHeight();j++)
        {
            STColor3f currentPixel = hdr->GetPixel(i, j);
            STColor3f currentPixelScaled = currentPixel * (key/logAverageLuminance);
            STColor3f compressedCurrentPixelScaled = currentPixelScaled / (STColor3f(1) + currentPixelScaled);
            STColor4ub resultPixel(compressedCurrentPixelScaled);
            result->SetPixel(i, j, resultPixel);
        }
    }
    
}
void KisConvolutionPainterTest::testAsymmConvolutionImp(QBitArray channelFlags)
{
    qreal offset = 0.0;
    qreal factor = 1.0;
    Eigen::Matrix<qreal, 3, 3> filter = initAsymmFilter(offset, factor);

    QRect imageRect;
    int pixelSize = -1;
    QByteArray initialData;
    KisPaintDeviceSP dev = initAsymTestDevice(imageRect, pixelSize, initialData);

    KisConvolutionKernelSP kernel =
        KisConvolutionKernel::fromMatrix(filter, offset, factor);
    KisConvolutionPainter gc(dev);
    gc.beginTransaction();
    gc.setChannelFlags(channelFlags);

    QRect filterRect = imageRect.adjusted(1,1,-1,-1);
    gc.applyMatrix(kernel, dev, filterRect.topLeft(), filterRect.topLeft(),
                   filterRect.size());
    gc.deleteTransaction();


    QByteArray resultData(initialData.size(), 0);
    dev->readBytes((quint8*)resultData.data(), imageRect);

    QRect filteredRect = imageRect.adjusted(1, 1, -1, -1);

    quint8 *srcPtr = (quint8*) initialData.data();
    quint8 *resPtr = (quint8*) resultData.data();

    for(int row = 0; row < imageRect.height(); row++) {
        for(int col = 0; col < imageRect.width(); col++) {

            bool isFiltered = filteredRect.contains(col, row);

            int pixelValue = 8 + row * imageRect.width() + col;
            KoColor filteredPixel(QColor(pixelValue, pixelValue, pixelValue, 255), dev->colorSpace());

            KoColor resultPixel(dev->colorSpace());
            for(int j = 0; j < pixelSize; j++) {
                resultPixel.data()[j] = isFiltered && channelFlags[j] ?
                    filteredPixel.data()[j] : srcPtr[j];
            }

            if(memcmp(resPtr, resultPixel.data(), pixelSize)) {
                printPixel("Actual:  ", pixelSize, resPtr);
                printPixel("Expected:", pixelSize, resultPixel.data());
                QFAIL("Failed to filter area");
            }

            srcPtr += pixelSize;
            resPtr += pixelSize;
        }
    }
}