最近在做的工作是在一张红外图像中提取人脸区域,由于该区域是不规则的,所以一时找不到头绪。初步思路是:先将其转换成灰度图,对其使用形态学操作,接着使用Canny提取边缘,最后使用FindContours寻找轮廓。问题是寻找到轮廓后如何将其提取出来,暂时真正探索,神啊,Help me......
以下是在网上找到的一篇提取不规则图像的代码,参考一下: /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 程序要求:请自备同大小同的图片两张,一张为原图srcImg,为三通道图片,另一张为mask图,为单通道图片。 下面是Opencv官方手册的对cvCopy的说明: Copy 用cvCopy的mask进行对不规制的提取程序截图: 以下是代码: #include "stdafx.h" int _tmain(int argc, _TCHAR* argv[]) cvCopy(pImg,dstImg,mask); ////////////////////////////////////另一个例子/////////////////////////////////////////////////////////// opencv例子里没有提供cvsnakeimage的使用方法,在此整理一个例子,可以形象的看看snake算法的结果,大致做法是: 首先设定域值分割,把基本的轮廓找出来,见图中蓝色轮廓线,再将轮廓点传入cvSnakeImage函数,计算出绿色的snake轮廓线。 其中参数alpha代表点相互靠拢的权值(0-1.0),beta表示弯曲能量(越小越容易弯曲)(0-1.0),gamma表示整体能量(0-1.0)。其中参数我自己也不确定具体的范围,最好自己更改不同的范围试试. // TrainingTools.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <iostream> #include <string.h> #include <cxcore.h> #include <cv.h> #include <highgui.h> #include <fstream> IplImage *image = 0 ; //原始图像 IplImage *image2 = 0 ; //原始图像copy using namespace std; int Thresholdness = 141; int ialpha = 20; int ibeta=20; int igamma=20; void onChange(int pos) { if(image2) cvReleaseImage(&image2); if(image) cvReleaseImage(&image); image2 = cvLoadImage("grey.bmp",1); //显示图片 image= cvLoadImage("grey.bmp",0); cvThreshold(image,image,Thresholdness,255,CV_THRESH_BINARY); //分割域值 CvMemStorage* storage = cvCreateMemStorage(0); CvSeq* contours = 0; cvFindContours( image, storage, &contours, sizeof(CvContour), //寻找初始化轮廓 CV_RETR_EXTERNAL , CV_CHAIN_APPROX_SIMPLE ); if(!contours) return ; int length = contours->total; if(length<10) return ; CvPoint* point = new CvPoint[length]; //分配轮廓点 CvSeqReader reader; CvPoint pt= cvPoint(0,0);; CvSeq *contour2=contours; cvStartReadSeq(contour2, &reader); for (int i = 0; i < length; i++) { CV_READ_SEQ_ELEM(pt, reader); point[i]=pt; } cvReleaseMemStorage(&storage); //显示轮廓曲线 for(int i=0;i<length;i++) { int j = (i+1)%length; cvLine( image2, point[i],point[j],CV_RGB( 0, 0, 255 ),1,8,0 ); } float alpha=ialpha/100.0f; float beta=ibeta/100.0f; float gamma=igamma/100.0f; CvSize size; size.width=3; size.height=3; CvTermCriteria criteria; criteria.type=CV_TERMCRIT_ITER; criteria.max_iter=1000; criteria.epsilon=0.1; cvSnakeImage( image, point,length,&alpha,&beta,&gamma,CV_VALUE,size,criteria,0 ); //显示曲线 for(int i=0;i<length;i++) { int j = (i+1)%length; cvLine( image2, point[i],point[j],CV_RGB( 0, 255, 0 ),1,8,0 ); } delete []point; } int main(int argc, char* argv[]) { cvNamedWindow("win1",0); cvCreateTrackbar("Thd", "win1", &Thresholdness, 255, onChange); cvCreateTrackbar("alpha", "win1", &ialpha, 100, onChange); cvCreateTrackbar("beta", "win1", &ibeta, 100, onChange); cvCreateTrackbar("gamma", "win1", &igamma, 100, onChange); cvResizeWindow("win1",300,500); onChange(0); for(;;) { if(cvWaitKey(40)==27) break; cvShowImage("win1",image2); } return 0; } |
|