C++ 分水岭分割opencv xcode

C++ 分水岭分割opencv xcode,c++,xcode,opencv,image-processing,watershed,C++,Xcode,Opencv,Image Processing,Watershed,我现在正在学习opencv代码手册(opencv 2计算机视觉应用程序编程食谱)中的一段代码:第5章,使用分水岭分割图像,第131页 这是我的主要代码: #include "opencv2/opencv.hpp" #include <string> using namespace cv; using namespace std; class WatershedSegmenter { private: cv::Mat markers; public:

我现在正在学习opencv代码手册(opencv 2计算机视觉应用程序编程食谱)中的一段代码:第5章,使用分水岭分割图像,第131页

这是我的主要代码:

#include "opencv2/opencv.hpp"
#include <string>

using namespace cv;
using namespace std;

class WatershedSegmenter {
    private:
    cv::Mat markers;
    public:
    void setMarkers(const cv::Mat& markerImage){
        markerImage.convertTo(markers, CV_32S);
    }

    cv::Mat process(const cv::Mat &image){
        cv::watershed(image,markers);
        return markers;
    }
};

int main ()
{
    cv::Mat image = cv::imread("/Users/yaozhongsong/Pictures/IMG_1648.JPG");

    // Eliminate noise and smaller objects
    cv::Mat fg;
    cv::erode(binary,fg,cv::Mat(),cv::Point(-1,-1),6);

    // Identify image pixels without objects
    cv::Mat bg;
    cv::dilate(binary,bg,cv::Mat(),cv::Point(-1,-1),6);
    cv::threshold(bg,bg,1,128,cv::THRESH_BINARY_INV);

    // Create markers image
    cv::Mat markers(binary.size(),CV_8U,cv::Scalar(0));
    markers= fg+bg;

    // Create watershed segmentation object
    WatershedSegmenter segmenter;
    // Set markers and process
    segmenter.setMarkers(markers);
    segmenter.process(image);

    imshow("a",image);
    std::cout<<".";
    cv::waitKey(0);
}
#包括“opencv2/opencv.hpp”
#包括
使用名称空间cv;
使用名称空间std;
类分水岭{
私人:
cv::Mat标记;
公众:
无效设置标记(常量cv::Mat和标记图像){
标记图像转换到(标记,CV_32S);
}
cv::Mat过程(常数cv::Mat和图像){
cv::流域(图像、标记);
返回标记;
}
};
int main()
{
cv::Mat image=cv::imread(“/Users/yaochongsong/Pictures/IMG_1648.JPG”);
//消除噪音和较小的物体
cv::Mat-fg;
侵蚀(二进制,fg,cv::Mat(),cv::Point(-1,-1),6);
//识别没有对象的图像像素
cv::Mat bg;
扩张(二进制,bg,cv::Mat(),cv::Point(-1,-1),6);
cv::threshold(bg,bg,1128,cv::THRESH_BINARY_INV);
//创建标记图像
cv::Mat标记(binary.size(),cv_8U,cv::Scalar(0));
标记=fg+bg;
//创建分水岭分割对象
分水岭分水岭;
//设置标记和进程
切割器。设置标记(标记);
分割器。处理(图像);
imshow(“a”,图像);

std::cout下面是您的代码的简化版本,对我来说效果很好。请查看:

#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

using namespace cv;
using namespace std;

int main ()
{
    Mat image = imread("sofwatershed.jpg");
    Mat binary = imread("sofwsthresh.png",0);

    // Eliminate noise and smaller objects
    Mat fg;
    erode(binary,fg,Mat(),Point(-1,-1),2);

    // Identify image pixels without objects
    Mat bg;
    dilate(binary,bg,Mat(),Point(-1,-1),3);
    threshold(bg,bg,1,128,THRESH_BINARY_INV);

// Create markers image
    Mat markers(binary.size(),CV_8U,Scalar(0));
    markers= fg+bg;

markers.convertTo(markers, CV_32S);
watershed(image,markers);

markers.convertTo(markers,CV_8U);
imshow("a",markers);
waitKey(0);
}
下面是我的输入图像:

下面是我的输出图像:


请参见此处的代码说明:

关于您的代码,有几件事需要提及:

  • 流域期望输入和输出图像具有相同的大小
  • 您可能希望去掉方法中的
    const
    参数
  • 请注意,分水岭的结果实际上是
    标记
    ,而不是您的代码所建议的
    图像
    ;关于这一点,您需要获取
    process()
    的返回
这是您的代码,包含上述修复程序:

// 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 binary;// = cv::imread(argv[2], 0);
    cv::cvtColor(image, binary, CV_BGR2GRAY);
    cv::threshold(binary, binary, 100, 255, THRESH_BINARY);

    imshow("originalimage", image);
    imshow("originalbinary", binary);

    // Eliminate noise and smaller objects
    cv::Mat fg;
    cv::erode(binary,fg,cv::Mat(),cv::Point(-1,-1),2);
    imshow("fg", fg);

    // Identify image pixels without objects
    cv::Mat bg;
    cv::dilate(binary,bg,cv::Mat(),cv::Point(-1,-1),3);
    cv::threshold(bg,bg,1, 128,cv::THRESH_BINARY_INV);
    imshow("bg", bg);

    // Create markers image
    cv::Mat markers(binary.size(),CV_8U,cv::Scalar(0));
    markers= fg+bg;
    imshow("markers", markers);

    // Create watershed segmentation object
    WatershedSegmenter segmenter;
    segmenter.setMarkers(markers);

    cv::Mat result = segmenter.process(image);
    result.convertTo(result,CV_8U);
    imshow("final_result", result);

    cv::waitKey(0);

    return 0;
}
//用法:./app input.jpg
#包括“opencv2/opencv.hpp”
#包括
使用名称空间cv;
使用名称空间std;
类分水岭{
私人:
cv::Mat标记;
公众:
无效设置标记(cv::Mat和markerImage)
{
标记图像转换到(标记,CV_32S);
}
cv::Mat过程(cv::Mat和图像)
{
cv::流域(图像、标记);
标记。转换到(标记,CV_8U);
返回标记;
}
};
int main(int argc,char*argv[])
{
cv::Mat image=cv::imread(argv[1]);
cv::Mat binary;//=cv::imread(argv[2],0);
cv::CVT颜色(图像、二进制、cv_bgr2灰色);
cv::阈值(二进制、二进制、100255、阈值二进制);
imshow(“原始图像”,图像);
imshow(“原始二进制”,二进制);
//消除噪音和较小的物体
cv::Mat-fg;
侵蚀(二进制,fg,cv::Mat(),cv::Point(-1,-1),2);
imshow(“fg”,fg);
//识别没有对象的图像像素
cv::Mat bg;
扩张(二进制,bg,cv::Mat(),cv::Point(-1,-1),3);
cv::threshold(bg,bg,1128,cv::THRESH\u BINARY\u INV);
imshow(“bg”,bg);
//创建标记图像
cv::Mat标记(binary.size(),cv_8U,cv::Scalar(0));
标记=fg+bg;
imshow(“markers”,markers);
//创建分水岭分割对象
分水岭分水岭;
切割器。设置标记(标记);
cv::Mat结果=分段器处理(图像);
结果。转换到(结果,CV_8U);
imshow(“最终结果”,结果);
cv::waitKey(0);
返回0;
}
我冒昧地使用了阿比德的输入图像进行测试,结果如下:


我遇到了与您相同的问题,遵循了与烹饪书完全相同的代码示例(顺便说一句,很棒的书)

只是把我编写的代码放在Visual Studio 2013和OpenCV 2.4.8下。经过大量搜索,没有解决方案,我决定更改IDE

它仍然是VisualStudio,但现在是2010年!!!!而且很好用

请注意如何使用OpenCV配置VisualStudio。下面是一个很棒的安装教程


大家好

您好,您在理解代码方面有问题吗?请检查所使用的OpenCV版本。我还听说那本书中有一些错误,我没有检查。我正在使用OpenCV 2.4.1…是的,我在理解代码方面有一些困难…您可以检查我在回答中设置的链接。不是关于算法如何运行RKS,但是它的功能是如何使用的。THX!我有一个问题:SoFixSeD.jpg和SoopWsLexh之间的关系。PNG。哦,对不起。SpWATHED.PNG是原始图像。SoopWsVal.PNG是阈值图像。实际上我使用Python。所以我不想在C++中再次对它进行二进制化。您可以在链接中找到那些我拥有的图像。最后,我有一个问题,你的最终图像是哪个图像?是Mat图像吗?我的图像在分水岭函数之后与原始图像相同……第二个图像就是结果。实际上我在C++中一点都不好。我只用Python。@ abIDRAHMANK + 1我赞成你的主动性答案,但是这不会显示他的错误。我也添加了一个答案。很酷!很有效!原始图像和二进制图像的大小应该是相同的。Thx!这是2012年的。OpenCV API从那时起可能有点变化。你有什么问题吗?@karlphillip我想他指的是没有发生分割的事实?@Daniel“不起作用”这是一个糟糕的问题定义。没有更多的技术信息,我无法帮助任何人。@Daniel谢谢你的评论。如果有人说“它不工作”,我永远也不会明白所有这些。我的第一个猜测是编译器或链接器相关的问题。