こんにちは、私は現在、OpenCV ライブラリを使用して基本的な C++ アプリケーションを作成して、画像の主題を背景からセグメント化しています。アプリケーションは画像ファイルを読み取り、ウォーターシェッド アルゴリズムを使用して、エッジ周辺で検出したデータと画像の中心で検出したデータに基づいてマスクを生成します。
(最初に、全体の値が -1 の画像オブジェクトを作成しました。次に、値が 1 の空の画像の周囲に境界線を作成しました。次に、画像のほぼ中央に、値が の長方形を作成しました。 2. 境界線と長方形は接触していません。)
元の画像と自動生成されたマスクの間のビットごとの AND を使用して、生成されたマスクを使用して画像からデータを削除しようとしました。
私はこれを C++ で書いています。誰かが私のコードを簡単に見てくれたらとてもありがたいです。私が見つけた唯一の同様の例は、Python のネイティブ OpenCV バインディングを使用したものでした。
サンプルマスク: http://i.imgur.com/a0SUwy3.png
サンプル画像: http://i.imgur.com/FQywu6P.png
// Usage: ./app input.jpg
#include "opencv2/opencv.hpp"
#include <string>
using namespace cv;
using namespace std;
class WatershedSegmenter{
private:
cv::Mat markers;
public:
void setMarkers(cv::Mat& markerImage)
{
markerImage.convertTo(markers, CV_32S);
}
cv::Mat process(cv::Mat &image)
{
cv::watershed(image, markers);
markers.convertTo(markers,CV_8U);
return markers;
}
};
int main(int argc, char* argv[])
{
cv::Mat image = cv::imread(argv[1]);
cv::Mat blank(image.size(),CV_8U,cv::Scalar(0xFF));
cv::Mat dest(image.size(),CV_8U,cv::Scalar(0xFF));
imshow("originalimage", image);
// Create markers image
cv::Mat markers(image.size(),CV_8U,cv::Scalar(-1));
//Rect(topleftcornerX, topleftcornerY, width, height);
//top rectangle
markers(Rect(0,0,image.cols, 5)) = Scalar::all(1);
//bottom rectangle
markers(Rect(0,image.cols-5,image.cols, 5)) = Scalar::all(1);
//left rectangle
markers(Rect(0,0,5,image.rows)) = Scalar::all(1);
//right rectangle
markers(Rect(image.cols-5,0,5,image.rows)) = Scalar::all(1);
//centre rectangle
markers(Rect(image.cols/2,image.rows/2,50, 50)) = Scalar::all(2);
//Create watershed segmentation object
WatershedSegmenter segmenter;
segmenter.setMarkers(markers);
cv::Mat result = segmenter.process(image);
result.convertTo(result,CV_8U);
bitwise_and(image, blank, dest, result);
imshow("final_result", dest);
cv::waitKey(0);
return 0;
}