分水岭算法---Kinect V2开发学习(3)

#include <iostream>
#include <Windows.h>
#include <opencv.hpp>
#include <Kinect.h>
#include <opencv2/imgproc.hpp>
using namespace std;
using namespace cv;
#include "watershedSegmentation.h"

void delay(int a)
{
	int b, i, j;
	b = a * 10000;
	for (i = 0; i < b; i++)
	{
		for (j = 0; j < b; j++)
		{

		}
	}

}



int main(int argc, char* argv[])
{
	//添加语句
	bool save = true;

	namedWindow("Color", 0);
	IKinectSensor *sensor = nullptr;//创建KinectSensor空指针
	IColorFrameSource *source = nullptr;
	IColorFrameReader *reader = nullptr;
	IColorFrame *frame = nullptr;
	IFrameDescription *description = nullptr;

	int height = 0, width = 0;
	unsigned int bytesPerPixel = 0;
	HRESULT result;

	result = GetDefaultKinectSensor(&sensor);//获取默认Kinect Device
	if (SUCCEEDED(result))//判断是否正确获取Kinect
	{
		cout << "Found Kinect Device" << endl;
	}
	else
	{
		return result;
	}

	result = sensor->Open();//打开Kinect
	Sleep(500);//等待500ms,保证Kinect正确打开
	if (SUCCEEDED(result))
	{
		cout << "Success to open Kinect" << endl;
	}
	else
	{
		return result;
	}
	result = sensor->get_ColorFrameSource(&source);//获取ColorFrameSource
	if (SUCCEEDED(result))
	{
		cout << "Get Color Source" << endl;
	}
	else
	{
		return result;
	}

	source->get_FrameDescription(&description);//获取帧格式描述
	description->get_Height(&height);//帧高度
	description->get_Width(&width);//帧宽度
	description->get_BytesPerPixel(&bytesPerPixel);//每一像素的大小,单位Byte
	cout << height << endl << width << endl << bytesPerPixel << endl;
	//Sleep(15000);
	//return -1;
	result = source->OpenReader(&reader);//获取彩色图像Reader
	if (SUCCEEDED(result))
	{
		cout << "Get Color Reader" << endl;
	}
	else
	{
		return result;
	}

	Mat colorImage(height, width, CV_8UC4);  //创建Mat,用来放彩色图像数据
	Mat firstframe(height, width, CV_8UC4);
	Mat difframe(height, width, CV_8UC4);
	Mat nowframe(height, width, CV_8UC4);
	Mat firstframe_gray;
	Mat nowframe_gray;

	while (1)
	{
		result = reader->AcquireLatestFrame(&frame);   //获取最新的彩色帧
		if (FAILED(result) || !frame)      //检测是否成功获取帧数据,并不是每一次都能成功获取的
		{
			continue;
		}
		else
		{
			frame->CopyConvertedFrameDataToArray(height * width * 4 * sizeof(BYTE), reinterpret_cast<BYTE*>(colorImage.data), ColorImageFormat_Bgra);//图像数据流转换

			frame->Release();//每一次获取帧后都要释放
			imshow("Color", colorImage);//绘制当前图像

				//添加
			if (save == true)   //保存第一帧背景图
			{
				delay(2);
				imwrite("first.jpg", colorImage);
				firstframe = imread("first.jpg", IMREAD_COLOR);     //frame_first为背景彩色图				
				cvtColor(firstframe , firstframe_gray, CV_BGR2GRAY);//framepro为背景灰度图	
				save = false;
			}

			imwrite("now.jpg", colorImage);
			nowframe = imread("now.jpg", IMREAD_COLOR);       //当前帧彩色图
			cvtColor(nowframe, nowframe_gray, CV_BGR2GRAY);    //当前帧灰度图
			absdiff(nowframe_gray, firstframe_gray, difframe);
			threshold(difframe, difframe, 50, 255, CV_THRESH_BINARY);//阈值分割
			imshow("image", firstframe);   //显示第一帧彩色图
			//imshow("test", difframe);     //显示差分结果

			//分水岭算法
			Mat fg;
			erode(difframe, fg, Mat(), Point(-1, -1), 4);

			// 显示前景图像
			//namedWindow("Foreground Image");
			//cv::imshow("Foreground Image", fg);

			// 标识不含物体的图像像素
			Mat bg;
			dilate(difframe, bg, Mat(), Point(-1, -1), 4);
			threshold(bg, bg, 1, 128, THRESH_BINARY_INV);

			// 显示背景图像
			//namedWindow("Background Image");
			//imshow("Background Image", bg);

			// 创建标记图像,黑色为不确定,白色为前景,灰色为背景
			Mat markers(difframe.size(), CV_8U, Scalar(0));
			markers = fg + bg;
//			namedWindow("Markers");
//			imshow("Markers", markers);

			// 创建分水岭分割类的对象
			WatershedSegmenter segmenter;

			// 设置标记图像,然后进行分割
			segmenter.setMarkers(markers);
			segmenter.process(nowframe);

			// 显示分割结果
			namedWindow("Segmentation");
			imshow("Segmentation", segmenter.getSegmentation());

			// 显示分水岭
			namedWindow("Watersheds");
			imshow("Watersheds", segmenter.getWatersheds());



		}
		if (waitKey(40) > 0)//按任意键退出程序
			break;
	}
	reader->Release();  //释放指针
	source->Release();
	sensor->Close();   //sensor记得要先Close再释放
	sensor->Release();
	return 0;
}
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>

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

分水岭算法---Kinect V2开发学习(3)

分水岭算法---Kinect V2开发学习(3)

分水岭算法---Kinect V2开发学习(3)