C++ Version, nicht geeignet für den direkten Einsatz in Android
ich eine Lösung für Ihr Problem entwickelt; ist nicht perfekt, aber Sie können es versuchen. Bitte beachten Sie, dass die roten Bereiche wirklich rot sein müssen, also RGB (255,0,0). In dem Bild, das Sie zur Verfügung gestellt hatten, waren die roten Regionen nicht perfekt rot.
#include <iostream>
#include <vector>
#include <opencv2/opencv.hpp>
cv::Mat fillWall(cv::Mat homeImage, cv::Mat screenshot);
int main()
{
cv::Mat originalImage = cv::imread("original2.png");
cv::Mat maskImage = cv::imread("maks.jpg");
cv::Mat finalImage = fillWall(originalImage, maskImage);
cv::imshow("result", finalImage);
cv::waitKey(5000);
return 0;
}
cv::Mat fillWall(cv::Mat originalImage, cv::Mat pattern)
{
cv::Mat output;
cv::Mat rectHome;
// Preproc
cv::cvtColor(originalImage, originalImage, CV_RGBA2BGR);
// Select only red regions in the originalImage.
cv::inRange(originalImage, cv::Scalar(254, 0, 0), cv::Scalar(255, 0, 0), rectHome);
cv::Mat originalMask;
rectHome.copyTo(originalMask);
originalImage.copyTo(output);
// Contours
std::vector<std::vector<cv::Point>> allContours;
std::vector<std::vector<cv::Point>> contours;
allContours.reserve(10);
cv::findContours(rectHome, allContours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
for (auto &c : allContours) {
if (c.size() > 50) {
contours.push_back(c);
}
}
// Find the rotated rectangles for each contour
// This approx the contours to rectangles.
std::vector<cv::RotatedRect> minRect;
for(size_t i = 0; i < contours.size(); i++) {
minRect.push_back(cv::minAreaRect(cv::Mat(contours[i])));
}
for (int ci = 0; ci < minRect.size(); ci++) {
cv::Point2f pointsRes[4], pointsIn[4];
pointsIn[0] = cv::Point2f(10, 10) ;
pointsIn[1] = cv::Point2f(pattern.cols - 10, 10);
pointsIn[2] = cv::Point2f(pattern.cols - 10, pattern.rows - 10);
pointsIn[3] = cv::Point2f(10, pattern.rows - 10);
cv::Point2f rect[4];
minRect[ci].points(rect);
pointsRes[3] = rect[2];
pointsRes[2] = rect[3];
pointsRes[1] = rect[0];
pointsRes[0] = rect[1];
// Do a perspective transform in order to display
// the pattern image with the correct orientation
cv::Mat prsxTrnsf = cv::getPerspectiveTransform(pointsIn, pointsRes);
cv::Mat outScreen;
cv::warpPerspective(pattern, outScreen, prsxTrnsf, cv:: Size(originalImage.cols , originalImage.rows));
cv::cvtColor(outScreen, outScreen, CV_BGRA2RGB);
for (int row = 0; row < originalImage.rows; row++) {
for (int col = 0; col < originalImage.cols; col++) {
double inside = cv::pointPolygonTest(contours[ci], cv::Point2f(col,row), false);
if (originalMask.at<uchar>(row, col) == 255 && inside >= 0) {
output.at<cv::Vec3b>(row, col) = outScreen.at<cv::Vec3b>(row, col);
}
}
}
}
cv::cvtColor(output, output, CV_BGR2RGBA);
return output;
}

anzumerken, dass das Musterbild gedreht zufällig ist; Wenn Sie mir sagen, wie Sie das Muster wollen, kann ich es einstellen. Ich denke, dass dies ein guter Anfang ist.
Was ist die Programmiersprache? ndk? oder ...? bitte posten Sie hier den Link wie Sie wie Sie auf Android arbeiten. Vielen vielen Dank. –
Sorry, ich habe total vergessen, dass Android Java bedeutet. Dies ist C++ - Code, den Sie nicht direkt in einer Android-App verwenden können. Ich denke, Sie haben hier zwei Möglichkeiten: Versuchen Sie, den Code mit dem OpenCV für Java zu übersetzen, oder verwenden Sie direkt den obigen C++ - Code unter folgendem Link: http://docs.opencv.org/2.4.2/doc/tutorials/introduction/android_binary_package /android_binary_package_using_with_NDK.html –
In jedem Fall können Sie den Algorithmus in der Funktion * fillWall * vorgeschlagen und übersetzen für Android, sollte nicht schwierig sein. –