【问题标题】:How get contours between objects with OpenCV Watershed?如何使用 OpenCV Watershed 获得对象之间的轮廓?
【发布时间】:2014-07-25 04:17:48
【问题描述】:

我将 OpenCV 分水岭与我的图像一起使用:

#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;
}

但这给了我唯一的面具。我还尝试将标记创建为两个点 - 结果只有一个蒙版。使用 OpenCV 是否可以像 http://biodynamics.ucsd.edu/ir/ 示例那样使用轮廓分隔单元格(对象)? 如果不是,是否可以使用以下值创建结果掩码:1 表示第一个对象,2 - 表示第二个对象,.. 99 表示 99 ?

【问题讨论】:

标签: c++ opencv mask image-segmentation watershed


【解决方案1】:

表演后

cv::watershed(image, markers);

markers 图像在区域边界处为 -1,在与标记为 1 的种子对应的区域中为 1,在与标记为 2 的种子对应的区域中为 2 , 等等。所以你可以这样做:

cv::Mat region1 = markers==1;

【讨论】:

    【解决方案2】:

    我使用以下方法在分水岭分割后提取对象计数。分水岭输出是一个标记图像,其中包含每个像素的段代码。我从标记图像中为每个单个对象段创建一个二进制掩码图像。这可以在标记图像的所有像素上进行一次迭代。对于核心“for 循环”,请参阅 opencv 示例 https://github.com/Itseez/opencv/blob/master/samples/cpp/watershed.cpp。我将所有对象掩码存储在vector &lt;Mat&gt; 中。然后我在每个这样的掩码上运行 findContours -> 每个对象的轮廓。见http://docs.opencv.org/doc/tutorials/imgproc/shapedescriptors/find_contours/find_contours.html。您只是不需要使用边缘检测器 Canny,因为掩码图像已经是二进制的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-08-23
      • 2022-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-04
      • 2016-10-24
      相关资源
      最近更新 更多