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; }
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; }
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; 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; }