OpenCV 分水岭算法 图像进行分割

水岭分割方法是一种基于拓扑理论的数学形态学的分割方法,其基本思想是把图像看作是测地学上的拓扑地貌,图像中每一点像素的灰度值表示该点的海拔高度,每一个局部极小值及其影响区域称为集水盆,而集水盆的边界则形成分水岭。

1.创建WatershedSegmenter类处理方法

/*WatershedSegmenter*/

class WatershedSegmenter {

private:

	cv::Mat markers;

public:

	void setMarkers(const cv::Mat& markerImage) {

		// Convert to image of ints
		markerImage.convertTo(markers, CV_32S);
	}

	cv::Mat process(const cv::Mat &image) {

		// Apply watershed
		cv::watershed(image, markers);

		return markers;
	}

	// Return result in the form of an image
	cv::Mat getSegmentation() {

		cv::Mat tmp;
		// all segment with label higher than 255
		// will be assigned value 255
		markers.convertTo(tmp, CV_8U);

		return tmp;
	}

	// Return watershed in the form of an image
	cv::Mat getWatersheds() {

		cv::Mat tmp;
		markers.convertTo(tmp, CV_8U, 255, 255);

		return tmp;
	}
};

2.实现过程

void OpenCVQtGui::Watershed_clicked()
{
	cv::Mat Result = image.clone();

	cvtColor(Result, Result, CV_BGR2GRAY);

	/**/
// 	cv::threshold(Result, Result, 0, 255, cv::THRESH_BINARY|cv::THRESH_OTSU);
// 	
// 	cv::imshow("Foreground Image1", Result);
// 
// 	/*形态学操作,进一步消除图像中噪点*/
// 	cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
// 
// 	cv::morphologyEx(Result, Result, cv::MORPH_OPEN, element, cv::Point(-1, -1), 2);
// 	
// 	cv::Mat bg;
// 	cv::dilate(Result, bg, element, cv::Point(-1, -1), 6);
// 	cv::imshow("Background Image2", bg);



//Eliminate noise and smaller objects
	cv::threshold(Result, Result, 0, 255, cv::THRESH_BINARY | cv::THRESH_OTSU);
	cv::Mat fg;
	cv::erode(Result, fg, cv::Mat(), cv::Point(-1, -1), 6);

	// Display the foreground image
	cv::imshow("Foreground Image1", fg);

	// Identify image pixels without objects
	cv::Mat bg;
	cv::dilate(Result, bg, cv::Mat(), cv::Point(-1, -1), 6);

	cv::threshold(bg, bg, 1, 128, cv::THRESH_BINARY_INV);

	// Display the background image
	cv::imshow("Background Image2", bg);

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

	cv::imshow("Markers3", markers);

	// Create watershed segmentation object
	WatershedSegmenter segmenter;

	// Set markers and process
	segmenter.setMarkers(markers);
	markers = segmenter.process(image);
	//cv::imshow("Segmentation4", image);
	// Display segmentation result
	cv::imshow("Segmentation4", segmenter.getSegmentation());

	// Display watersheds
	
	
	cv::Mat marker1 = segmenter.getWatersheds();

	cv::imshow("Waterheds5", marker1);


	cv::Mat mask;

	cv::compare(markers, -1, mask, cv::CMP_EQ);

	cv::imshow("Waterheds6", mask);

	Result = image.clone();

	Result.setTo(cv::Scalar(0, 255, 0), mask);
	
	cvtColor(Result, Result, CV_BGR2RGB);

	QImage img1 = QImage((const unsigned char*)(Result.data), Result.cols, Result.rows, QImage::Format_RGB888);

	ui.label_2->setPixmap(QPixmap::fromImage(img1));

	ui.label_2->resize(QSize(img1.width(), img1.height()));
}

3.实现结果

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值