1

イメージで OpenCV Watershed を使用します。

#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("d:\\projekty\\OpenCV\\trainData\\base01.jpg"); //http://i.imgur.com/sEWFHfY.jpg
    cv::Mat blank(image.size(),CV_8U,cv::Scalar(0xFF));
    cv::Mat dest;
    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.rows-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
    int centreW = image.cols/4;
    int centreH = image.rows/4;
    markers(Rect((image.cols/2)-(centreW/2),(image.rows/2)-(centreH/2), centreW, centreH)) = Scalar::all(2);
    markers.convertTo(markers,CV_BGR2GRAY);
    imshow("markers", markers);

    //Create watershed segmentation object
    WatershedSegmenter segmenter;
    segmenter.setMarkers(markers);
    cv::Mat wshedMask = segmenter.process(image);
    cv::Mat mask;
    convertScaleAbs(wshedMask, mask, 1, 0);
    double thresh = threshold(mask, mask, 1, 255, THRESH_BINARY);
    bitwise_and(image, image, dest, mask);
    dest.convertTo(dest,CV_8U);

    imshow("final_result", dest);
    cv::waitKey(0);

    return 0;
}

しかし、これは私に個別のマスクしか与えません。また、2 つのポイントとしてマーカーを作成しようとしましたが、結果は 1 つのマスクだけでした。http://biodynamics.ucsd.edu/ir/の例のように、OpenCV でセル (オブジェクト) を輪郭で分離することは可能ですか? そうでない場合、値を持つ結果マスクとして作成することは可能ですか?

4

2 に答える 2

2

流域セグメンテーション後にオブジェクトの輪郭を抽出するために、次のアプローチを使用します。流域出力は、各ピクセルのセグメント コードを含む 1 つのマーカー イメージです。マーカー画像から単一のオブジェクト セグメントごとにバイナリ マスク画像を作成します。これは、マーカー画像のすべてのピクセルに対して 1 回の反復で実行できます。コアの「for ループ」については、opencv の例https://github.com/Itseez/opencv/blob/master/samples/cpp/watershed.cppを参照してください。すべてのオブジェクト マスクを に保存していvector <Mat>ます。次に、そのようなすべてのマスクで findContours を実行します->各オブジェクトの輪郭。http://docs.opencv.org/doc/tutorials/imgproc/shapeescriptors/find_contours/find_contours.htmlを参照してください。マスク画像は既にバイナリであるため、エッジ検出器 Canny を使用する必要はありません。

于 2014-07-24T20:17:48.490 に答える