atexit()函数在程序退出时经常需要做一些诸如释放资源的操作,但程序退出的方式有很多种。因此需要一种与程序退出方式无关的方法来进行程序退出时的必要处理。atexit()函数用来注册程序正常终止时要被调用的函数。 atexit()函数的参数是一个函数指针,函数指针指向一个没有参数也没有返回值的函数。其原型如下所示: atexit(void(*)(void)); 在一个程序中做多可以用atexit()函数注册32个处理函数,这些处理函数的调用顺序与其注册顺序相反,即最先注册的最后调用,最后注册的最先调用。 如下所示: #include <STDIO.H> void fn1() void fn2() int main() atexit(fn1); return 0; 结果输出: calling main ***** calling fn2***** calling fn1*****
posted @ 2012-07-24 22:27 xingma0910 阅读(34) 评论(0) 编辑 变量之间交换数据(不用第三变量)编程之中却有诸多美妙之处。 #include <STDIO.H> int main() int a,b; printf("before exchange:"); a=a+b; printf("after the 1st:"); a=a^b; printf("after the 2nd:"); return 0; posted @ 2012-07-24 21:37 xingma0910 阅读(12) 评论(0) 编辑 图像处理和图像识别中常用的OpenCV函数 (转)1、cvLoadImage:将图像文件加载至内存; 2、cvNamedWindow:在屏幕上创建一个窗口; 3、cvShowImage:在一个已创建好的窗口中显示图像; 4、cvWaitKey:使程序暂停,等待用户触发一个按键操作; 5、cvReleaseImage:释放图像文件所分配的内存; 6、cvDestroyWindow:销毁显示图像文件的窗口; 7、cvCreateFileCapture:通过参数设置确定要读入的AVI文件; 8、cvQueryFrame:用来将下一帧视频文件载入内存; 9、cvReleaseCapture:释放CvCapture结构开辟的内存空间; 10、cvCreateTrackbar:创建一个滚动条; 11、cvSetCaptureProperty:设置CvCapture对象的各种属性; 12、cvGetCaptureProperty:查询CvCapture对象的各种属性; 13、cvGetSize:当前图像结构的大小; 14、cvSmooth:对图像进行平滑处理; 15、cvPyrDown:图像金字塔,降采样,图像缩小为原来四分之一; 16、cvCanny:Canny边缘检测; 17、cvCreateCameraCapture:从摄像设备中读入数据; 18、cvCreateVideoWriter:创建一个写入设备以便逐帧将视频流写入视频文件; 19、cvWriteFrame:逐帧将视频流写入文件; 20、cvReleaseVideoWriter:释放CvVideoWriter结构开辟的内存空间; 21、CV_MAT_ELEM:从矩阵中得到一个元素; 22、cvAbs:计算数组中所有元素的绝对值; 23、cvAbsDiff:计算两个数组差值的绝对值; 24、cvAbsDiffS:计算数组和标量差值的绝对值; 25、cvAdd:两个数组的元素级的加运算; 26、cvAddS:一个数组和一个标量的元素级的相加运算; 27、cvAddWeighted:两个数组的元素级的加权相加运算(alpha运算); 28、cvAvg:计算数组中所有元素的平均值; 29、cvAvgSdv:计算数组中所有元素的绝对值和标准差; 30、cvCalcCovarMatrix:计算一组n维空间向量的协方差; 31、cvCmp:对两个数组中的所有元素运用设置的比较操作; 32、cvCmpS:对数组和标量运用设置的比较操作; 33、cvConvertScale:用可选的缩放值转换数组元素类型; 34、cvCopy:把数组中的值复制到另一个数组中; 35、cvCountNonZero:计算数组中非0值的个数; 36、cvCrossProduct:计算两个三维向量的向量积(叉积); 37、cvCvtColor:将数组的通道从一个颜色空间转换另外一个颜色空间; 38、cvDet:计算方阵的行列式; 39、cvDiv:用另外一个数组对一个数组进行元素级的除法运算; 40、cvDotProduct:计算两个向量的点积; 41、cvEigenVV:计算方阵的特征值和特征向量; 42、cvFlip:围绕选定轴翻转; 43、cvGEMM:矩阵乘法; 44、cvGetCol:从一个数组的列中复制元素; 45、cvGetCols:从数据的相邻的多列中复制元素; 46、cvGetDiag:复制数组中对角线上的所有元素; 47、cvGetDims:返回数组的维数; 48、cvGetDimSize:返回一个数组的所有维的大小; 49、cvGetRow:从一个数组的行中复制元素值; 50、cvGetRows:从一个数组的多个相邻的行中复制元素值; 51、cvGetSize:得到二维的数组的尺寸,以CvSize返回; 52、cvGetSubRect:从一个数组的子区域复制元素值; 53、cvInRange:检查一个数组的元素是否在另外两个数组中的值的范围内; 54、cvInRangeS:检查一个数组的元素的值是否在另外两个标量的范围内; 55、cvInvert:求矩阵的逆; 56、cvMahalonobis:计算两个向量间的马氏距离; 57、cvMax:在两个数组中进行元素级的取最大值操作; 58、cvMaxS:在一个数组和一个标量中进行元素级的取最大值操作; 59、cvMerge:把几个单通道图像合并为一个多通道图像; 60、cvMin:在两个数组中进行元素级的取最小值操作; 61、cvMinS:在一个数组和一个标量中进行元素级的取最小值操作; 62、cvMinMaxLoc:寻找数组中的最大最小值; 63、cvMul:计算两个数组的元素级的乘积(点乘); 64、cvNot:按位对数组中的每一个元素求反; 65、cvNormalize:将数组中元素进行归一化; 66、cvOr:对两个数组进行按位或操作; 67、cvOrs:在数组与标量之间进行按位或操作; 68、cvReduce:通过给定的操作符将二维数组简为向量; 69、cvRepeat:以平铺的方式进行数组复制; 70、cvSet:用给定值初始化数组; 71、cvSetZero:将数组中所有元素初始化为0; 72、cvSetIdentity:将数组中对角线上的元素设为1,其他置0; 73、cvSolve:求出线性方程组的解; 74、cvSplit:将多通道数组分割成多个单通道数组; 75、cvSub:两个数组元素级的相减; 76、cvSubS:元素级的从数组中减去标量; 77、cvSubRS:元素级的从标量中减去数组; 78、cvSum:对数组中的所有元素求和; 79、cvSVD:二维矩阵的奇异值分解; 80、cvSVBkSb:奇异值回代计算; 81、cvTrace:计算矩阵迹; 82、cvTranspose:矩阵的转置运算; 83、cvXor:对两个数组进行按位异或操作; 84、cvXorS:在数组和标量之间进行按位异或操作; 85、cvZero:将所有数组中的元素置为0; 86、cvConvertScaleAbs:计算可选的缩放值的绝对值之后再转换数组元素的类型; 87、cvNorm:计算数组的绝对范数, 绝对差分范数或者相对差分范数; 88、cvAnd:对两个数组进行按位与操作; 89、cvAndS:在数组和标量之间进行按位与操作; 90、cvScale:是cvConvertScale的一个宏,可以用来重新调整数组的内容,并且可以将参数从一种数据类型转换为另一种; 91、cvT:是函数cvTranspose的缩写; 92、cvLine:画直线; 93、cvRectangle:画矩形; 94、cvCircle:画圆; 95、cvEllipse:画椭圆; 96、cvEllipseBox:使用外接矩形描述椭圆; 97、cvFillPoly、cvFillConvexPoly、cvPolyLine:画多边形; 98、cvPutText:在图像上输出一些文本; 99、cvInitFont:采用一组参数配置一些用于屏幕输出的基本个特定字体; 100、cvSave:矩阵保存; 101、cvLoad:矩阵读取; 102、cvOpenFileStorage:为读/写打开存储文件; 103、cvReleaseFileStorage:释放存储的数据; 104、cvStartWriteStruct:开始写入新的数据结构; 105、cvEndWriteStruct:结束写入数据结构; 106、cvWriteInt:写入整数型; 107、cvWriteReal:写入浮点型; 108、cvWriteString:写入字符型; 109、cvWriteComment:写一个XML或YAML的注释字串; 110、cvWrite:写一个对象; 111、cvWriteRawData:写入多个数值; 112、cvWriteFileNode:将文件节点写入另一个文件存储器; 113、cvGetRootFileNode:获取存储器最顶层的节点; 114、cvGetFileNodeByName:在映图或存储器中找到相应节点; 115、cvGetHashedKey:为名称返回一个惟一的指针; 116、cvGetFileNode:在映图或文件存储器中找到节点; 117、cvGetFileNodeName:返回文件的节点名; 118、cvReadInt:读取一个无名称的整数型; 119、cvReadIntByName:读取一个有名称的整数型; 120、cvReadReal:读取一个无名称的浮点型; 121、cvReadRealByName:读取一个有名称的浮点型; 122、cvReadString:从文件节点中寻找字符串; 123、cvReadStringByName:找到一个有名称的文件节点并返回它; 124、cvRead:将对象解码并返回它的指针; 125、cvReadByName:找到对象并解码; 126、cvReadRawData:读取多个数值; 127、cvStartReadRawData:初始化文件节点序列的读取; 128、cvReadRawDataSlice:读取文件节点的内容; 129、cvGetModuleInfo:检查IPP库是否已经正常安装并且检验运行是否正常; 130、cvResizeWindow:用来调整窗口的大小; 131、cvSaveImage:保存图像; 132、cvMoveWindow:将窗口移动到其左上角为x,y的位置; 133、cvDestroyAllWindow:用来关闭所有窗口并释放窗口相关的内存空间; 134、cvGetTrackbarPos:读取滑动条的值; 135、cvSetTrackbarPos:设置滑动条的值; 136、cvGrabFrame:用于快速将视频帧读入内存; 137、cvRetrieveFrame:对读入帧做所有必须的处理; 138、cvConvertImage:用于在常用的不同图像格式之间转换; 139、cvErode:形态腐蚀; 140、cvDilate:形态学膨胀; 141、cvMorphologyEx:更通用的形态学函数; 142、cvFloodFill:漫水填充算法,用来进一步控制哪些区域将被填充颜色; 143、cvResize:放大或缩小图像; 144、cvPyrUp:图像金字塔,将现有的图像在每个维度上都放大两倍; 145、cvPyrSegmentation:利用金字塔实现图像分割; 146、cvThreshold:图像阈值化; 147、cvAcc:可以将8位整数类型图像累加为浮点图像; 148、cvAdaptiveThreshold:图像自适应阈值; 149、cvFilter2D:图像卷积; 150、cvCopyMakeBorder:将特定的图像轻微变大,然后以各种方式自动填充图像边界; 151、cvSobel:图像边缘检测,Sobel算子; 152、cvLaplace:拉普拉斯变换、图像边缘检测; 153、cvHoughLines2:霍夫直线变换; 154、cvHoughCircles:霍夫圆变换; 155、cvRemap:图像重映射,校正标定图像,图像插值; 156、cvWarpAffine:稠密仿射变换; 157、cvGetQuadrangleSubPix:仿射变换; 158、cvGetAffineTransform:仿射映射矩阵的计算; 159、cvCloneImage:将整个IplImage结构复制到新的IplImage中; 160、cv2DRotationMatrix:仿射映射矩阵的计算; 161、cvTransform:稀疏仿射变换; 162、cvWarpPerspective:密集透视变换(单应性); 163、cvGetPerspectiveTransform:计算透视映射矩阵; 164、cvPerspectiveTransform:稀疏透视变换; 165、cvCartToPolar:将数值从笛卡尔空间到极坐标(极性空间)进行映射; 166、cvPolarToCart:将数值从极性空间到笛卡尔空间进行映射; 167、cvLogPolar:对数极坐标变换; 168、cvDFT:离散傅里叶变换; 169、cvMulSpectrums:频谱乘法; 170、cvDCT:离散余弦变换; 171、cvIntegral:计算积分图像; 172、cvDistTransform:图像的距离变换; 173、cvEqualizeHist:直方图均衡化; 174、cvCreateHist:创建一新直方图; 175、cvMakeHistHeaderForArray:根据已给出的数据创建直方图; 176、cvNormalizeHist:归一化直方图; 177、cvThreshHist:直方图阈值函数; 178、cvCalcHist:从图像中自动计算直方图; 179、cvCompareHist:用于对比两个直方图的相似度; 180、cvCalcEMD2:陆地移动距离(EMD)算法; 181、cvCalcBackProject:反向投影; 182、cvCalcBackProjectPatch:图块的方向投影; 183、cvMatchTemplate:模板匹配; 184、cvCreateMemStorage:用于创建一个内存存储器; 185、cvCreateSeq:创建序列; 186、cvSeqInvert:将序列进行逆序操作; 187、cvCvtSeqToArray:复制序列的全部或部分到一个连续内存数组中; 188、cvFindContours:从二值图像中寻找轮廓; 189、cvDrawContours:绘制轮廓; 190、cvApproxPoly:使用多边形逼近一个轮廓; 191、cvContourPerimeter:轮廓长度; 192、cvContoursMoments:计算轮廓矩; 193、cvMoments:计算Hu不变矩; 194、cvMatchShapes:使用矩进行匹配; 195、cvInitLineIterator:对任意直线上的像素进行采样; 196、cvSampleLine:对直线采样; 197、cvAbsDiff:帧差; 198、cvWatershed:分水岭算法; 199、cvInpaint:修补图像; 200、cvGoodFeaturesToTrack:寻找角点; 201、cvFindCornerSubPix:用于发现亚像素精度的角点位置; 202、cvCalcOpticalFlowLK:实现非金字塔的Lucas-Kanade稠密光流算法; 203、cvMeanShift:mean-shift跟踪算法; 204、cvCamShift:camshift跟踪算法; 205、cvCreateKalman:创建Kalman滤波器; 206、cvCreateConDensation:创建condensation滤波器; 207、cvConvertPointsHomogenious:对齐次坐标进行转换; 208、cvFindChessboardCorners:定位棋盘角点; 209、cvFindHomography:计算单应性矩阵; 210、cvRodrigues2:罗德里格斯变换; 211、cvFitLine:直线拟合算法; 212、cvCalcCovarMatrix:计算协方差矩阵; 213、cvInvert:计算协方差矩阵的逆矩阵; 214、cvMahalanobis:计算Mahalanobis距离; 215、cvKMeans2:K均值; 216、cvCloneMat:根据一个已有的矩阵创建一个新矩阵; 217、cvPreCornerDetect:计算用于角点检测的特征图; 218、cvGetImage:CvMat图像数据格式转换成IplImage图像数据格式; 219、cvMatMul:两矩阵相乘; 220、cvRound:返回和参数最接近的整数值; 221、cvFloor:返回不大于参数的最大整数值; 222、cvCeil:返回不小于参数的最小整数值; 223、cvCreateImage:创建图像; 224、cvSetMouseCallback:用鼠标获取确定窗口上的矩形; 225、cvContourArea:计算整个或部分轮廓的面积; 226、cvArcLength:计算轮廓周长或曲线长度; 227、cvBoundingRect:计算点集的最外面矩形边界(获取轮廓的外接矩形); 228、cvSeqRemove:删除序列中指定位置的元素(轮廓); 229、cvRNG:随机生成一个64位随机数; 230、cvGetTickCount:返回64位长整数的时间数据; 231、cvGetTickFrequency:返回系统时钟频率; 232、cvRandInt:返回均匀分布32位的随机数; 233、cvRandReal: 返回均匀分布0~1之间的随机小数; 234、cvInitMatHeader:初始化矩阵头,不分配存储空间; 235、cvTermCriteria:迭代算法终止准则; 236、CvSVMParams:SVM训练参数,该结构需要初始化,并传递给CvSVM训练函数; 237、CvSVM::train:训练SVM; 238、CvSVM::predict:预测一个新样本的响应值,在分类问题中,这个函数返回类别编号,在回归问题中,返回函数值; 239、cvSet2D:修改指定的数组; 240、CvSVM::get_support_vector_count:获得支持向量的个数; 241、CvSVM::get_support_vector:获得对应索引编号的支持向量; 242、CvSVM::save:将SVM训练完的数据保存到指定的文件中(save来源于cvStatModel为ML库的通用类); 243、CvSVM::load:将指定的文件装载到SVM指定的对象中; 244、cvCreateBGCodeBookModel:codebook方法中,初始化; 245、cvBGCodeBookUpdate:codebook方法中,更新背景模型; 246、cvBGCodeBookClearStale:codebook方法中,清除消极的codebook; 247、cvBGCodeBookDiff:codebook方法中,背景减除; 248、cvReleaseBGCodeBookModel:codebook方法中,释放资源; posted @ 2012-07-24 16:44 xingma0910 阅读(540) 评论(0) 编辑 图像处理的基本知识(转)调色板 图像的颜色处理 将真彩色图像转换为256色位图 2010.03.27 灰度变换法: 直方图均值法: 种植滤波法: 图像的锐化 低通滤波法: 高通滤波法: 图像的边缘检测: 微分算子边缘检测: 哈夫变换 方向算子: 梯度方向算子: Krisch边缘检测算子: 拉普拉斯算子: 综合正交算子: 边界闭合: posted @ 2012-07-24 16:14 xingma0910 阅读(563) 评论(0) 编辑 cvRectangle 用法Rectangle 绘制简单、指定粗细或者带填充的 矩形 void cvRectangle( CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color, int thickness=1, int line_type=8, int shift=0 ); img 图像. pt1 矩形的一个顶点。 pt2 矩形对角线上的另一个顶点 color 线条颜色 (RGB) 或亮度(灰度图像 )(grayscale image)。 thickness 组成矩形的线条的粗细程度。取负值时(如 CV_FILLED)函数绘制填充了色彩的矩形。 line_type 线条的类型。见cvLine的描述 shift 坐标点的小数点位数。 函数 cvRectangle 通过对角线上的两个顶点绘制矩形。 如: cvRectangle( ResImage, cvPoint(x1,y1), cvPoint(x2,y2), CV_RGB(255,250,250), 2, 8, 0 ); 其中(x1,y1)是坐标为x1,y1的点。这里要注意,x1对应Width,y1代表Height.具体应用的时候不要搞反了。 posted @ 2012-07-24 15:18 xingma0910 阅读(85) 评论(0) 编辑 手势识别方法综述(hand detect) 肤色(转)看了一天的论文,总结出手势识别的三种方法:1、通过肤色识别
2、通过haar-like基
3、通过HandUv
说下各个优缺点
1、通过肤色识别
设定人的肤色的范围,监测在这个范围内的 肤色InRange,然后画出给定的区域。
例子:
#include "cv.h" #include "cxcore.h" #include "highgui.h" #include "math.h" #include <iostream> #include <stdio.h> #include <string.h> #include <conio.h> #include <sstream> #include <time.h> using namespace std; int main()
{ int c = 0; CvSeq* a = 0; CvCapture* capture = cvCaptureFromCAM(0);//从对摄像头的初始化捕获 if(!cvQueryFrame(capture)) cout<<"Video capture failed, please check the camera."<<endl; else cout<<"Video camera capture status: OK"<<endl; CvSize sz = cvGetSize(cvQueryFrame( capture));//得到摄像头图像大小 IplImage* src = cvCreateImage( sz, 8, 3 );//3通道,每个通道8位 IplImage* hsv_image = cvCreateImage( sz, 8, 3);// IplImage* hsv_mask = cvCreateImage( sz, 8, 1); IplImage* hsv_mask2 = cvCreateImage( sz, 8, 1); IplImage* hsv_edge = cvCreateImage( sz, 8, 1); CvScalar hsv_min = cvScalar(0, 30, 80, 0);//最小像素的RGB值
CvScalar hsv_max = cvScalar(20, 150, 255, 0);//最大像素的RGB值 //CvScalar hsv_min = cvScalar(30, 30, 30, 0);//最小像素的RGB值 //CvScalar hsv_max = cvScalar(200, 200, 200, 0);//最大像素的RGB值 // CvMemStorage* storage = cvCreateMemStorage(0);//分配大小为0的内存空间 CvMemStorage* areastorage = cvCreateMemStorage(0); CvMemStorage* minStorage = cvCreateMemStorage(0); CvMemStorage* dftStorage = cvCreateMemStorage(0); CvSeq* contours = NULL; // cvNamedWindow( "src",1); //在屏幕上创建一个窗口,第一个参数为窗口标题,第二个参数为窗口属性, //设置为0(默认值),或者CV_WINDOW_AUTOSIZE,设置为0,则窗口不会因图像的大小而改变 //图像只能在窗口中根据窗口的大小进行拉伸或缩放;设置为CV_WINDOW_AUTOSIZE时,窗口会根据图像 //的实际大小进行自动拉伸或缩放。 //cvNamedWindow( "hsv-msk",1); //cvNamedWindow( "contour",1); ////// IplImage * background=cvLoadImage("c:\\002.jpg");
if (background==0) { cout<<"open background error"<<endl; } else cout<<"open background ok!"<<endl; CvRect rect=cvRect(0,0,background->width,background->height); cvSetImageROI(background,rect); IplImage * src3=cvCreateImage(cvGetSize(background),background->depth,background->nChannels); while( c != 27)//27为ASCII键值(ESC),
{ IplImage* bg = cvCreateImage( sz, 8, 3);// cvRectangle( bg, cvPoint(0,0), cvPoint(bg->width,bg->height), CV_RGB( 255, 255, 255), -1, 8, 0 );//画矩形,参数:Image,两个顶点坐标,线的颜色,线的厚度 bg->origin = 1; for(int b = 0; b< int(bg->width/10); b++)//画网格 { cvLine( bg, cvPoint(b*20, 0), cvPoint(b*20, bg->height), CV_RGB( 200, 200, 200), 1, 8, 0 );//画竖线 cvLine( bg, cvPoint(0, b*20), cvPoint(bg->width, b*20), CV_RGB( 200, 200, 200), 1, 8, 0 );//画横线 } src = cvQueryFrame( capture);//得到一帧图像
cvSaveImage("c:\\src.bmp",src);
cvCvtColor(src, hsv_image, CV_BGR2HSV);//色彩空间转换,HSV cvSaveImage("c:\\hsv.bmp",hsv_image);
cvInRangeS (hsv_image, hsv_min, hsv_max, hsv_mask);//检查数组元素是否在两个数量之间,输出新图像hsv_mask,从3通道到1通道 //hsv_mask的数据要么为0,要么为1,在min和max范围内为1,得到ROI区域,找到在像素RGB范围内的数据 //cvSmooth( hsv_mask, hsv_mask, CV_MEDIAN, 27, 0, 0, 0 ); cvSaveImage("c:\\mask.bmp",hsv_mask); //cvSmooth( hsv_mask, hsv_mask2, CV_MEDIAN, 27, 0, 0);//图像平滑,
cvSmooth( hsv_mask, hsv_mask2, CV_MEDIAN, 3, 0, 0, 0 ); //CV_MEDIAN (median blur) - 对图像进行核大小为param1×param1 的中值滤波 (i.e. 邻域是方的).
cvCanny(hsv_mask2, hsv_edge, 1, 3, 5); //cvCanny(hsv_mask, hsv_edge, 1, 3, 5);//采用 Canny 算法做边缘检测 cvFindContours( hsv_mask, storage, &contours, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0) );
//对单通道图像检索轮廓,返回第一个轮廓的指针 CvSeq* contours2 = NULL; double result = 0, result2 = 0; while(contours)//得到最大的两个感兴趣区 { result = fabs( cvContourArea( contours, CV_WHOLE_SEQ ) );//计算感兴趣区域的像素点数 if ( result > result2) {result2 = result; contours2 = contours;}; contours = contours->h_next; } if ( contours2 )//最大的感兴趣区,ROI { //cout << "contours2: " << contours2->total << endl; CvRect rect = cvBoundingRect( contours2, 0 );//返回一个2d矩形的点集合 cvRectangle( bg, cvPoint(rect.x, rect.y + rect.height), cvPoint(rect.x + rect.width, rect.y), CV_RGB(200, 0, 200), 1, 8, 0 ); //在bg的矩形区域中画rect的图形 //cout << "Ratio: " << rect.width << ", " << rect.height << ", " << (float)rect.width / rect.height << endl; int checkcxt = cvCheckContourConvexity( contours2 );//检测输入的轮廓是否是凸的 //cout << checkcxt <<endl; CvSeq* hull = cvConvexHull2( contours2, 0, CV_CLOCKWISE, 0 );//二维凸包 CvSeq* defect = cvConvexityDefects( contours2, hull, dftStorage );//凸包中的缺陷 if( defect->total >=40 ) {cout << " Closed Palm " << endl;} else if( defect->total >=30 && defect->total <40 ) {cout << " Open Palm " << endl;} else{ cout << " Fist " << endl;} cout << "defet: " << defect->total << endl; CvBox2D box = cvMinAreaRect2( contours2, minStorage );//包围所有点的轮廓的最小矩形
//cout << "box angle: " << (int)box.angle << endl; cvCircle( bg, cvPoint(box.center.x, box.center.y), 3, CV_RGB(200, 0, 200), 2, 8, 0 );//画圆 cvEllipse( bg, cvPoint(box.center.x, box.center.y), cvSize(box.size.height/2, box.size.width/2), box.angle, 0, 360, CV_RGB(220, 0, 220), 1, 8, 0 );//椭圆 //cout << "Ratio: " << (float)box.size.width/box.size.height <<endl; } //cvShowImage( "hsv-msk", hsv_mask); hsv_mask->origin = 1; //IplImage* contour = cvCreateImage( sz, 8, 3 ); cvDrawContours( bg, contours2, CV_RGB( 0, 200, 0), CV_RGB( 0, 100, 0), 1, 1, 8, cvPoint(0,0));//绘制轮廓的图像到bg图像中
cvShowImage( "src", src);
//cvShowImage("src",src3); //contour->origin = 1; cvShowImage( "contour", contour); //cvReleaseImage( &contour); cvNamedWindow("bg",0);
cvShowImage("bg",bg); cvNamedWindow( "ROI",0); cvShowImage("ROI",hsv_mask2); //cvShowImage("ROI",hsv_mask2); cvReleaseImage( &bg); c = cvWaitKey( 100);
} ////// cvReleaseCapture( &capture); cvDestroyAllWindows(); }
缺陷在于不能区分脸的颜色和手的颜色,而且识别出来的是全部在这个范围内的东西,难以满足要求。 比较有特点的是http://vinjn.spaces./
他提供的是“虚拟鼓”比较有特色,是
原理
1.原始视频->人脸识别
2.根据人脸的颜色分布,找到手 3.去除手和脸以外的区域 3.1 对手和脸进行连通区域划分 3.2 对双手进行运动分析,满足条件则击鼓 他的方法从部分上克服了上述缺陷,但是从他提供的视频可以看出来他穿的一个长袖的衣服,而且衣服颜色和肤色差距很大,如果是短袖的衣服效果估计不会怎么样了。 posted @ 2012-07-24 11:29 xingma0910 阅读(256) 评论(0) 编辑 |
|