アンドロイド
で直接使用するのに適していないC++バージョン、私はあなたの問題の解決策を開発しました。完璧ではありませんが、あなたはそれを試すことができます。 赤色の領域はとなります。実際にはの赤色なので、RGB(255,0,0)です。 あなたが提供したイメージでは、赤い領域は完全に赤ではありませんでした。
#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;
}
パターン画像を回転ランダムであることに注意してください。パターンをどのようにしたいか教えてくれたら、それを調整することができます。私はこれが始めるには良い場所だと思います。
どのようなプログラミング言語が使用されていますか? ndk?or ...?ここに投稿してくださいあなたのようにあなたのように働く方法のリンクアンドロイド。非常に非常にありがとう。 –
申し訳ありませんが、AndroidはJavaを完全に忘れています。これはC++コードなので、Android Appで直接使用することはできません。ここでは2つの選択肢があると思います:OpenCV for Javaを使用してコードを翻訳しようとするか、上記のC++コードを直接このリンクの次に使用してください:http://docs.opencv.org/2.4.2/doc/tutorials/introduction/android_binary_package /android_binary_package_using_with_NDK.html –
いずれにしても、* fillWall *関数で提案されているアルゴリズムに従って、Android用に翻訳することは難しくありません。 –