C++ 分水岭分割 opencv xcode
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11435974/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
watershed segmentation opencv xcode
提问by Yaozhong
I am now learning a code from the opencv codebook (OpenCV 2 Computer Vision Application Programming Cookbook): Chapter 5, Segmenting images using watersheds, page 131.
我现在正在从 opencv 代码手册(OpenCV 2 计算机视觉应用程序编程手册)学习代码:第 5 章,使用分水岭对图像进行分割,第 131 页。
Here is my main code:
这是我的主要代码:
#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);
}
However, it doesn't work. How could I initialize a binary image? And how could I make this segmentation code work?
但是,它不起作用。我怎么能初始化一个二进制图像?我怎样才能使这个分段代码工作?
I am not very clear about this part of the book. Thanks in advance!
书的这部分我不是很清楚。提前致谢!
回答by karlphillip
There's a couple of things that should be mentioned about your code:
关于您的代码,应该提到以下几点:
- Watershed expects the input and the output image to have the same size;
- You probably want to get rid of the
const
parameters in the methods; - Notice that the result of watershed is actually
markers
and notimage
as your code suggests; About that, you need to grab the return ofprocess()
!
- Watershed 期望输入和输出图像具有相同的大小;
- 你可能想去掉方法中的
const
参数; - 请注意,分水岭的结果实际上
markers
并不image
像您的代码所暗示的那样;关于那个,你需要抓住process()
!
This is your code, with the fixes above:
这是您的代码,具有上述修复程序:
// 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;
}
I took the liberty of using Abid's input image for testing and this is what I got:
我冒昧地使用 Abid 的输入图像进行测试,这就是我得到的:
回答by Abid Rahman K
Below is the simplified version of your code, and it works fine for me. Check it out :
以下是您的代码的简化版本,对我来说效果很好。一探究竟 :
#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);
}
Below is my input image :
以下是我的输入图像:
Below is my output image :
下面是我的输出图像:
See the code explanation here : Simple watershed Sample in OpenCV
请参阅此处的代码说明:OpenCV 中的简单分水岭示例
回答by SlenderMuse
I had the same problem as you, following the exact same code sample of the cookbook (great book btw).
我和你有同样的问题,遵循食谱的完全相同的代码示例(顺便说一句好书)。
Just to place the matter I was coding under Visual Studio 2013 and OpenCV 2.4.8. After a lot of searching and no solutions I decided to change the IDE.
只是为了将我在 Visual Studio 2013 和 OpenCV 2.4.8 下编码的问题。经过大量搜索但没有解决方案,我决定更改IDE。
It's still Visual Studio BUT it's 2010!!!! And boom it works!
它仍然是 Visual Studio,但它是 2010 年!!!!繁荣它的工作原理!
Becareful of how you configure Visual Studio with OpenCV. Here's a great tutorial for installation here
注意如何使用 OpenCV 配置 Visual Studio。这是一个很棒的安装教程here
Good day to all
祝大家有个美好的一天