分水岭算法---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;
}
};