【矩阵算法】distance transform用以提取手掌中心区域
来源:互联网 发布:手机扫码软件 编辑:程序博客网 时间:2024/05/17 07:39
这几天在做一个手势识别的项目,其中最的关键一步是提取手掌中心。
获得手掌重心通常的做法是计算整个手部的重心,并以该重心位置近似手掌重心,这种方法只适用于没有手指伸出或只有一个手指伸出的情况,否则获得的手掌重心位置将严重偏离真实位置。
距离变换的基本含义是计算一个图像中非零像素点到最近的零像素点的距离,也就是到零像素点的最短距离。因此可以基于距离变换提取手掌重心。
算法基本思想:
(1)将手掌图像二值化,手掌内的区域设为白色,外部区域设为黑色。
(2)将二值化后的图像经过distanceTransform变换,得到dist_image,其中每个像素点的值是该像素点到其最近的零像素点的距离。
(3)找到dist_image的最大值(即圆的半径R),并记录下位置(即圆心坐标)。
代码如下:
#include "opencv2/opencv.hpp"#include <opencv2/core/core.hpp>#include <opencv2/highgui/highgui.hpp>#include <opencv2/imgproc/imgproc.hpp>#include <vector>using namespace cv; using namespace std; pair<Point,double> DetectInCircles(vector<Point> contour,Mat src){Mat dist_image;distanceTransform(src,dist_image,CV_DIST_L2,3);int temp=0,R=0,cx=0,cy=0;int d;for (int i=0;i<src.rows;i++)for (int j=0;j<src.cols;j++){/* checks if the point is inside the contour. Optionally computes the signed distance from the point to the contour boundary*/ d = pointPolygonTest(contour, Point2f(j, i), 0);if (d>0){temp=(int)dist_image.ptr<float>(i)[j];if (temp>R){R=temp;cy=i;cx=j;}}} return make_pair(Point(cx,cy),R); }int main() { // Read input binary image Mat src= imread("D:\\mycode\\6.jpg",1);Mat image;cvtColor(src,image,CV_BGR2GRAY);vector<vector<Point>> contours; //findContours的输入是二值图像 findContours(image, contours, // a vector of contours CV_RETR_EXTERNAL, // retrieve the external contours CV_CHAIN_APPROX_NONE); // retrieve all pixels of each contours // Print contours' length轮廓的个数 cout << "Contours: " << contours.size() << endl; vector<vector<Point>>::const_iterator itContours= contours.begin(); for ( ; itContours!=contours.end(); ++itContours) { cout << "Size: " << itContours->size() << endl;//每个轮廓包含的点数 } //找到最大轮廓int index=0,maxArea=0;for(unsigned int i=0;i<contours.size();i++){int area=contourArea(contours[i]);if (area>maxArea){index=i;maxArea=area;}}// draw black contours on white image Mat result(image.size(),CV_8U,Scalar(0)); drawContours(result,contours, //画出轮廓 -1, // draw all contours Scalar(255), // in black 2); // with a thickness of 2 pair<Point,double> m=DetectInCircles(contours[index],image);cout<<m.first.x<<" "<<m.first.y<<" "<<m.second<<endl;circle(src,m.first,3,Scalar(0,0,255),2);circle(src,m.first,m.second,Scalar(0,0,255),1);namedWindow("result"); imshow("result",src); waitKey(0);return 0;}
结果:
原图 dist_image 结果
其中有一点需要注意:
distanceTransform(InputArray src, OutputArray dst, int distanceType, int maskSize)Parameters:src – 8-bit, single-channel (binary) source image.dst – Output image with calculated distances. It is a 32-bit floating-point, single-channelimage of the same size as src .distanceType – Type of distance. It can be CV_DIST_L1, CV_DIST_L2 , or CV_DIST_C .maskSize – Size of the distance transform mask. It can be 3, 5, or CV_DIST_MASK_PRECISE(the latter option is only supported by the first function). In case of the CV_DIST_L1 orCV_DIST_C distance type, the parameter is forced to 3 because a 3 3 mask gives the sameresult as 5 5 or any larger aperture.labels – Optional output 2D array of labels (the discrete Voronoi diagram). It has the typeCV_32SC1 and the same size as src . See the details below.
dst为单通道的32-bit 浮点型矩阵,读取元素时需要用image.ptr<float>(i)[j],用imshow显示的时候需要用normalize(dist_image, magI, 0, 1, CV_MINMAX); 将float类型的矩阵转换到可显示图像范围 (float [0, 1]).
另外还有一个博客值得参考:http://blog.csdn.net/wuhaibing_cver/article/details/8602461
0 0
- 【矩阵算法】distance transform用以提取手掌中心区域
- 基于距离变换的手掌中心提取
- 基于distanceTransform-距离变换的手掌中心提取
- 基于distanceTransform-距离变换的手掌中心提取
- distance transform
- Distance Transform
- OpenCV提取轮廓的方法获取瞳孔区域及中心
- OpenCV手势识别-手掌特征提取
- pww区域连接特征提取算法
- 四种显著区域特征提取算法
- 区域生长算法提取鱼眼有效区域
- 区域提取
- 一种运动区域提取算法及Matlab实现
- 简单有效的连通区域提取算法实现
- 快速扫描算法提取鱼眼图像有效区域
- 快速扫描算法提取鱼眼图像有效区域
- transform算法
- transform算法
- static_cast, dynamic_cast, const_cast,reinterpret_cast探讨
- Creating Custom share buttons: Facebook, Twitter, Google+
- Java中文与ASCII码的转换
- MySql数据库使用SQL语句设置编码
- Tomcat7 Maven插件
- 【矩阵算法】distance transform用以提取手掌中心区域
- 史上最容易理解Spring的IoC和DI
- IOS数据持久化层
- C#一元二次方程
- [ffmpeg 扩展第三方库编译系列] 关于libopenjpeg mingw32编译问题
- LeetCode刷题笔录Permutation Sequence
- R语言 -- Q&A
- Bean Query 第一个版本(1.0.0)已发布
- 【基础算法】排序-复杂排序之一(归并排序)