多指尖检测的简单方法有哪些_指尖血糖测试方法「建议收藏」

多指尖检测的简单方法有哪些_指尖血糖测试方法「建议收藏」新开的CSDN博客

新开的CSDN 博客。准备开始写点东西


初学CV,翻很多文献。找了很多指尖检测的实例。不懂数学的我其实遇到了很多困难。


主要是从候选点获取指尖的算法上面。鲁棒性好像都不是很好。


关于指尖检测

主要下面两种

1.用Opencv 自带的凸包检测


主要步骤下


1.阈值操作 (一般用 前景检测 或者 肤色检测)


2.寻找轮廓

3.寻找凸包 

4.选出指尖

凸包结构的点


1.Start

2.Depth_point

3.End 


多指尖检测的简单方法有哪些_指尖血糖测试方法「建议收藏」

约束的条件

1.Depth 的角度 < 90 度

2.当前组 Start 点 与上一组 End 点的距离 < 20 (第一组 与 最后一组比较 )


则当前组的start点可以认为是指尖

检测效果如下

多指尖检测的简单方法有哪些_指尖血糖测试方法「建议收藏」

2.计算重心到轮廓边缘的距离

主要步骤(16年更新:我之前高中没有学过计算几何方面的内容。之前的代码完全靠想象)


1.阈值操作 (一般用 前景检测 或者 肤色检测)

2.寻找轮廓

3.寻找重心

计算一阶矩


4.列举重心到边缘的距离

5.选出指尖点


网上随便找了一张手的图

多指尖检测的简单方法有哪些_指尖血糖测试方法「建议收藏」


多指尖检测的简单方法有哪些_指尖血糖测试方法「建议收藏」



做完阈值操作后

寻找轮廓

计算重心的坐标

然后获取重心到轮廓距离。

下面这张图

横坐标是点的顺序

纵坐标是重心到轮廓边缘的距离

多指尖检测的简单方法有哪些_指尖血糖测试方法「建议收藏」

多指尖检测的简单方法有哪些_指尖血糖测试方法「建议收藏」

可以看出图中有 5 个峰值点。

这五个峰值点表示对应的就是 五个手指的位置。

检测效果图如下 

多指尖检测的简单方法有哪些_指尖血糖测试方法「建议收藏」多指尖检测的简单方法有哪些_指尖血糖测试方法「建议收藏」

换一张

多指尖检测的简单方法有哪些_指尖血糖测试方法「建议收藏」

检测结果还是比较精确的 。大拇指的点可能不满足条件未检测到。

如果用最小二乘拟合峰值附近的点几个点 可以获取亚像素精度的指尖点。

void gethandpoint(Mat frame){
	Mat show_img;
	frame.copyTo(show_img);
	Mat derivative_img=cvCreateMat(300,900,show_img.type());
	derivative_img.setTo(255);


GaussianBlur(frame, frame, Size(3, 3), 0);
threshold(frame,frame,240,255,THRESH_BINARY_INV);
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
findContours(frame, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);
//获取轮廓
int index;
double area, maxArea(0);
for (int i=0; i < contours.size(); i++)
{
	area = contourArea(Mat(contours[i]));
	if (area > maxArea)
	{
		maxArea = area;
		index = i;
	}			
}

//drawContours(frame, contours, index, Scalar(0, 0, 255), 2, 8, hierarchy );

Moments moment = moments(frame, true);
Point center(moment.m10/moment.m00, moment.m01/moment.m00);
//获取重心
//circle(show_img, center, 8 ,Scalar(0, 0, 255), CV_FILLED);

vector<Point> couPoint = contours[index];
float current(0), depth(50000),mosthigher(0);

//count Num
int q(0),m(0),k(0),j(0),notice(0),spos(0);

Point fingerTips_single;
Point p, n, r;


for(int i=1;i < couPoint.size();i++){



	float pn = sqrt(float((couPoint[i].x - center.x) * (couPoint[i].x - center.x) + (couPoint[i].y - center.y) * (couPoint[i].y - center.y)) ); //计算重心到轮廓边缘的距离

	
	line(derivative_img,cvPoint(i,300),cvPoint(i,300-pn/3),Scalar(0,0,0,0));

		//line(show_img,couPoint[i],center,Scalar(0,0,0,0));

   //cout<<int(pn)<<endl;
 if (pn>=current)
   {
	   current=pn;//找出第一次的峰值
	   

   }
   else
   {
	   m++;
	   if(m ==1 ){
		   	 notice=i;
		   fingerTips_single=couPoint[i];

			      depth=500000;
	   }


	   if (depth>=pn)
	   {
depth=pn;
k++;
//从峰值向下开始爬。

	   }
	   else
	   {  
		 
			
		   if(k>20)
	   {
//如果爬的步长 > 20  则认为是指尖的候选点。
		  // spos=notice;
		   if(notice<10)
		   {
			   notice= 10;

		   }
//更进一步的获取精确的指尖位置	枚举候选点周围的 10 个点 选出距离重心最大的点
	
	 for (int k = notice-10;k<notice+10;k++)
	 {
		 current = sqrt(float((couPoint[k].x - center.x) * (couPoint[k].x - center.x) + (couPoint[k].y - center.y) * (couPoint[k].y - center.y)) );
		 if(current>mosthigher){
		 mosthigher = current;
		 spos = k ;

		 }

		    
	 }
	 mosthigher=0;
	fingerTips_single =couPoint[spos];
//获得的指尖
	cout<<"["<<fingerTips_single.x<<","<<fingerTips_single.y<<"]"<<endl;

		   circle(show_img,couPoint[spos],3,Scalar(0,0,0,0),5,CV_AA);

	

			 	
	   }
		 
		    
		   current=0 ;

		   m=0;
		   k=0;
		   k=0;
		 

	   }

   }

   
  //waitKey(0);
   	 
}
imshow("hand",show_img);
imshow("derivative_img",derivative_img);
}

 20130611

今天的文章多指尖检测的简单方法有哪些_指尖血糖测试方法「建议收藏」分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/87366.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注