Esempio n. 1
0
void ADCensus::disparityMapFromRGB(QUrl leftImageUrl, QUrl rightImageUrl) {
    std::string left  = leftImageUrl.toLocalFile().toStdString();
    std::string right = rightImageUrl.toLocalFile().toStdString();

    cout << "Opening [" << left << " " << right << "]" << endl;

    RGB24Buffer *leftImage  = BMPLoader().loadRGB(left);
    RGB24Buffer *rightImage = BMPLoader().loadRGB(right);
    G8Buffer *leftGray      = leftImage->getChannel(ImageChannel::GRAY);
    G8Buffer *rightGray     = rightImage->getChannel(ImageChannel::GRAY);

    AbstractBuffer<int32_t> disparities = constructDisparityMap(leftImage, rightImage, leftGray, rightGray);

    G8Buffer *result = new G8Buffer(disparities.getSize());
    for (int x = 0; x < result->w; ++x) {
        for (int y = 0; y < result->h; ++y) {
            result->element(y,x) = (disparities.element(y, x) / (double)result->w * 255 * 3);
        }
    }
    BMPLoader().save("result.bmp", result);

    cout << "Resulting disparity map saved to result.bmp\n";

    delete leftImage;
    delete rightImage;
    delete leftGray;
    delete rightGray;
    delete result;
}
G8Buffer *TestbedMainWindow::projectToDirection(RGB24Buffer *input, const Vector3dd &direction)
{
    double min =  std::numeric_limits<double>::max();
    double max = -std::numeric_limits<double>::max();

    G8Buffer *projected = new G8Buffer(input->getSize(), false);

    /*Find minimum and maximum */
    for (int i = 0; i < input->h; i++)
    {
        for (int j = 0; j < input->w; j++)
        {
            RGBColor &color = input->element(i,j);
            Vector3dd c(color.r(), color.g(), color.b());
            double projection = c & direction;
            if (projection > max) max = projection;
            if (projection < min) min = projection;
        }
    }

    double mean = (min + max) / 2;
    double scale = (max - min);


    for (int i = 0; i < input->h; i++)
    {
        for (int j = 0; j < input->w; j++)
        {
            RGBColor &color = input->element(i,j);
            Vector3dd c(color.r(), color.g(), color.b());
            double projection = (c & direction) - mean;
            int result = (projection / scale * G8Buffer::BUFFER_MAX_VALUE) + (G8Buffer::BUFFER_MAX_VALUE / 2);
            if (result > G8Buffer::BUFFER_MAX_VALUE) result = G8Buffer::BUFFER_MAX_VALUE;
            if (result < 0) result = 0;
            projected->element(i,j) = result;
        }
    }

    return projected;
}
    bool operator()(RGB24Buffer */*buffer*/, int x, int y) {
        if (mMask->element(y,x) == 255)
            return false;

        int sum = 0;
        for (int i = 0; i < LocalHistogram::SIZE; i++)
        {
            sum += abs(mBase.data[i] - mLocalHist->element(y,x).data[i]);
        }

        if (sum > mTolerance) {
           return false;
        }
        return true;
     }
    bool operator()(RGB24Buffer *buffer, int x, int y) {
        if (mMask->element(y,x) == 255)
            return false;

        RGBColor currentColor = buffer->element(y,x);
        int r = (int)currentColor.r() - (int)mStartColor.r();
        int g = (int)currentColor.g() - (int)mStartColor.g();
        int b = (int)currentColor.b() - (int)mStartColor.b();

        int sum = abs(r) + abs(g) + abs(b);
        if (sum > mTolerance) {
           return false;
        }
        return true;
     }
    bool operator()(RGB24Buffer *buffer, int x, int y) {
        if (mMask->element(y,x) == 255)
            return false;

        if (!mLimit.contains(x,y))
            return false;

        RGBColor currentColor = buffer->element(y,x);
        for (unsigned i = 0; i < mStartColor.size(); i++)
        {
            RGBColor &color = mStartColor[i];
            int r = (int)currentColor.r() - (int)color.r();
            int g = (int)currentColor.g() - (int)color.g();
            int b = (int)currentColor.b() - (int)color.b();

            int sum = abs(r) + abs(g) + abs(b);
            if (sum < mTolerance) {
               return true;
            }
        }
        return false;
     }
void TestbedMainWindow::maskToleranceGraph(QPoint point)
{
    int x = point.x();
    int y = point.y();
    L_INFO_P("Starting the fill");

    //mGraphPlot->res
    if (!mMask->isValidCoord(y,x))
        return;

    vector<RGBColor> currentColor;
    switch (mUi->samplingComboBox->currentIndex())
    {
        case 0:
            currentColor.push_back(mImage->element(y,x));
            break;
        case 1:
            {
                int rad = mImageWidget->getImageRadius();
                qDebug() << "Radius is :" << rad;
                Vector3dd mean(0);
                int num = 0;

                for (int i = y - rad; i <= y + rad; i++ )
                {
                    double l = sqrt((rad * rad) - (i-y) * (i-y ));
                    for (int j = x - l; j <= x + l; j++)
                    {
                        if (!mImage->isValidCoord(i,j))
                        {
                            continue;
                        }

                        mean += mImage->element(i,j).toDouble();
                        num++;
                       // mImage->element(i,j) = RGBColor::Yellow();
                    }
                }

                mean /= num;
                currentColor.push_back(RGBColor(mean.x(), mean.y(), mean.z()));
                Vector2d<int> point = Vector2d<int>(x,y);
                if (mImage->isValidCoord(point)) currentColor.push_back(mImage->element(point));
            }
            break;
        case 2:
        default:
            {
                int rad = mImageWidget->getImageRadius();

                Vector2d<int> point;

                point = Vector2d<int>(x,y);
                if (mImage->isValidCoord(point)) currentColor.push_back(mImage->element(point));
                point = Vector2d<int>(x + rad ,y);
                if (mImage->isValidCoord(point)) currentColor.push_back(mImage->element(point));
                point = Vector2d<int>(x - rad ,y);
                if (mImage->isValidCoord(point)) currentColor.push_back(mImage->element(point));
                point = Vector2d<int>(x,y + rad);
                if (mImage->isValidCoord(point)) currentColor.push_back(mImage->element(point));
                point = Vector2d<int>(x,y + rad);
                if (mImage->isValidCoord(point)) currentColor.push_back(mImage->element(point));

                point = Vector2d<int>(x + rad * 0.7 ,y + rad * 0.7);
                if (mImage->isValidCoord(point)) currentColor.push_back(mImage->element(point));
                point = Vector2d<int>(x + rad * 0.7 ,y - rad * 0.7);
                if (mImage->isValidCoord(point)) currentColor.push_back(mImage->element(point));
                point = Vector2d<int>(x - rad * 0.7 ,y - rad * 0.7);
                if (mImage->isValidCoord(point)) currentColor.push_back(mImage->element(point));
                point = Vector2d<int>(x - rad * 0.7 ,y + rad * 0.7);
                if (mImage->isValidCoord(point)) currentColor.push_back(mImage->element(point));

                qDebug() << "Adding " << currentColor.size() << " points";
            }
            break;
    }


    QRect inputRect = mImageWidget->getInputRect();
    QRect maskRect = QRect(0,0,mMask->w - 1, mMask->h - 1);
    QRect workingRect = inputRect.intersected(maskRect);
    int totalArea = workingRect.height() * workingRect.width();

    vector<int> areas;
    G8Buffer *mMaskTmp = NULL;

    delete_safe(mMaskStore);
    mMaskStore = new G12Buffer(mMask->getSize());

    for (int i = 0; i < mUi->toleranceSpinBox->value(); i++)
    {
        delete_safe(mMaskTmp);
        mMaskTmp = new G8Buffer(mMask);
        ToleranceFinalPredicate predicate(
                mMaskTmp,
                currentColor,
                i,
                mImageWidget->getInputRect()
        );
        AbstractPainter<RGB24Buffer> painter(mImage);
        painter.floodFill(x,y, predicate);
        int area = mMaskTmp->countValues(255,
                workingRect.topLeft().x(),
                workingRect.topLeft().y(),
                workingRect.bottomRight().x(),
                workingRect.bottomRight().y()
        );
        qDebug() << "Processing tolerance:" << i << " area :" << area << " (" << ((double)area / totalArea) * 100 << "%)";
        areas.push_back(area);

        for (int y = 0; y < mMaskTmp->h; y++)
        {
            for (int x = 0; x < mMaskTmp->w; x++)
            {
                if (mMaskTmp->element(y,x) && mMaskStore->element(y,x) == 0) {
                    mMaskStore->element(y,x) = i;
                }
            }
        }

    }

    delete_safe(mMaskTmp);

    int toleranceMax = mUi->toleranceSpinBox->value();
    int toleranceMin = 0;
    for (int i = 0; i < areas.size() - 1 ; i++)
    {
        double part = ((double)areas[i + 1] / totalArea) * 100 ;
        double dpart = (((double)areas[i + 1] - areas[i] ) / totalArea) * 100;

        if (part > mUi->maximumSelectioSpinBox->value())
        {
            toleranceMax = i;
            break;
        }

        if (part > mUi->minimumSelectionSpinBox->value() && toleranceMin == 0)
        {
            toleranceMin = i;
        }

        if (part > mUi->minimumSelectionSpinBox->value() && dpart > mUi->spikeSpinBox->value())
        {
            toleranceMax = i - mUi->stepBackSpinBox->value();
            if (toleranceMax < toleranceMin) toleranceMax = toleranceMin;
            break;
        }
   }

    /* Draw result */
    mGraphPlot->addGraphPoint(0, 0, true);
    for (int i = areas.size() - 1; i >= 0; i--)
    {
        mGraphPlot->addGraphPoint(0, ((double)areas[i] / totalArea) * 100, true);

        if (i > 0)
        mGraphPlot->addGraphPoint(1, (((double)areas[i] - areas[i - 1]) / totalArea) * 100, true);

        if (i == toleranceMax) {
            mGraphPlot->addGraphPoint(2, 1, true);
        } else {
            mGraphPlot->addGraphPoint(2, 0, true);
        }

        mGraphPlot->addGraphPoint(3, mUi->spikeSpinBox->value(),true);

    }
    mGraphPlot->update();

    /*clean path*/
    mMaskTmp = new G8Buffer(mMask);
       ToleranceFinalPredicate predicate(
               mMaskTmp,
               currentColor,
               toleranceMax,
               mImageWidget->getInputRect()
       );
       AbstractPainter<RGB24Buffer> painter(mImage);
       painter.floodFill(x,y, predicate);

    mMask->fillWith(mMaskTmp);

    L_INFO_P("Fill finished");
}
 void mark(RGB24Buffer */*buffer*/, int x, int y) {
     mMask->element(y,x) = 255;
 }
int main (int argc, char **argv)
{
	QCoreApplication app(argc, argv);
	printf("Loading mask...\n");
    QTRGB24Loader  ::registerMyself();
    QTG12Loader    ::registerMyself();
    QTRuntimeLoader::registerMyself();

	QImage imageMask    ("data/adopt/orig.png");
	QImage imageAlpha   ("data/adopt/alpha.bmp");
    QImage imageFace    ("data/adopt/face.png");

    RGB24Buffer *alpha24 = QTFileLoader::RGB24BufferFromQImage(&imageAlpha);
    RGB24Buffer *mask    = QTFileLoader::RGB24BufferFromQImage(&imageMask);
    RGB24Buffer *face    = QTFileLoader::RGB24BufferFromQImage(&imageFace);

    G8Buffer *alpha = alpha24->getChannel(ImageChannel::GRAY);

    Vector3dd meanMask(0.0);
    Vector3dd meanFace(0.0);
    double count = 0;

	/* Get hole statistics */
    for (int i = 0; i < mask->h; i++)
    {
        for (int j = 0; j < mask->w; j++)
        {
            if (alpha->element(i,j) > 10)
                continue;

            count++;
            meanFace += face->element(i,j).toDouble();
            meanMask += mask->element(i,j).toDouble();
        }
    }

    meanFace /= count;
    meanMask /= count;

    cout << "Mean face value is" << meanFace << endl;
    cout << "Mean face value is" << meanMask << endl;

    EllipticalApproximationUnified<Vector3dd> facePrincipal;
    EllipticalApproximationUnified<Vector3dd> maskPrincipal;

    for (int i = 0; i < mask->h; i++)
    {
       for (int j = 0; j < mask->w; j++)
       {
           facePrincipal.addPoint(face->element(i,j).toDouble() - meanFace);
           maskPrincipal.addPoint(mask->element(i,j).toDouble() - meanMask);
       }
    }
    facePrincipal.getEllipseParameters();
    maskPrincipal.getEllipseParameters();

    cout << "Face Principals" << endl;
    cout << facePrincipal.mAxes[0] << "->" << facePrincipal.mValues[0] << endl;
    cout << facePrincipal.mAxes[1] << "->" << facePrincipal.mValues[1] << endl;
    cout << facePrincipal.mAxes[2] << "->" << facePrincipal.mValues[2] << endl;

    cout << "Mask Principals" << endl;
    cout << maskPrincipal.mAxes[0] << "->" << maskPrincipal.mValues[0] << endl;
    cout << maskPrincipal.mAxes[1] << "->" << maskPrincipal.mValues[1] << endl;
    cout << maskPrincipal.mAxes[2] << "->" << maskPrincipal.mValues[2] << endl;

    Vector3dd scalers;
    scalers.x() = sqrt(maskPrincipal.mValues[0]) / sqrt(facePrincipal.mValues[0]);
    scalers.y() = sqrt(maskPrincipal.mValues[1]) / sqrt(facePrincipal.mValues[1]);
    scalers.z() = sqrt(maskPrincipal.mValues[2]) / sqrt(facePrincipal.mValues[2]);

    /* Making correction for face */
    RGB24Buffer *faceCorr = new RGB24Buffer(face->getSize(), false);
    for (int i = 0; i < faceCorr->h; i++)
    {
       for (int j = 0; j < faceCorr->w; j++)
       {
           Vector3dd color = face->element(i,j).toDouble() - meanFace;
           Vector3dd projected(color & facePrincipal.mAxes[0],
                      color & facePrincipal.mAxes[1],
                      color & facePrincipal.mAxes[2]);

           projected = projected * scalers;

           Vector3dd newColor =
                   maskPrincipal.mAxes[0] * projected.x() +
                   maskPrincipal.mAxes[1] * projected.y() +
                   maskPrincipal.mAxes[2] * projected.z() + meanMask;
           RGBColor newrgb;
           double c;
           c = newColor.x();
           if (c <   0) c =   0;
           if (c > 255) c = 255;
           newrgb.r() = c;
           c = newColor.y();
           if (c <   0) c =   0;
           if (c > 255) c = 255;
           newrgb.g() = c;
           c = newColor.z();
           if (c <   0) c =   0;
           if (c > 255) c = 255;
           newrgb.b() = c;

           faceCorr->element(i,j) = newrgb;
       }
    }

    /* With Matrix*/
    Matrix33 scalerM    = Matrix33::Scale3(scalers);
    Matrix33 toUnityM   = Matrix33::FromRows(facePrincipal.mAxes[0], facePrincipal.mAxes[1], facePrincipal.mAxes[2]);
    Matrix33 fromUnityM = Matrix33::FromColumns(maskPrincipal.mAxes[0], maskPrincipal.mAxes[1], maskPrincipal.mAxes[2]);

    Matrix33 transform = fromUnityM * scalerM * toUnityM;

    RGB24Buffer *faceCorr2 = new RGB24Buffer(face->getSize(), false);
    for (int i = 0; i < faceCorr2->h; i++)
    {
       for (int j = 0; j < faceCorr2->w; j++)
       {
           Vector3dd newColor = transform * (face->element(i,j).toDouble() - meanFace) + meanMask;
           RGBColor newrgb;
           double c;
           c = newColor.x();
           if (c <   0) c =   0;
           if (c > 255) c = 255;
           newrgb.r() = c;
           c = newColor.y();
           if (c <   0) c =   0;
           if (c > 255) c = 255;
           newrgb.g() = c;
           c = newColor.z();
           if (c <   0) c =   0;
           if (c > 255) c = 255;
           newrgb.b() = c;

           faceCorr2->element(i,j) = newrgb;
       }
    }


    /* Without roots */
    scalers.x() = maskPrincipal.mValues[0] / facePrincipal.mValues[0];
    scalers.y() = maskPrincipal.mValues[1] / facePrincipal.mValues[1];
    scalers.z() = maskPrincipal.mValues[2] / facePrincipal.mValues[2];


    /* Making correction for face */
    RGB24Buffer *faceCorr1 = new RGB24Buffer(face->getSize(), false);
    for (int i = 0; i < faceCorr1->h; i++)
    {
       for (int j = 0; j < faceCorr1->w; j++)
       {
           Vector3dd color = face->element(i,j).toDouble() - meanFace;
           Vector3dd projected(color & facePrincipal.mAxes[0],
                      color & facePrincipal.mAxes[1],
                      color & facePrincipal.mAxes[2]);

           projected = projected * scalers;

           Vector3dd newColor =
                   maskPrincipal.mAxes[0] * projected.x() +
                   maskPrincipal.mAxes[1] * projected.y() +
                   maskPrincipal.mAxes[2] * projected.z() + meanMask;
           RGBColor newrgb;
           double c;
           c = newColor.x();
           if (c <   0) c =   0;
           if (c > 255) c = 255;
           newrgb.r() = c;
           c = newColor.y();
           if (c <   0) c =   0;
           if (c > 255) c = 255;
           newrgb.g() = c;
           c = newColor.z();
           if (c <   0) c =   0;
           if (c > 255) c = 255;
           newrgb.b() = c;

           faceCorr1->element(i,j) = newrgb;
       }
    }



    /* Make a final blending */
    BMPLoader().save("output0.bmp", mask);


    RGB24Buffer *result = alphaBlend(mask, face, alpha);
	BMPLoader().save("output1.bmp", result);

	RGB24Buffer *result1 = alphaBlend(mask, faceCorr, alpha);
	BMPLoader().save("output2.bmp", result1);

	RGB24Buffer *result2 = alphaBlend(mask, faceCorr1, alpha);
    BMPLoader().save("output3.bmp", result2);

    RGB24Buffer *result3 = alphaBlend(mask, faceCorr2, alpha);
    BMPLoader().save("matrix-out.bmp", result3);


	delete_safe(alpha);
    delete_safe(mask);
    delete_safe(face);
    delete_safe(faceCorr);
    delete_safe(faceCorr1);
    delete_safe(faceCorr2);

    delete_safe(result);
    delete_safe(result1);
    delete_safe(result2);
    delete_safe(result3);
    return 0;
}