opencv学习(四)轮廓识别

本章学习轮廓识别

// bbb.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <opencv2/opencv.hpp>  
using namespace std;  
using namespace cv; 

int _tmain()
{
	const std::string sourceReference = "c://avi.avi";
	int delay = 1;

	char c;
	int frameNum = -1;			// Frame counter

	VideoCapture captRefrnc(sourceReference);

	if ( !captRefrnc.isOpened())
	{
		// 		cout  << "Could not open reference " << sourceReference << endl;
		return -1;
	}

	Size refS = Size( (int) captRefrnc.get(CV_CAP_PROP_FRAME_WIDTH),
		(int) captRefrnc.get(CV_CAP_PROP_FRAME_HEIGHT) );

	bool bHandFlag = false;

	const char* WIN_SRC = "Source";
	const char* WIN_RESULT = "Result";

	// Windows
	namedWindow(WIN_SRC, CV_WINDOW_AUTOSIZE );
	namedWindow(WIN_RESULT, CV_WINDOW_AUTOSIZE);

	Mat frame;	// 输入视频帧序列
	Mat frameHSV;	// hsv空间
	Mat mask(frame.rows, frame.cols, CV_8UC1);	// 2值掩膜
	Mat dst(frame);	// 输出图像

// 	Mat frameSplit[4];

	vector< vector<Point> > contours;	// 轮廓
	vector< vector<Point> > filterContours;	// 筛选后的轮廓
	vector< Vec4i > hierarchy;	// 轮廓的结构信息
	vector< Point > hull;	// 凸包络的点集

	while(true) //Show the image captured in the window and repeat
	{
		captRefrnc >> frame;

		if( frame.empty() )
		{
			cout << " < < <  Game over!  > > > ";
			break;
		}
		imshow( WIN_SRC, frame);

		// Begin

		// 中值滤波,去除椒盐噪声
		medianBlur(frame, frame, 5);
// 		GaussianBlur( frame, frameHSV, Size(9, 9), 2, 2 );
// 		imshow("blur2", frameHSV);
//		pyrMeanShiftFiltering(frame, frameHSV, 10, 10);
//	 	imshow(WIN_BLUR, frameHSV);
		// 转换到HSV颜色空间,更容易处理
		cvtColor( frame, frameHSV, CV_BGR2HSV );

// 		split(frameHSV, frameSplit);
// 		imshow(WIN_H, frameSplit[0]);
// 		imshow(WIN_S, frameSplit[1]);
// 		imshow(WIN_V, frameSplit[2]);

		Mat dstTemp1(frame.rows, frame.cols, CV_8UC1);
		Mat dstTemp2(frame.rows, frame.cols, CV_8UC1);
		// 对HSV空间进行量化,得到2值图像,亮的部分为手的形状
		inRange(frameHSV, Scalar(0,30,30), Scalar(40,170,256), dstTemp1);
		inRange(frameHSV, Scalar(156,30,30), Scalar(180,170,256), dstTemp2);
		bitwise_or(dstTemp1, dstTemp2, mask);
// 		inRange(frameHSV, Scalar(0,30,30), Scalar(180,170,256), dst);		

		// 形态学操作,去除噪声,并使手的边界更加清晰
		Mat element = getStructuringElement(MORPH_RECT, Size(3,3));
		erode(mask, mask, element);
		morphologyEx(mask, mask, MORPH_OPEN, element);
		dilate(mask, mask, element);
		morphologyEx(mask, mask, MORPH_CLOSE, element);

		frame.copyTo(dst, mask);

		contours.clear();
		hierarchy.clear();
		filterContours.clear();
		// 得到手的轮廓
		findContours(mask, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
		// 去除伪轮廓
		for (size_t i = 0; i < contours.size(); i++)
		{
// 			approxPolyDP(Mat(contours[i]), Mat(approxContours[i]), arcLength(Mat(contours[i]), true)*0.02, true);
			if (fabs(contourArea(Mat(contours[i]))) > 30000)	//判断手进入区域的阈值
			{
				filterContours.push_back(contours[i]);
			}
		}
		// 画轮廓
		drawContours(dst, filterContours, -1, Scalar(0,0,255), 3/*, 8, hierarchy*/);
		// 得到轮廓的凸包络
		for (size_t j=0; j<filterContours.size(); j++)
		{
			convexHull(Mat(filterContours[j]), hull, true);
			int hullcount = (int)hull.size();

			for (int i=0; i<hullcount-1; i++)
			{
				line(dst, hull[i+1], hull[i], Scalar(255,0,0), 2, CV_AA);
			}
			line(dst, hull[hullcount-1], hull[0], Scalar(255,0,0), 2, CV_AA);
		}
		
		imshow(WIN_RESULT, dst);
		dst.release();
		// End

		c = cvWaitKey(delay);
		if (c == 27) break;
	}	
	return 0;
}

源代码下载地址如下:http://download.csdn.net/detail/qq5132834/8358691 

运行效果如下图所示:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值