opencv分水岭算法对图像进行切割
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了opencv分水岭算法对图像进行切割相关的知识,希望对你有一定的参考价值。
先看效果
说明
使用分水岭算法对图像进行切割,设置一个标记图像能达到比較好的效果,还能防止过度切割。
1、这里首先对阈值化的二值图像进行腐蚀,去掉小的白色区域,得到图像的前景区域。并对前景区域用255白色标记
2、相同对阈值化后的图像进行膨胀,然后再阈值化并取反。得到背景区域。
并用128灰度表示
3、将前景和背景叠加在一起在同一幅图像中显示。
4、用标记图和原图,利用opencv的watershed对图像进行切割。
源代码class WatershedSegment{
private:
cv::Mat markers;
public:
void setMarkers(const cv::Mat &image){
image.convertTo(markers,CV_32S);
}
cv::Mat process(const cv::Mat &image) {
// Apply watershed
cv::watershed(image,markers);
markers.convertTo(markers,CV_8U);
return markers;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
cv::Mat image = cv::imread("group.jpg");
cv::Mat binary = cv::imread("binary.bmp",0); //没加0害得我找好久错误的原因。即使"binary.bmp"为二值图像不加0读进来还是3通道
//cv::threshold(image,binary,60,255,CV_THRESH_BINARY); //阈值化操作
//binary = 255 - binary; //让前景变为白色区域
cv::namedWindow("binary",CV_WINDOW_AUTOSIZE);
cv::imshow("binary",binary);
cv::Mat fImage;
cv::erode(binary,fImage,cv::Mat(),cv::Point(-1,-1),6); //binary = 255 - binary; //让前景变为白色区域//腐蚀去掉小的干扰物体得到前景图像
cv::namedWindow("eroded",CV_WINDOW_AUTOSIZE);
cv::imshow("eroded",fImage);
cv::Mat bImage;
cv::dilate(binary,bImage,cv::Mat(),cv::Point(-1,-1),6);
cv::threshold(bImage,bImage,1,128,cv::THRESH_BINARY_INV);//对原始二值图像阈值化并取反,得到背景图像
cv::namedWindow("bImage",CV_WINDOW_AUTOSIZE);
cv::imshow("bImage",bImage);
cv::Mat marker(binary.size(),CV_8U,cv::Scalar(0));
marker = fImage + bImage; //创建标记图像
cv::namedWindow("marker",CV_WINDOW_AUTOSIZE);
cv::imshow("marker",marker);
WatershedSegment segmenter;
segmenter.setMarkers(marker);
cv::Mat segment = segmenter.process(image);
cv::namedWindow("segmenter",CV_WINDOW_AUTOSIZE);
cv::imshow("segmenter",segment);
cv::waitKey(0);
return 0;
}
:
以上是关于opencv分水岭算法对图像进行切割的主要内容,如果未能解决你的问题,请参考以下文章