examples - sumpig/OpenCV GitHub Wiki

GrabCut 分割图像

main.cpp

int main() 
{
	cv::Mat image = cv::imread("H:\\opencv_c++\\boldt.jpg");
	if (image.empty())
		return 0;

	cv::Rect rectangle(5, 70, 260, 120);
	cv::Mat result, bgModel, fgModel; 

	// GrabCut 分割算法
	cv::grabCut(image, // 输入
		result,          // 分割结果
		rectangle,       // 前景区域
		bgModel, fgModel,// 模型存储 
		5,               // 迭代次数
		cv::GC_INIT_WITH_RECT); // 矩形方法

	cv::compare(result, cv::GC_PR_FGD, result, cv::CMP_EQ);

	// 生成输出图像
	cv::Mat foreground(image.size(), CV_8UC3, cv::Scalar(255, 255, 255));
	image.copyTo(foreground, result); 

	cv::namedWindow("result");
	cv::imshow("result", foreground);
	cv::waitKey(0);

	return 0;
}

original result foreground

分水岭图像分割

watershed.h

#if !defined WATERSHS
#define WATERSHS

#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>

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

	// 返回标签图像
	cv::Mat getSegmentation() {
		cv::Mat tmp;
		markers.convertTo(tmp, CV_8U);
		return tmp;
	}

	// 返回边缘图像
	cv::Mat getWatersheds() {
		cv::Mat tmp;
		markers.convertTo(tmp, CV_8U, 255, 255);
		return tmp;
	}
};

#endif

main.cpp

int main() 
{
	cv::Mat image = cv::imread("H:\\opencv_c++\\apple.jpg");
	if (image.empty())
		return 0;

	// 标识背景像素
	cv::Mat imageMask(image.size(), CV_8U, cv::Scalar(0));
	cv::rectangle(imageMask, cv::Point(5, 5),
		cv::Point(image.cols - 5, image.rows - 5),
		cv::Scalar(255), 3);

	// 标识前景像素
	cv::rectangle(imageMask,
		cv::Point(image.cols / 2 - 20, image.rows / 2 - 20),
		cv::Point(image.cols / 2 + 20, image.rows / 2 + 20),
		cv::Scalar(1), 10);

	WatershedSegmenter segmenter;
	segmenter.setMarkers(imageMask);
	segmenter.process(image);

	return 0;
}