RGB24Buffer * alphaBlend(RGB24Buffer *in1, RGB24Buffer *in2, G8Buffer *alpha) { RGB24Buffer *result = new RGB24Buffer(in1->getSize()); for (int i = 0; i < result->h; i++) { for (int j = 0; j < result->w; j++) { RGBColor maskEl = in1->element(i,j); RGBColor faceEl = in2->element(i,j); int a = alpha->element(i,j); int b = 255 - a; int r1 = maskEl.r(); int g1 = maskEl.g(); int b1 = maskEl.b(); int r2 = faceEl.r(); int g2 = faceEl.g(); int b2 = faceEl.b(); RGBColor resultEl( (r1 * a + r2 * b) / 255, (g1 * a + g2 * b) / 255, (b1 * a + b2 * b) / 255 ); result->element(i,j) = resultEl; } } return result; }
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; }
void Bitmap::SetPixel(int x, int y, const RGBColor &c) { CheckCoordinates(x, y); data_[y * bi_.width + x].red = c.r(); data_[y * bi_.width + x].green = c.g(); data_[y * bi_.width + x].blue = c.b(); return; }
void Bitmap::SetPixelImageCoordinates(int i, int j, const RGBColor &c) { CheckImageCoordinates(i, j); const int image_coordinates_i = height_ - i - 1; data_[image_coordinates_i * width_ + j].red = c.r(); data_[image_coordinates_i * width_ + j].green = c.g(); data_[image_coordinates_i * width_ + j].blue = c.b(); return; }
void TestbedMainWindow::recursiveTolerance(RGBColor startColor, int tolerance, int x, int y) { if (!mMask->isValidCoord(y,x)) return; if (mMask->element(y,x)) return; RGBColor currentColor = mImage->element(y,x); int r = (int)currentColor.r() - (int)startColor.r(); int g = (int)currentColor.g() - (int)startColor.g(); int b = (int)currentColor.b() - (int)startColor.b(); int sum = abs(r) + abs(g) + abs(b); if (sum > tolerance) return; mMask->element(y,x) = 255; recursiveTolerance(startColor, tolerance, x - 1, y ); recursiveTolerance(startColor, tolerance, x + 1, y ); recursiveTolerance(startColor, tolerance, x , y + 1); recursiveTolerance(startColor, tolerance, x , y - 1); }
void PaintImageWidget::childRepaint(QPaintEvent *event, QWidget *who) { AdvancedImageWidget::childRepaint(event, who); if (mImage.isNull()) { return; } /* Now the points */ QPainter painter(who); for (unsigned i = 0; i < mFeatures.mPoints.size(); i ++) { SelectableGeometryFeatures::Vertex *vertex = mFeatures.mPoints[i]; painter.setPen(vertex->isSelected() ? Qt::red : Qt::green); if (vertex->ownerPath == NULL) { drawCircle(painter, imageToWidgetF(vertex->position), 5); } else { drawSquare(painter, imageToWidgetF(vertex->position), 5); } if (vertex->weight >= 0.0) { RGBColor color = RGBColor::rainbow1(vertex->weight); painter.setPen(QColor(color.r(), color.g(), color.b())); drawCircle(painter, imageToWidgetF(vertex->position), 7); } } for (unsigned i = 0; i < mFeatures.mPaths.size(); i++) { SelectableGeometryFeatures::VertexPath *path = mFeatures.mPaths[i]; painter.setPen(path->mSelected ? Qt::yellow : Qt::green); for (unsigned i = 1; i < path->vertexes.size(); i++) { Vector2dd point1 = path->vertexes[i ]->position; Vector2dd point2 = path->vertexes[i - 1]->position; drawLine(painter, imageToWidgetF(point1), imageToWidgetF(point2)); } } }
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::updateViewImage(void) { enum {IMAGE, MASK, HUE, SATURATION, VALUE, EDGES, CANNY, PRINCIPAL, SECONDARY, THIRD}; switch (mUi->bufferSelectBox->currentIndex()) { case IMAGE: { if (mImage == NULL) { return; } if (mUi->blendEdgeCheckBox->isChecked()) { prepareBlendedMask(); } RGB24Buffer *toDraw = new RGB24Buffer(mImage); RGBColor maskColor = mUi->maskColorWidget->getColor(); double alpha = (mUi->maskAlphaSpinBox->value()) / 100.0; if (mUi->actionShowMask->isChecked()) { for (int i = 0; i < toDraw->h; i++) { for (int j = 0; j < toDraw->w; j++) { bool hasmask = false; bool hasnomask = false; /* so far no optimization here */ if (mUi->showEdgeCheckBox->isChecked()) { for (int dx = -1; dx <= 1; dx++) { for (int dy = -1; dy <= 1; dy++) { if (!mMask->isValidCoord(i + dy, j + dx)) continue; if (mMask->element(i + dy, j + dx)) { hasmask = true; } else { hasnomask = true; } } } } if (mUi->blendEdgeCheckBox->isChecked()) { double scaler = alpha * mMaskBlended->element(i,j) / 255; toDraw->element(i,j).r() += (maskColor.r() - toDraw->element(i,j).r()) * scaler; toDraw->element(i,j).g() += (maskColor.g() - toDraw->element(i,j).g()) * scaler; toDraw->element(i,j).b() += (maskColor.b() - toDraw->element(i,j).b()) * scaler; } else { if (mMask->element(i,j)) { toDraw->element(i,j).r() += (maskColor.r() - toDraw->element(i,j).r()) * alpha; toDraw->element(i,j).g() += (maskColor.g() - toDraw->element(i,j).g()) * alpha; toDraw->element(i,j).b() += (maskColor.b() - toDraw->element(i,j).b()) * alpha; } } if (mMask->element(i,j)) { if (hasmask && hasnomask) { toDraw->element(i,j) = mUi->edgeColorWidget->getColor(); } } if (mUi->levelDebugCheckBox->isChecked() && mMaskStore != NULL && mMaskStore->element(i,j) != 0) { if (mMaskStore->element(i,j) > mUi->levelSpinBox->value()) { toDraw->element(i,j) = RGBColor::Red(); } else { toDraw->element(i,j) = RGBColor::Blue(); } } } } } QImage *qImage = new RGB24Image(toDraw); mImageWidget->setImage(QSharedPointer<QImage>(qImage)); delete_safe(toDraw); } break; case MASK: mImageWidget->setImage(QSharedPointer<QImage>(new G8Image(mMask))); break; case HUE: mImageWidget->setImage(QSharedPointer<QImage>(new G8Image(mHComp))); break; case SATURATION: mImageWidget->setImage(QSharedPointer<QImage>(new G8Image(mSComp))); break; case VALUE: mImageWidget->setImage(QSharedPointer<QImage>(new G8Image(mVComp))); break; case EDGES: mImageWidget->setImage(QSharedPointer<QImage>(new G12Image(mEdges))); break; case CANNY: mImageWidget->setImage(QSharedPointer<QImage>(new G12Image(mCannyEdges))); break; case PRINCIPAL: mImageWidget->setImage(QSharedPointer<QImage>(new G8Image(mPrincipal))); break; case SECONDARY: mImageWidget->setImage(QSharedPointer<QImage>(new G8Image(mPrincipal2))); break; case THIRD: default: mImageWidget->setImage(QSharedPointer<QImage>(new G8Image(mPrincipal3))); break; } }
/** * @brief Copy constructor * @param val Source RGBA value */ inline Rgba( const RGBColor & val ) : Base( val.r(), val.g(), val.b(), static_cast<T>( 1 ) ) { }
/// Find the color of the SfM_Data Landmarks/structure void ColorizeTracks( const SfM_Data & sfm_data, std::vector<Vec3> & vec_3dPoints, std::vector<Vec3> & vec_tracksColor) { // Colorize each track // Start with the most representative image // and iterate to provide a color to each 3D point { C_Progress_display my_progress_bar(sfm_data.getLandmarks().size(), std::cout, "\nCompute scene structure color\n"); vec_tracksColor.resize(sfm_data.getLandmarks().size()); vec_3dPoints.resize(sfm_data.getLandmarks().size()); //Build a list of contiguous index for the trackIds std::map<IndexT, IndexT> trackIds_to_contiguousIndexes; IndexT cpt = 0; for (Landmarks::const_iterator it = sfm_data.getLandmarks().begin(); it != sfm_data.getLandmarks().end(); ++it, ++cpt) { trackIds_to_contiguousIndexes[it->first] = cpt; vec_3dPoints[cpt] = it->second.X; } // The track list that will be colored (point removed during the process) std::set<IndexT> remainingTrackToColor; std::transform(sfm_data.getLandmarks().begin(), sfm_data.getLandmarks().end(), std::inserter(remainingTrackToColor, remainingTrackToColor.begin()), RetrieveKey() ); while( !remainingTrackToColor.empty() ) { // Find the most representative image (for the remaining 3D points) // a. Count the number of observation per view for each 3Dpoint Index // b. Sort to find the most representative view index std::map<IndexT, IndexT> map_IndexCardinal; // ViewId, Cardinal for (std::set<IndexT>::const_iterator iterT = remainingTrackToColor.begin(); iterT != remainingTrackToColor.end(); ++iterT) { const size_t trackId = *iterT; const Observations & obs = sfm_data.getLandmarks().at(trackId).obs; for( Observations::const_iterator iterObs = obs.begin(); iterObs != obs.end(); ++iterObs) { const size_t viewId = iterObs->first; if (map_IndexCardinal.find(viewId) == map_IndexCardinal.end()) map_IndexCardinal[viewId] = 1; else ++map_IndexCardinal[viewId]; } } // Find the View index that is the most represented std::vector<IndexT> vec_cardinal; std::transform(map_IndexCardinal.begin(), map_IndexCardinal.end(), std::back_inserter(vec_cardinal), RetrieveValue()); using namespace indexed_sort; std::vector< sort_index_packet_descend< IndexT, IndexT> > packet_vec(vec_cardinal.size()); sort_index_helper(packet_vec, &vec_cardinal[0], 1); // First image index with the most of occurence std::map<IndexT, IndexT>::const_iterator iterTT = map_IndexCardinal.begin(); std::advance(iterTT, packet_vec[0].index); const size_t view_index = iterTT->first; const View * view = sfm_data.getViews().at(view_index).get(); const std::string sView_filename = stlplus::create_filespec(sfm_data.s_root_path, view->s_Img_path); Image<RGBColor> image; ReadImage(sView_filename.c_str(), &image); // Iterate through the remaining track to color // - look if the current view is present to color the track std::set<IndexT> set_toRemove; for (std::set<IndexT>::const_iterator iterT = remainingTrackToColor.begin(); iterT != remainingTrackToColor.end(); ++iterT) { const size_t trackId = *iterT; const Observations & obs = sfm_data.getLandmarks().at(trackId).obs; Observations::const_iterator it = obs.find(view_index); if (it != obs.end()) { // Color the track const Vec2 & pt = it->second.x; const RGBColor color = image(pt.y(), pt.x()); vec_tracksColor[ trackIds_to_contiguousIndexes[trackId] ] = Vec3(color.r(), color.g(), color.b()); set_toRemove.insert(trackId); ++my_progress_bar; } } // Remove colored track for (std::set<IndexT>::const_iterator iter = set_toRemove.begin(); iter != set_toRemove.end(); ++iter) { remainingTrackToColor.erase(*iter); } } } }
inline void Convert<RGBColor, unsigned char>( const RGBColor& valin, unsigned char& valOut) { valOut = static_cast<unsigned char>(0.3 * valin.r() + 0.59 * valin.g() + 0.11 * valin.b()); }
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; }
void OpenGLTools::glColorRGB(const RGBColor &color) { //glColor3f(color.r() / 256.0, color.g() / 256.0, color.b() / 256.0); glColor3ub(color.r(), color.g(), color.b()); }
/** * TODO: Add error handling * * */ bool BMPLoader::save(string name, RGB24Buffer *buffer) { CORE_ASSERT_TRUE(buffer != NULL, "Null buffer could not be saved"); FILE *fp = fopen(name.c_str(), "wb"); if (fp == NULL) return false; int w = buffer->w; int h = buffer->h; /*Line length in BMP is always 32bit aligned*/ int lineLength = w * 3; lineLength = (lineLength % 4) ? (lineLength | 0x3) + 1 : lineLength; int fileSize = BMPHeader::HEADER_SIZE + h * lineLength; uint8_t *data = new uint8_t[fileSize]; if (!data) { fclose(fp); return false; } memset(data, 0, BMPHeader::HEADER_SIZE /*fileSize*/); data[0x0] = BMPHeader::HEADER_SIGNATURE[0]; data[0x1] = BMPHeader::HEADER_SIGNATURE[1]; *((uint32_t *)(data + 0x2)) = h * lineLength + BMPHeader::HEADER_SIZE; data[0x6] = 0; data[0x7] = 0; *((uint32_t *)(data + 0xA)) = BMPHeader::HEADER_SIZE; *((uint32_t *)(data + 0xE)) = 0x28; *((uint32_t *)(data + 0x12)) = w; *((uint32_t *)(data + 0x16)) = h; *((uint16_t *)(data + 0x1A)) = 1; *((uint16_t *)(data + 0x1C)) = 24; *((uint32_t *)(data + 0x1E)) = 0; *((uint32_t *)(data + 0x22)) = lineLength * h; *((uint32_t *)(data + 0x26)) = 0x0000B013; *((uint32_t *)(data + 0x2A)) = 0x0000B013; *((uint32_t *)(data + 0x2E)) = 0x0; *((uint32_t *)(data + 0x32)) = 0x0; for (int i = 0; i < h; i++) { uint8_t *offset = data + BMPHeader::HEADER_SIZE + (lineLength * (h - 1 - i)); // lines are flipped vertically there int j; for (j = 0; j < w; j++) { RGBColor pixel = buffer->element(i, j); *offset++ = pixel.b(); *offset++ = pixel.g(); *offset++ = pixel.r(); } // Put in predictable padding values for (int k = j * 3; k < lineLength; k++) { *offset++ = 0; } } fwrite(data, sizeof(uint8_t), fileSize, fp); fclose(fp); delete[] data; return true; }