opencv:分水嶺分割

參考:http://www.voidcn.com/article/p-uvzxwqea-bch.html

 

 

 

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

#include <iostream>

using namespace cv;
using namespace std;

Vec3b RandomColor(int value);  //生成隨機顏色函數



int main(int argc, char* argv[])
{
	Mat image = imread("D:\\xxxxxx\\image\\4078.png");//載入RGB彩色圖像
	imshow("Source Image", image);

	//灰度化,濾波,Canny邊緣檢測
	Mat imageGray, imageCanny;
	cvtColor(image, imageGray, CV_BGR2GRAY);//灰度轉換
	GaussianBlur(imageGray, imageGray, Size(5, 5), 2);   //高斯濾波
	imshow("Gray Image", imageGray);
	Canny(imageGray, imageCanny, 40, 100);
	imshow("Canny Image", imageCanny);

	//查找輪廓
	vector<vector<Point>> contours;
	vector<Vec4i> hierarchy;
	findContours(imageCanny, contours, hierarchy, RETR_LIST, CHAIN_APPROX_SIMPLE, Point());
	Mat imageContours = Mat::zeros(image.size(), CV_8UC1);  //輪廓	
	Mat marks(image.size(), CV_32S);   //Opencv分水嶺第二個矩陣參數
	marks = Scalar::all(0);
	int index = 0;
	int compCount = 0;
	for (; index >= 0; index = hierarchy[index][0], compCount++)
	{
		//對marks進行標記,對不同區域的輪廓進行編號,相當於設置注水點,有多少輪廓,就有多少注水點
		drawContours(marks, contours, index, Scalar::all(compCount + 1), 1, 8, hierarchy);
		drawContours(imageContours, contours, index, Scalar(255), 1, 8, hierarchy);
	}

	//我們來看一下傳入的矩陣marks裏是什麼東西
	Mat marksShows;
	convertScaleAbs(marks, marksShows);
	imshow("marksShow", marksShows);
	imshow("輪廓", imageContours);
	watershed(image, marks);

	//我們再來看一下分水嶺算法之後的矩陣marks裏是什麼東西
	Mat afterWatershed;
	convertScaleAbs(marks, afterWatershed);
	imshow("After Watershed", afterWatershed);

	//對每一個區域進行顏色填充
	Mat PerspectiveImage = Mat::zeros(image.size(), CV_8UC3);
	for (int i = 0; i < marks.rows; i++)
	{
		for (int j = 0; j < marks.cols; j++)
		{
			int index = marks.at<int>(i, j);
			if (marks.at<int>(i, j) == -1)
			{
				PerspectiveImage.at<Vec3b>(i, j) = Vec3b(255, 255, 255);
			}
			else
			{
				PerspectiveImage.at<Vec3b>(i, j) = RandomColor(index);
			}
		}
	}
	imshow("After ColorFill", PerspectiveImage);

	//分割並填充顏色的結果跟原始圖像融合
	Mat wshed;
	addWeighted(image, 0.4, PerspectiveImage, 0.6, 0, wshed);
	imshow("AddWeighted Image", wshed);

	//waitKey();
	cvWaitKey(0);
	return 0;
}

Vec3b RandomColor(int value)    //生成隨機顏色函數
{
	value = value % 255;  //生成0~255的隨機數
	RNG rng;
	int aa = rng.uniform(0, value);
	int bb = rng.uniform(0, value);
	int cc = rng.uniform(0, value);
	return Vec3b(aa, bb, cc);
}

原圖:                                                           灰度:                                                   輪廓:                                   

                       

Mark:                                                        輪廓:                                              分水嶺:                                                    

                              

填充顏色:

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章