8

画像 (.jpg 画像) があり、元の画像から背景を抽出したいと考えています。私はたくさんグーグルで検索しましたが、前景画像を抽出するチュートリアルしか見つかりませんでした。

別のスタックオーバーフローの質問からコードを取得しました。コードは問題なく機能しており、フォアグラウンドの抽出に成功しました (私の要件に従って)。ここで、この前景を元の画像から完全に削除したいと思います。私はそれがこのようなものになりたい:-

背景 = 元のイメージ - 前景

空のスペースは、黒または白の色で埋めることができます。どうすればこれを達成できますか?

私はこのテクニックを使ってみました:-

Mat background = image2 - foreground;

しかし、それは完全な黒いイメージを与えます。

コード:-

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main( )
{
// Open another image
Mat image;
image= cv::imread("images/abc.jpg");

Mat image2 = image.clone();

// define bounding rectangle
cv::Rect rectangle(40,90,image.cols-80,image.rows-170);

cv::Mat result; // segmentation result (4 possible values)
cv::Mat bgModel,fgModel; // the models (internally used)

// GrabCut segmentation
cv::grabCut(image,    // input image
            result,   // segmentation result
            rectangle,// rectangle containing foreground
            bgModel,fgModel, // models
            1,        // number of iterations
            cv::GC_INIT_WITH_RECT); // use rectangle
cout << "oks pa dito" <<endl;
// Get the pixels marked as likely foreground
cv::compare(result,cv::GC_PR_FGD,result,cv::CMP_EQ);
// Generate output image
cv::Mat foreground(image.size(),CV_8UC3,cv::Scalar(255,255,255));
//cv::Mat background(image.size(),CV_8UC3,cv::Scalar(255,255,255));
image.copyTo(foreground,result); // bg pixels not copied

// draw rectangle on original image
cv::rectangle(image, rectangle, cv::Scalar(255,255,255),1);

imwrite("img_1.jpg",image);

imwrite("Foreground.jpg",foreground);
Mat background = image2 - foreground;
imwrite("Background.jpg",background);

return 0;
}

注: 私は opencv の初心者であり、現在はあまり知識がありません。完全なコードを投稿するか (私の要求に応じて)、コード行のみを投稿して、これらのコード行が配置されている場所を教えていただければ、非常に感謝します。ありがとう。

PS これは、StackOverflow.com での 2 番目の質問です。申し訳ありません...慣習に従っていない場合。

4

4 に答える 4

12

前景のすべてのピクセルをコピーする代わりに、前景ではないすべてのピクセルをコピーします。~これは、マスクを無効にするを使用して行うことができます。

image.copyTo(background,~result);
于 2013-07-17T11:29:59.733 に答える
3

もしあなたが//Get the pixels marked as likely background:

// Get the pixels marked as likely background
cv::compare(result,cv::GC_PR_BGD,result,cv::CMP_EQ);

編集:上記のコードには GC_BGD ピクセルがありません。より効率的な回答が得られましたが、始めたことを終わらせましょう。

// Get the pixels marked as background
cv::compare(result,cv::GC_BGD,result_a,cv::CMP_EQ);
// Get the pixels marked as likely background
cv::compare(result,cv::GC_PR_BGD,result_b,cv::CMP_EQ);
// Final results
result=result_a+result_b;
于 2013-07-17T11:39:52.737 に答える
0

ちょっとした提案,<a href="https://stackoverflow.com/a/17698817/5671531">@William の回答はより簡潔に次のように書くことができます:</p>

result = result & 1;

バイナリマスクを取得するために。

于 2017-06-03T14:08:26.030 に答える