2016-07-24 7 views
0

Androidのopencvで、下の画像の赤いオブジェクトを見つけて、2番目の写真のようなパターンで埋め込むにはどうしたらいいですか?opencvでオブジェクトを見つけてアンドロイドの新しい写真と置き換える方法は?

壁をマスキングパターンで自動的に塗りつぶすアプリを作成する必要があります。ユーザーが画像パターンをクリックすると、選択したパターンで画像が塗りつぶされます。

これを実行するライブラリをご記入ください。

ありがとうございました。

enter image description here enter image description here

答えて

0

アンドロイド

で直接使用するのに適していない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; 
} 
Output image

パターン画像を回転ランダムであることに注意してください。パターンをどのようにしたいか教えてくれたら、それを調整することができます。私はこれが始めるには良い場所だと思います。

+0

どのようなプログラミング言語が使用されていますか? ndk?or ...?ここに投稿してくださいあなたのようにあなたのように働く方法のリンクアンドロイド。非常に非常にありがとう。 –

+0

申し訳ありませんが、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 –

+0

いずれにしても、* fillWall *関数で提案されているアルゴリズムに従って、Android用に翻訳することは難しくありません。 –