特征提取代码总结
来自https://www.sodocs.net/doc/bf18280149.html,/source/3208155#acomment 特征提取代码总结
颜色提取
颜色直方图提取:
C ode:
#include
#include
#include
using namespace std;
int main( int argc, char** argv )
{
IplImage * src= cvLoadImage("E:\\Download\\test1.jpg",1);
IplImage* hsv = cvCreateImage( cvGetSize(src), 8, 3 );
IplImage* h_plane = cvCreateImage( cvGetSize(src), 8, 1 ); IplImage* s_plane = cvCreateImage( cvGetSize(src), 8, 1 ); IplImage* v_plane = cvCreateImage( cvGetSize(src), 8, 1 ); IplImage* planes[] = { h_plane, s_plane };
/** H 分量划分为16个等级,S分量划分为8个等级*/
int h_bins = 16, s_bins = 8;
int hist_size[] = {h_bins, s_bins};
/** H 分量的变化范围*/
float h_ranges[] = { 0, 180 };
/** S 分量的变化范围*/
float s_ranges[] = { 0, 255 };
float* ranges[] = { h_ranges, s_ranges };
/** 输入图像转换到HSV颜色空间*/
cvCvtColor( src, hsv, CV_BGR2HSV );
cvCvtPixToPlane( hsv, h_plane, s_plane, v_plane, 0 );
/** 创建直方图,二维, 每个维度上均分*/
CvHistogram * hist = cvCreateHist( 2, hist_size, CV_HIST_ARRAY, ranges, 1 ); /** 根据H,S两个平面数据统计直方图*/
cvCalcHist( planes, hist, 0, 0 );
/** 获取直方图统计的最大值,用于动态显示直方图*/
float max_value;
cvGetMinMaxHistValue( hist, 0, &max_value, 0, 0 );
/** 设置直方图显示图像*/
int height = 240;
int width = (h_bins*s_bins*6);
IplImage* hist_img = cvCreateImage( cvSize(width,height), 8, 3 );
cvZero( hist_img );
/** 用来进行HSV到RGB颜色转换的临时单位图像*/
IplImage * hsv_color = cvCreateImage(cvSize(1,1),8,3);
IplImage * rgb_color = cvCreateImage(cvSize(1,1),8,3);
int bin_w = width / (h_bins * s_bins);
for(int h = 0; h < h_bins; h++)
{
for(int s = 0; s < s_bins; s++)
{
int i = h*s_bins + s;
/** 获得直方图中的统计次数,计算显示在图像中的高度*/
float bin_val = cvQueryHistValue_2D( hist, h, s );
int intensity = cvRound(bin_val*height/max_value);
/** 获得当前直方图代表的颜色,转换成RGB用于绘制*/
cvSet2D(hsv_color,0,0,cvScalar(h*180.f / h_bins,s*255.f/s_bins,255,0)); cvCvtColor(hsv_color,rgb_color,CV_HSV2BGR);
CvScalar color = cvGet2D(rgb_color,0,0);
cvRectangle( hist_img, cvPoint(i*bin_w,height),
cvPoint((i+1)*bin_w,height - intensity),
color, -1, 8, 0 );
}
}
cvNamedWindow( "Source", 1 );
cvShowImage( "Source", src );
cvNamedWindow( "H-S Histogram", 1 );
cvShowImage( "H-S Histogram", hist_img );
cvWaitKey(0);
}
运行效果截图:
形状提取
C andy算子对边缘提取:
Code:
#include"cv.h"
#include"cxcore.h"
#include"highgui.h"
int main( int argc, char** argv )
{
//声明IplImage指针
IplImage* pImg = NULL;
IplImage* pCannyImg = NULL;
//载入图像,强制转化为Gray
pImg = cvLoadImage( "E:\\Download\\test.jpg", 0);
//为canny边缘图像申请空间
pCannyImg = cvCreateImage(cvGetSize(pImg), IPL_DEPTH_8U, 1);
//canny边缘检测
cvCanny(pImg, pCannyImg, 50, 150, 3); //创建窗口
cvNamedWindow("src", 1); cvNamedWindow("canny",1);
//显示图像
cvShowImage( "src", pImg ); cvShowImage( "canny", pCannyImg );
//等待按键
cvWaitKey(0);
//销毁窗口
cvDestroyWindow( "src" ); cvDestroyWindow( "canny" );
//释放图像
cvReleaseImage( &pImg ); cvReleaseImage( &pCannyImg );
return 0;
}
运行效果截图:
角点提取:
Code:
#include
#include"cv.h"
#include"highgui.h"
#define MAX_CORNERS 100
int main(void)
{
int cornersCount=MAX_CORNERS;//得到的角点数目
CvPoint2D32f corners[MAX_CORNERS];//输出角点集合
IplImage *srcImage = 0,*grayImage = 0,*corners1 = 0,*corners2 = 0;
int i;
CvScalar color = CV_RGB(255,0,0);
cvNamedWindow("image",1);
//Load the image to be processed
srcImage = cvLoadImage("E:\\Download\\1.jpg",1);
grayImage = cvCreateImage(cvGetSize(srcImage),IPL_DEPTH_8U,1);
//copy the source image to copy image after converting the format
//复制并转为灰度图像
cvCvtColor(srcImage,grayImage,CV_BGR2GRAY);
//create empty images os same size as the copied images
//两幅临时位浮点图像,cvGoodFeaturesToTrack会用到
corners1 = cvCreateImage(cvGetSize(srcImage),IPL_DEPTH_32F,1);
corners2 = cvCreateImage(cvGetSize(srcImage),IPL_DEPTH_32F,1);
cvGoodFeaturesToTrack(grayImage,corners1,corners2,corners,&cornersCount,0.05,
30,//角点的最小距离是
0,//整个图像
3,0,0.4);
printf("num corners found: %d\n",cornersCount);
//开始画出每个点
if (cornersCount>0)
{
for (i=0;i { cvCircle(srcImage,cvPoint((int)(corners[i].x),(int)(corners[i].y)),2,color,2,CV_AA, 0); } } cvShowImage("image",srcImage); cvSaveImage("imagedst.png",srcImage); cvReleaseImage(&srcImage); cvReleaseImage(&grayImage); cvReleaseImage(&corners1); cvReleaseImage(&corners2); cvWaitKey(0); return 0; } 运行效果截图: H ough直线提取: Code: #include #include #include int main(int argc, char** argv) { IplImage* src = cvLoadImage( "E:\\Download\\2.jpg" , 0 ); IplImage* dst; IplImage* color_dst; CvMemStorage* storage = cvCreateMemStorage(0); CvSeq* lines = 0; int i; if( !src ) return -1; dst = cvCreateImage( cvGetSize(src), 8, 1 ); color_dst = cvCreateImage( cvGetSize(src), 8, 3 ); cvCanny( src, dst, 50, 200, 3 ); cvCvtColor( dst, color_dst, CV_GRAY2BGR ); #if 0 lines = cvHoughLines2( dst, storage, CV_HOUGH_STANDARD, 1, CV_PI/180, 100, 0, 0 ); for( i = 0; i < MIN(lines->total,100); i++ ) { float* line = (float*)cvGetSeqElem(lines,i); float rho = line[0]; float theta = line[1]; CvPoint pt1, pt2; double a = cos(theta), b = sin(theta); double x0 = a*rho, y0 = b*rho; pt1.x = cvRound(x0 + 1000*(-b)); pt1.y = cvRound(y0 + 1000*(a)); pt2.x = cvRound(x0 - 1000*(-b)); pt2.y = cvRound(y0 - 1000*(a)); cvLine( color_dst, pt1, pt2, CV_RGB(255,0,0), 3, CV_AA, 0 ); } #else lines = cvHoughLines2( dst, storage, CV_HOUGH_PROBABILISTIC, 1, CV_PI/180, 50, 50, 10 ); for( i = 0; i < lines->total; i++ ) { CvPoint* line = (CvPoint*)cvGetSeqElem(lines,i); cvLine( color_dst, line[0], line[1], CV_RGB(255,0,0), 3, CV_AA, 0 ); } #endif cvNamedWindow( "Source", 1 ); cvShowImage( "Source", src ); cvNamedWindow( "Hough", 1 ); cvShowImage( "Hough", color_dst ); cvWaitKey(0); return 0; } 运行效果截图: Hough圆提取: C ode: #include #include #include #include using namespace std; int main(int argc, char** argv) { IplImage* img; img=cvLoadImage("E:\\Download\\3.jpg", 1); IplImage* gray = cvCreateImage( cvGetSize(img), 8, 1 ); CvMemStorage* storage = cvCreateMemStorage(0); cvCvtColor( img, gray, CV_BGR2GRAY ); cvSmooth( gray, gray, CV_GAUSSIAN, 5, 15 ); // smooth it, otherwise a lot of false circles may be detected CvSeq* circles = cvHoughCircles( gray, storage, CV_HOUGH_GRADIENT, 2, gray->height/4, 200, 1 00 ); int i; for( i = 0; i < circles->total; i++ ) { float* p = (float*)cvGetSeqElem( circles, i ); cvCircle( img, cvPoint(cvRound(p[0]),cvRound(p[1])), 3, CV_RGB(0,255,0), -1, 8, 0 ); cvCircle( img, cvPoint(cvRound(p[0]),cvRound(p[1])), cvRound(p[2]), CV_RGB(255,0,0), 3, 8, 0 ); cout<<"圆心坐标x= "< cout<<"半径="< } cout<<"圆数量="< cvShowImage( "circles", img ); cvWaitKey(0); return 0; } 运行效果截图: Hough矩形提取: C ode: #include"cv.h" #include"highgui.h" #include #include #include int thresh = 50; IplImage* img = 0; IplImage* img0 = 0; CvMemStorage* storage = 0; CvPoint pt[4];const char* wndname = "Square Detection Demo"; double angle( CvPoint* pt1, CvPoint* pt2, CvPoint* pt0 ) { double dx1 = pt1->x - pt0->x; double dy1 = pt1->y - pt0->y; double dx2 = pt2->x - pt0->x; double dy2 = pt2->y - pt0->y; return (dx1*dx2 + dy1*dy2)/sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10); } CvSeq* findSquares4( IplImage* img, CvMemStorage* storage ) { CvSeq* contours; int i, c, l, N = 11; CvSize sz = cvSize( img->width & -2, img->height & -2 ); IplImage* timg = cvCloneImage( img ); IplImage* gray = cvCreateImage( sz, 8, 1 ); IplImage* pyr = cvCreateImage( cvSize(sz.width/2, sz.height/2), 8, 3 ); IplImage* tgray; CvSeq* result; double s, t; CvSeq* squares = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvPoint), storage ); cvSetImageROI( timg, cvRect( 0, 0, sz.width, sz.height )); // down-scale and upscale the image to filter out the noise cvPyrDown( timg, pyr, 7 ); cvPyrUp( pyr, timg, 7 ); tgray = cvCreateImage( sz, 8, 1 ); // find squares in every color plane of the image for( c = 0; c < 3; c++ ) { cvSetImageCOI( timg, c+1 ); cvCopy( timg, tgray, 0 ); for( l = 0; l < N; l++ ) { if( l == 0 ) { cvCanny( tgray, gray, 0, thresh, 5 ); cvDilate( gray, gray, 0, 1 ); } else { cvThreshold( tgray, gray, (l+1)*255/N, 255, CV_THRESH_BINARY ); } cvFindContours( gray, storage, &contours, sizeof(CvContour),CV_RETR_LIST, CV_CHAIN_APPROX_SI MPLE, cvPoint(0,0) ); while( contours ) { result = cvApproxPoly( contours, sizeof(CvContour), storage,CV_POLY_APPROX_DP, cvContourPer imeter(contours)*0.02, 0 ); if( result->total == 4 && fabs(cvContourArea(result,CV_WHOLE_SEQ)) > 1000 && cvCheckCont ourConvexity(result) ) { s = 0; for( i = 0; i < 5; i++ ) { if( i >= 2 ) { t = fabs(angle( (CvPoint*)cvGetSeqElem( result, i ),(CvPoint*)cvGetSeqElem( result, i-2 ),(C vPoint*)cvGetSeqElem( result, i-1 ))); s = s > t ? s : t; } } if( s < 0.3 ) for( i = 0; i < 4; i++ ) cvSeqPush( squares, (CvPoint*)cvGetSeqElem( result, i )); } contours = contours->h_next; } } } cvReleaseImage( &gray ); cvReleaseImage( &pyr ); cvReleaseImage( &tgray ); cvReleaseImage( &timg ); return squares; } // the function draws all the squares in the image void drawSquares( IplImage* img, CvSeq* squares ) { CvSeqReader reader; IplImage* cpy = cvCloneImage( img ); int i; cvStartReadSeq( squares, &reader, 0 ); for( i = 0; i < squares->total; i += 4 ) { CvPoint* rect = pt; int count = 4; memcpy( pt, reader.ptr, squares->elem_size ); CV_NEXT_SEQ_ELEM( squares->elem_size, reader ); memcpy( pt + 1, reader.ptr, squares->elem_size ); CV_NEXT_SEQ_ELEM( squares->elem_size, reader ); memcpy( pt + 2, reader.ptr, squares->elem_size ); CV_NEXT_SEQ_ELEM( squares->elem_size, reader ); memcpy( pt + 3, reader.ptr, squares->elem_size ); CV_NEXT_SEQ_ELEM( squares->elem_size, reader ); cvPolyLine( cpy, &rect, &count, 1, 1, CV_RGB(0,255,0), 3, CV_AA, 0 ); } cvShowImage( wndname, cpy ); cvReleaseImage( &cpy ); } void on_trackbar( int a ) { if( img ) drawSquares( img, findSquares4( img, storage ) ); } char* names[] = { "1.jpg", 0 }; int main(int argc, char** argv) { int i, c; storage = cvCreateMemStorage(0); for( i = 0; names[i] != 0; i++ ) { img0 = cvLoadImage( names[i], 1 ); if( !img0 ) { printf("Couldn't load %s\n", names[i] ); continue; } img = cvCloneImage( img0 ); cvNamedWindow( wndname, 1 ); cvCreateTrackbar( "canny thresh", wndname, &thresh, 1000, on_trackbar ); on_trackbar(0); c = cvWaitKey(0); cvReleaseImage( &img ); cvReleaseImage( &img0 ); cvClearMemStorage( storage ); if( c == 27 ) break; } cvDestroyWindow( wndname ); return 0; } 运行效果截图: 边缘直方图提取: Code: #include"cv.h" #include"highgui.h" #include #include #define PI 3.14 int main() { IplImage *src = 0; // source imagre IplImage *histimg = 0; // histogram image CvHistogram *hist = 0; // define multi_demention histogram IplImage* canny; CvMat* canny_m; IplImage* dx; // the sobel x difference IplImage* dy; // the sobel y difference CvMat* gradient; // value of gradient CvMat* gradient_dir; // direction of gradient CvMat* dx_m; // format transform to matrix CvMat* dy_m; CvMat* mask; CvSize size; IplImage* gradient_im; int i,j; float theta; int hdims = 8; // 划分HIST的个数,越高越精确 float hranges_arr[] = {-PI/2,PI/2}; // 直方图的上界和下界 float* hranges = hranges_arr; float max_val; // int bin_w; src=cvLoadImage("E:\\Download\\test.jpg", 0); // force to gray image if(src==0) return -1; cvNamedWindow( "Histogram", 0 ); //cvNamedWindow( "src", 0); size=cvGetSize(src); canny=cvCreateImage(cvGetSize(src),8,1);//边缘图像 dx=cvCreateImage(cvGetSize(src),32,1);//x方向上的差分//此处的数据类型为U 不怕溢出吗? dy=cvCreateImage(cvGetSize(src),32,1); gradient_im=cvCreateImage(cvGetSize(src),32,1);//梯度图像 canny_m=cvCreateMat(size.height,size.width,CV_32FC1);//边缘矩阵 dx_m=cvCreateMat(size.height,size.width,CV_32FC1); dy_m=cvCreateMat(size.height,size.width,CV_32FC1); gradient=cvCreateMat(size.height,size.width,CV_32FC1);//梯度矩阵 gradient_dir=cvCreateMat(size.height,size.width,CV_32FC1);//梯度方向矩阵 mask=cvCreateMat(size.height,size.width,CV_32FC1);//掩码 cvCanny(src,canny,60,180,3);//边缘检测 cvConvert(canny,canny_m);//把图像转换为矩阵 cvSobel(src,dx,1,0,3);// 一阶X方向的图像差分:dx cvSobel(src,dy,0,1,3);// 一阶Y方向的图像差分:dy cvConvert(dx,dx_m); cvConvert(dy,dy_m); cvAdd(dx_m,dy_m,gradient); // value of gradient//梯度不是等于根号下x的导数的平方加上y导数的平方吗? cvDiv(dx_m,dy_m,gradient_dir); // direction for(i=0;i for(j=0;j { if(cvmGet(canny_m,i,j)!=0 && cvmGet(dx_m,i,j)!=0)//此行是什么意思?只看边缘上的方向? { theta=cvmGet(gradient_dir,i,j); theta=atan(theta); cvmSet(gradient_dir,i,j,theta); } else { cvmSet(gradient_dir,i,j,0); } } hist = cvCreateHist( 1, &hdims, CV_HIST_ARRAY, &hranges, 1 ); // 创建一个指定尺寸的直方图,并返回创建的直方图指针 histimg = cvCreateImage( cvSize(320,200), 8, 3 ); // 创建一个图像,通道 cvZero( histimg ); // 清; cvConvert(gradient_dir,gradient_im);//把梯度方向矩阵转化为图像 cvCalcHist( &gradient_im, hist, 0, canny ); // 计算直方图 cvGetMinMaxHistValue( hist, 0, &max_val, 0, 0 ); // 只找最大值 cvConvertScale( hist->bins, hist->bins, max_val ? 255. / max_val : 0., 0 ); // 缩放bin 到区间[0,255] ,比例系数 cvZero( histimg ); bin_w = histimg->width /16; // hdims: 条的个数,则bin_w 为条的宽度 // 画直方图 for( i = 0; i < hdims; i++ ) { double val = ( cvGetReal1D(hist->bins,i)*histimg->height/255 ); // 返回单通道数组的指定元素,返回直方图第i条的大小,val为histimg中的i条的高度 CvScalar color = CV_RGB(255,255,0); //(hsv2rgb(i*180.f/hdims);//直方图颜色 cvRectangle( histimg, cvPoint(100+i*bin_w,histimg->height),cvPoint(100+(i+1)*bin_w,( int)(histimg->height - val)), color, 1, 8, 0 ); // 画直方图——画矩形,左下角,右上角坐标 } cvShowImage( "src", src); cvShowImage( "Histogram", histimg ); cvWaitKey(0); cvDestroyWindow("src"); cvDestroyWindow("Histogram"); cvReleaseImage( &src ); cvReleaseImage( &histimg ); cvReleaseHist ( &hist ); return 0; } 运行效果截图: 视频流中边缘检测: Code: #include"highgui.h" #include"cv.h" #include"stdio.h" #include int main(int argc,char ** argv) { IplImage * laplace = 0; IplImage * colorlaplace = 0; IplImage * planes[3] = {0,0,0}; CvCapture *capture = 0; //从摄像头读取 /*if(argc == 1 ||( argc==2 && strlen(argv[1])==1 && isdigit(argv[1][0]) )) capture = cvCaptureFromCAM(argc == 2 ? argv[1][0] -'0':0);*/ //从文件中读取 /* else if(argc == 2)*/ capture = cvCaptureFromAVI("1.avi"); if(!capture) { fprintf(stderr,"Could not initialize capturing...\n"); return -1; } cvNamedWindow("Laplacian",1); cvNamedWindow("video",1); //循环捕捉,直到用户按键跳出循环体 for(;;) { IplImage * frame =0; //抓起一祯 frame = cvQueryFrame(capture); if(!frame) break; if(!laplace) { //创建图像 for(int i=0;i<3;i++) planes[i] = cvCreateImage(cvSize(frame->width,frame->height),IPL_DEPTH_8U,1); laplace = cvCreateImage(cvSize(frame->width,frame->height),IPL_DEPTH_16S,1); colorlaplace=cvCreateImage(cvSize(frame->width,frame->height),IPL_DEPTH_8U,3); } cvCvtPixToPlane(frame,planes[0],planes[1],planes[2],0); for(int i=0;i<3;i++) { //交换,如通道变换 cvLaplace(planes[i],laplace,3); //使用线性变换转换输入函数元素成为无符号整形 cvConvertScaleAbs(laplace,planes[i],1,0); } cvCvtPlaneToPix(planes[0],planes[1],planes[2],0,colorlaplace); //结构相同(- 顶—左结构,1 - 底—左结构) colorlaplace->origin = frame->origin; //高斯滤波,平滑图像 // cvSmooth(colorlaplace, colorlaplace, CV_GAUSSIAN, 1, 0, 0); //形态学滤波,闭运算 cvDilate(colorlaplace, colorlaplace, 0, 1);//膨胀 cvErode(colorlaplace, colorlaplace, 0, 1);//腐蚀 cvShowImage("video", frame); cvShowImage("Laplacian",colorlaplace); if(cvWaitKey(10)>0) break; } cvReleaseCapture(&capture); cvDestroyWindow("Laplacian"); cvDestroyWindow("video"); return 0; } 运行效果截图: 纹理提取: Code: #include #include #include"cv.h" #include"highgui.h" int main(int argc, char* argv[]) { int tmp[8]={0}; int sum=0;int k=0; IplImage* img,*dst; img=cvLoadImage("E:\\Download\\2.jpg",0); CvScalar s; cvNamedWindow("img",NULL); cvNamedWindow("dst",NULL); cvShowImage("img",img); uchar* data=(uchar*)img->imageData; int step=img->widthStep; dst=cvCreateImage(cvSize(img->width,img->height),img->depth,1); dst->widthStep=img->widthStep; for(int i=1;i for(int j=1;j { if(data[(i-1)*step+j-1]>data[i*step+j]) tmp[0]=1; else tmp[0]=0; if(data[i*step+(j-1)]>data[i*step+j]) tmp[1]=1; else tmp[1]=0; if(data[(i+1)*step+(j-1)]>data[i*step+j]) tmp[2]=1; else tmp[2]=0; if (data[(i+1)*step+j]>data[i*step+j]) tmp[3]=1; else tmp[3]=0; if (data[(i+1)*step+(j+1)]>data[i*step+j]) tmp[4]=1; else tmp[4]=0; if(data[i*step+(j+1)]>data[i*step+j]) tmp[5]=1; else tmp[5]=0; if(data[(i-1)*step+(j+1)]>data[i*step+j]) tmp[6]=1; else tmp[6]=0; if(data[(i-1)*step+j]>data[i*step+j]) tmp[7]=1; else tmp[7]=0; for(k=0;k<=7;k++) sum+=abs(tmp[k]-tmp[k+1]); sum=sum+abs(tmp[7]-tmp[0]); if (sum<=2) s.val[0]=(tmp[0]*128+tmp[1]*64+tmp[2]*32+tmp[3]*16+tmp[4]*8+tmp[5]*4+tmp[6]*2+tmp[7]) ; else s.val[0]=59; cvSet2D(dst,i,j,s); } cvShowImage("dst",dst); cvWaitKey(-1); return 0; } 运行效果截图: f=strcat('D:\bishe\',num2str(i)); image=strcat(f,'.jpg'); PS=imread(image); PS=imresize(PS,[300,300],'bilinear');%归一化大小 PS=rgb2gray(PS); [m,n]=size(PS); %测量图像尺寸参数 GP=zeros(1,256); %预创建存放灰度出现概率的向量 for k=0:255 GP(k+1)=length(find(PS==k))/(m*n); %计算每级灰度出现的概率,将其存入GP 中相应位置 end %直方图均衡化 S1=zeros(1,256); for i=1:256 for j=1:i S1(i)=GP(j)+S1(i); %计算Sk end end S2=round((S1*256)+0.5); %将Sk归到相近级的灰度 %图像均衡化 f=PS; for i=0:255 f(find(PS==i))=S2(i+1); %将各个像素归一化后的灰度值赋给这个像素 end figure,imshow(f); %边缘检测 f=edge(f,'canny',0.25); imshow(f); %二值法锐化图像 f=double(f); [x,y]=gradient(f); g=sqrt(x.*x+y.*y); i=find(g>=0.5); g(i)=256; j=find(g<0.5); g(j)=0; imshow(g); title('二值法锐化图像'); %中值滤波 g=medfilt2(g); g=dither(g); matlab程序代码关于医学图像分割处理边缘检测阈值法 图像分割程序:% This is a program for extracting objects from an image. Written for vehicle number plate segmentation and extraction % Authors : Jeny Rajan, Chandrashekar P S % U can use attached test image for testing % input - give the image file name as input. eg :- car3.jpg clc; clear all; k=input('Enter the file name','s'); % input image; color image im=imread(k); im1=rgb2gray(im); im1=medfilt2(im1,[3 3]); %Median filtering the image to remove noise% BW = edge(im1,'sobel'); %finding edges [imx,imy]=size(BW); msk=[0 0 0 0 0; 0 1 1 1 0; 0 1 1 1 0; 0 1 1 1 0; 0 0 0 0 0;]; B=conv2(double(BW),double(msk)); %Smoothing image to reduce the number of connected components L = bwlabel(B,8);% Calculating connected components mx=max(max(L)) % There will be mx connected components.Here U can give a value between 1 and mx for L or in a loop you can extract all connected components % If you are using the attached car image, by giving 17,18,19,22,27,28 to L you can extract the number plate completely. [r,c] = find(L==17); rc = [r c]; 一、颜色特征 1 颜色空间 1.1 RGB 颜色空间 是一种根据人眼对不同波长的红、绿、蓝光做出锥状体细胞的敏感度描述的基础彩色模式,R、 G、B 分别为图像红、绿、蓝的亮度值,大小限定在 0~1 或者在 0~255。 1.2 HIS 颜色空间 是指颜色的色调、亮度和饱和度,H表示色调,描述颜色的属性,如黄、红、绿,用角度 0~360度来表示;S 是饱和度,即纯色程度的量度,反映彩色的浓淡,如深红、浅红,大小限定在 0~1;I 是亮度,反映可见光对人眼刺激的程度,它表征彩色各波长的总能量,大小限定在 0~1。 1.3 HSV 颜色模型 HSV 颜色模型依据人类对于色泽、明暗和色调的直观感觉来定义颜色, 其中H (Hue)代表色度, S (Saturat i on)代表色饱和度,V (V alue)代表亮度, 该颜色系统比RGB 系统更接近于人们的经验和对彩色的感知, 因而被广泛应用于计算机视觉领域。 已知RGB 颜色模型, 令M A X = max {R , G, B },M IN =m in{R , G,B }, 分别为RGB 颜色模型中R、 G、 B 三分量的最大和最小值, RGB 颜色模型到HSV 颜色模型的转换公式为: S =(M A X - M IN)/M A X H = 60*(G- B)/(M A X - M IN) R = M A X 120+ 60*(B – R)/(M A X - M IN) G= M A X 240+ 60*(R – G)/(M A X - M IN) B = M A X V = M A X 2 颜色特征提取算法 2.1 一般直方图法 颜色直方图是最基本的颜色特征表示方法,它反映的是图像中颜色的组成分布,即出现了哪些颜色以及各种颜色出现的概率。其函数表达式如下: H(k)= n k/N (k=0,1,…,L-1) (1) 其中,k 代表图像的特征取值,L 是特征可取值的个数,n k是图像中具有特征值为 k 的象素的个数,N 是图像象素的总数。由上式可见,颜色直方图所描述的是不同色彩在整幅图像中所占的比例,无法描述图像中的对象或物体,但是由于直方图相对于图像以观察轴为轴心的旋转以及幅度不大的平移和缩放等几何变换是不敏感的,而且对于图像质量的变化也不甚敏感,所以它特别适合描述那些难以进行自动分割的图像和不需要考虑物体空间位置的图像。 由于计算机本身固有的量化缺陷,这种直方图法忽略了颜色的相似性,人们对这种算法进行改进,产生了全局累加直方图法和局部累加直方图法。 2.2 全局累加直方图法 全局累加直方图是以颜色值作为横坐标,纵坐标为颜色累加出现的频数,因此图像的累加直方空间 H 定义为: #include "stdafx.h" #include "mymfc.h" #include "mymfcDlg.h" #include "afxdialogex.h" #include CmymfcDlg::CmymfcDlg(CWnd* pParent /*=NULL*/) : CDialogEx(CmymfcDlg::IDD, pParent) , TheImage(NULL) , rePath(_T("")) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CmymfcDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CmymfcDlg, CDialogEx) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_ReadImg, &CmymfcDlg::OnBnClickedReadimg) ON_BN_CLICKED(IDC_EdgeDetect, &CmymfcDlg::OnBnClickedEdgedetect) ON_BN_CLICKED(IDC_Refresh, &CmymfcDlg::OnBnClickedRefresh) ON_BN_CLICKED(IDC_GrayProcess, &CmymfcDlg::OnBnClickedGrayprocess) ON_BN_CLICKED(IDC_Sobel, &CmymfcDlg::OnBnClickedSobel) ON_BN_CLICKED(IDC_Laplace, &CmymfcDlg::OnBnClickedLaplace) ON_BN_CLICKED(IDC_FFT2, &CmymfcDlg::OnBnClickedFft2) ON_BN_CLICKED(IDC_CImage, &CmymfcDlg::OnBnClickedCimage) ON_BN_CLICKED(IDC_Mirror, &CmymfcDlg::OnBnClickedMirror) ON_BN_CLICKED(IDC_CColor, &CmymfcDlg::OnBnClickedCcolor) ON_BN_CLICKED(IDC_MedianBlur, &CmymfcDlg::OnBnClickedMedianblur) ON_BN_CLICKED(IDC_Gaussian, &CmymfcDlg::OnBnClickedGaussian) ON_BN_CLICKED(IDC_BothSide, &CmymfcDlg::OnBnClickedBothside) ON_BN_CLICKED(IDC_Equally, &CmymfcDlg::OnBnClickedEqually) ON_BN_CLICKED(IDC_Corrosion, &CmymfcDlg::OnBnClickedCorrosion) ON_BN_CLICKED(IDC_Dilate, &CmymfcDlg::OnBnClickedDilate) END_MESSAGE_MAP() // CmymfcDlg 消息处理程序 BOOL CmymfcDlg::OnInitDialog() { CDialogEx::OnInitDialog(); MATLAB特征提取代码 for i=1:26 f=strcat('D:\bishe\',num2str(i)); image=strcat(f,'.jpg'); PS=imread(image); PS=imresize(PS,[300,300],'bilinear');%归一化大小 PS=rgb2gray(PS); [m,n]=size(PS); %测量图像尺寸参数 GP=zeros(1,256); %预创建存放灰度出现概率的向量 for k=0:255 GP(k+1)=length(find(PS==k))/(m*n); %计算每级灰度出现的概率,将其存入GP中相应位置 end %直方图均衡化 S1=zeros(1,256); for i=1:256 for j=1:i S1(i)=GP(j)+S1(i); %计算Sk end end S2=round((S1*256)+0.5); %将Sk归到相近级的灰度 %图像均衡化 f=PS; for i=0:255 f(find(PS==i))=S2(i+1); %将各个像素归一化后的灰度值赋给这个像素 end figure,imshow(f); %边缘检测 f=edge(f,'canny',0.25); imshow(f); %二值法锐化图像 f=double(f); [x,y]=gradient(f); g=sqrt(x.*x+y.*y); i=find(g>=0.5); g(i)=256; j=find(g<0.5); g(j)=0; imshow(g); title('二值法锐化图像'); %中值滤波 g=medfilt2(g); g=dither(g); imshow(g); ******************* 实践教学 ******************* 兰州理工大学 计算机与通信学院 2012年秋季学期 图像处理综合训练 题目:图像分割程序设计 专业班级: 姓名: 学号: 指导教师: 成绩: 目录 摘要 (1) 一、前言 (2) 二、算法分析与描述 (3) 三、详细设计过程 (5) 四、调试过程中出现的问题及相应解决办法 (8) 五、程序运行截图及其说明 (8) 六、简单操作手册 (12) 设计总结 (15) 参考资料 (16) 致谢 (17) 附录 (18) 摘要 图像分割就是从图像中将某个特定区域与其他部分进行分离并提取出来的处理 通常又称之为图像的二值化处理。图像分割就是把图像分成若干个特定的、具有独特性质的区域并提出感兴趣目标的技术和过程。它是由图像处理到图像分析的关键步骤。现有的图像分割方法主要分以下几类:基于阈值的分割方法、基于区域的分割方法、基于边缘的分割方法以及基于特定理论的分割方法等。近年来,研究人员不断改进原有的图像分割方法并把其它学科的一些新理论和新方法用于图像分割,提出了不少新的分割方法。 关键词:图像分割;阈值;二值化; 一、前言 图形图像处理的应用领域涉及人类生活和工作的各个方面,它是从60年代以来随计算机的技术和VLSI的发展而产生、发展和不断成熟起来的一个新技术领域理论上和实际应用上都并取得了巨大的成就。数字图像处理与模拟图像处理的根本不同在于,它不会因图像的存储、传输或复制等一系列变换操作而导致图像质量的退化,所以图形图像的处理在我们的生活中又很重要的作用。在对图像的研究和应用中,人们往往只对图像中的某些部分感兴趣。这些部分通常称为目标或前景,它们一般对应图像中特定的、具体独特性质的区域。为了辨识和分析目标,需要将它们分别提取出来,在此基础上才有可能对目标进一步利用。图像分割就是指把图像分成各具特性的区域并提取出感兴趣的目标的技术和过程。在图象分析中,通常需将所关心的目标从图象中提取出来,即图象的分割。图象分割在图象分析,图象识别,图象检测等方面占有非常重要的位置。 图像常见特征提取方法简介 常用的图像特征有颜色特征、纹理特征、形状特征、空间关系特征。 一、颜色特征 (一)特点:颜色特征是一种全局特征,描述了图像或图像区域所对应的景物的表面性质。一般颜色特征是基于像素点的特征,此时所有属于图像或图像区域的像素都有各自的贡献。由于颜色对图像或图像区域的方向、大小等变化不敏感,所以颜色特征不能很好地捕捉图像中对象的局部特征。另外,仅使用颜色特征查询时,如果数据库很大,常会将许多不需要的图像也检索出来。颜色直方图是最常用的表达颜色特征的方法,其优点是不受图像旋转和平移变化的影响,进一步借助归一化还可不受图像尺度变化的影响,基缺点是没有表达出颜色空间分布的信息。 (二)常用的特征提取与匹配方法 (1)颜色直方图 其优点在于:它能简单描述一幅图像中颜色的全局分布,即不同色彩在整幅图像中所占的比例,特别适用于描述那些难以自动分割的图像和不需要考虑物体空间位置的图像。其缺点在于:它无法描述图像中颜色的局部分布及每种色彩所处的空间位置,即无法描述图像中的某一具体的对象或物体。 最常用的颜色空间:RGB颜色空间、HSV颜色空间。 颜色直方图特征匹配方法:直方图相交法、距离法、中心距法、参考颜色表法、累加颜色直方图法。 (2)颜色集 颜色直方图法是一种全局颜色特征提取与匹配方法,无法区分局部颜色信息。颜色集是对颜色直方图的一种近似首先将图像从RGB颜色空间转化成视觉均衡的颜色空间(如HSV 空间),并将颜色空间量化成若干个柄。然后,用色彩自动分割技术将图像分为若干区域,每个区域用量化颜色空间的某个颜色分量来索引,从而将图像表达为一个二进制的颜色索引集。在图像匹配中,比较不同图像颜色集之间的距离和色彩区域的空间关系 (3)颜色矩 这种方法的数学基础在于:图像中任何的颜色分布均可以用它的矩来表示。此外,由于颜色分布信息主要集中在低阶矩中,因此,仅采用颜色的一阶矩(mean)、二阶矩(variance)和三阶矩(skewness)就足以表达图像的颜色分布。 (4)颜色聚合向量 其核心思想是:将属于直方图每一个柄的像素分成两部分,如果该柄内的某些像素所占据的连续区域的面积大于给定的阈值,则该区域内的像素作为聚合像素,否则作为非聚合像素。(5)颜色相关图 二纹理特征 (一)特点:纹理特征也是一种全局特征,它也描述了图像或图像区域所对应景物的表面性质。但由于纹理只是一种物体表面的特性,并不能完全反映出物体的本质属性,所以仅仅利用纹理特征是无法获得高层次图像内容的。与颜色特征不同,纹理特征不是基于像素点的特征,它需要在包含多个像素点的区域中进行统计计算。在模式匹配中,这种区域性的特征具有较大的优越性,不会由于局部的偏差而无法匹配成功。作为一种统计特征,纹理特征常具有旋转不变性,并且对于噪声有较强的抵抗能力。但是,纹理特征也有其缺点,一个很明显的缺点是当图像的分辨率变化的时候,所计算出来的纹理可能会有较大偏差。另外,由于有可能受到光照、反射情况的影响,从2-D图像中反映出来的纹理不一定是3-D物体表面真实 目录 1 梯度、边缘和角点 1.1 Sobel 1.2 Laplace 1.3 Canny 1.4 PreCornerDetect 1.5 CornerEigenValsAndVecs 1.6 CornerMinEigenVal 1.7 CornerHarris 1.8 FindCornerSubPix 1.9 GoodFeaturesToTrack 2 采样、插值和几何变换 2.1 InitLineIterator 2.2 SampleLine 2.3 GetRectSubPix 2.4 GetQuadrangleSubPix 2.5 Resize 2.6 WarpAffine 2.7 GetAffineTransform 2.8 2DRotationMatrix 2.9 WarpPerspective 2.10 WarpPerspectiveQMatrix 2.11 GetPerspectiveTransform 2.12 Remap 2.13 LogPolar 3 形态学操作 3.1 CreateStructuringElementEx 3.2 ReleaseStructuringElement 3.3 Erode 3.4 Dilate 3.5 MorphologyEx 4 滤波器与色彩空间变换 4.1 Smooth 4.2 Filter2D 4.3 CopyMakeBorder 4.4 Integral 4.5 CvtColor 4.6 Threshold 4.7 AdaptiveThreshold 5 金字塔及其应用 5.1 PyrDown 5.2 PyrUp 6 连接部件 6.1 CvConnectedComp 人脸检测算法原理及OpenCV 人脸检测程序分析 罗海风 2011-3-30 人脸检测研究背景:人脸检测 基于肤色特征基于灰度特征 启发模型统计模型 肤色区域分割方法人脸模板方法等特征空间方法PCA 、fisherfaces 方法等ANN SVM 概率模型方法 贝叶斯概率模型HMM 集成机器学习 以上所列方法中,基于统计模型的方法是目前比较流行的方法[1],具有较大的优越性。其优点有: 1.不依赖于人脸的先验知识和参数模型,可以避免不精确或不完整的知识造成的错误; 2.采用实例学习的方法获取模型的参数,统计意义上更加可靠; 3.通过增加学习的实例可以扩种检测模式范围,提高鲁棒性。 在统计模型方法中,2001年左右由Viola 和Jones 提出的基于集成机器学习的人脸检测算法相对于其他方法具有明显优势[123]。近期文献也表明目前尚未发现优于Viola &Jones 方法的其他人脸检测方法[4]。该方法不仅检测精度高,最关键的是其运算速度大大快于其他方法。Viola &Jones 人脸检测方法原理: 该方法中几个关键性概念[5]: 1.Haar-like 特征 Haar-like 型特征是Viola 等人提出的一种简单矩形特征,因为类似Haar 小波而得名。Haar 型特征的定义是黑色矩形和白色矩形在图像子窗口中对应的区域的权重灰度级总和之差。上图显示了两种最简单的特征算子。在上述图中,可以看到,在人脸特定结构处,算子计算得到较大的值。 2.积分图 算子数量庞大时上述计算量显得太大,Viola等人发明了积分图方法,使得计算速度大大加快。积分图如上所示,点1处的值为A区域的像素积分,点2处的值为AB区域的像素积分。对整张图片进行一次积分操作,便可以方便的计算出任一区域D像素积分值为4+1-2-3。 3.Adaboost训练算法 在离散Adaboost算法中,Haar-like特征算子计算结果减去某阈值,便可视为一个人脸检测器。因为其准确率不高,称为弱分类器。Adaboost算法的循环中,首先利用各种弱分类器对训练图片库进行分类,准确度最高的弱分类器保留下来,同时提高判断错误的图片的权重,进入下一循环。最终将每次循环所保留的弱分类器组合起来,成为一个准确的人脸检测器,称为强分类器。具体计算流程见[35]。 4.瀑布型级联检测器 瀑布型级联检测器是针对人脸检测速度问题提出的一种检测结构。瀑布的每一层是一个由adaboost算法训练得到的强分类器。设置每层的阈值,是的大多数人脸能够通过,在此基础上尽量抛弃反例。位置越靠后的层越复杂,具有越强的分类能力。 这样的检测器结构就想一系列筛孔大小递减的筛子,每一步都能筛除一些前面筛子楼下的反例,最终通过所有筛子的样本被接受为人脸。瀑布型检测器训练算法见[3]。 OpenCV人脸检测程序流程[6]: OpenCV的人脸检测程序采用了Viola&Jones人脸检测方法,主要是调用训练好的瀑布级联分类器cascade来进行模式匹配。 cvHaarDetectObjects,先将图像灰度化,根据传入参数判断是否进行canny边缘处理(默认不 for i=1:26 f=strcat('D:\bishe\',num2str(i)); image=strcat(f,'.jpg'); PS=imread(image); PS=imresize(PS,[300,300],'bilinear');%归一化大小 PS=rgb2gray(PS); [m,n]=size(PS); %测量图像尺寸参数 GP=zeros(1,256); %预创建存放灰度出现概率的向量 for k=0:255 GP(k+1)=length(find(PS==k))/(m*n); %计算每级灰度出现的概率,将其存入GP中相应位置 end %直方图均衡化 S1=zeros(1,256); for i=1:256 for j=1:i S1(i)=GP(j)+S1(i); %计算Sk end end S2=round((S1*256)+0.5); %将Sk归到相近级的灰度 %图像均衡化 f=PS; for i=0:255 f(find(PS==i))=S2(i+1); %将各个像素归一化后的灰度值赋给这个像素 end figure,imshow(f); %边缘检测 f=edge(f,'canny',0.25); imshow(f); %二值法锐化图像 f=double(f); [x,y]=gradient(f); g=sqrt(x.*x+y.*y); i=find(g>=0.5); g(i)=256; j=find(g<0.5); g(j)=0; imshow(g); title('二值法锐化图像'); %中值滤波 g=medfilt2(g); g=dither(g); imshow(g); %提取面积,矩形度,圆形度,拉伸度特征 %两个程序,亲测可用 clear all a=imread('moon.tif'); figure,imshow(a) count=imhist(a); [m,n]=size(a); N=m*n; L=256; count=count/N;%%每一个像素的分布概率 count for i=1:L if count(i)~=0 st=i-1; break; end end st for i=L:-1:1 if count(i)~=0 nd=i-1; break; end end nd f=count(st+1:nd+1); %f是每个灰度出现的概率 size(f) E=[]; for Th=st:nd-1 %%%设定初始分割阈值为Th av1=0; av2=0; Pth=sum(count(1:Th+1)); %%%第一类的平均相对熵为 for i=0:Th av1=av1-count(i+1)/Pth*log(count(i+1)/Pth+0.00001); end %%%第二类的平均相对熵为 for i=Th+1:L-1 av2=av2-count(i+1)/(1-Pth)*log(count(i+1)/(1-Pth)+0.00001); end E(Th-st+1)=av1+av2; end position=find(E==(max(E))); th=st+position-1 for i=1:m for j=1:n if a(i,j)>th a(i,j)=255; else a(i,j)=0; end end end figure,imshow(a); %%%%%%%%%%%%%%%%%%%%%2-d 最大熵法(递推方法) %%%%%%%%%%% clear all; clc; tic a=imread('trial2_2.tiff'); figure,imshow(a); a0=double(a); [m,n]=size(a); h=1; a1=zeros(m,n); % 计算平均领域灰度的一维灰度直方图 for i=1:m for j=1:n for k=-h:h for w=-h:h; p=i+k; q=j+w; if (p<=0)|( p>m) p=i; end if (q<=0)|(q>n) q=j; end a1(i,j)=a0(p,q)+a1(i,j); end end a2(i,j)=uint8(1/9*a1(i,j)); end 图像特征提取的定位是计算机视觉和图像处理里的一个概念,表征图像的特性。输入是一张图像(二维的数据矩阵),输出是一个值、一个向量、一个分布、一个函数或者是信号。提取特征的方法千差万别,下面是图像特征的一些特性: 边缘 边缘是两个区域边界的像素集合,本质上是图像像素的子集,能将区域分开。边缘形状是任意的,实践中定义为大的梯度的像素点的集合,同时为了平滑,还需要一些算法进行处理。角 顾名思义,有个突然较大的弧度。早起算法是在边缘检测的基础上,分析边缘的走向,如果突然转向则被认为是角。后来的算法不再需要边缘检测,直接计算图像梯度的高度曲率(合情合理)。但会出现没有角的地方也检测到角的存在。 区域 区域性的结构,很多区域检测用来检测角。区域检测可以看作是图像缩小后的角检测。 脊 长形的物体,例如道路、血管。脊可以看成是代表对称轴的一维曲线,每个脊像素都有脊宽度,从灰梯度图像中提取要比边缘、角和区域都难。 特征提取 检测到特征后提取出来,表示成特征描述或者特征向量。 常用的图像特征:颜色特征、 纹理特征 形状特征 空间关系特征。 1.颜色特征 1.1特点:颜色特征是全局特征,对区域的方向、大小不敏感,但是不能很好捕捉局部特征。 优点:不受旋转和平移变化的影响,如果归一化不受尺度变化的影响。 缺点:不能表达颜色空间分布的信息。 1.2特征提取与匹配方法 (1)颜色直方图 适用于难以自动分割的图像,最常用的颜色空间:RGB和HSV。 匹配方法:直方图相交法(相交即交集)、距离法、中心距法、参考颜色表法、累加颜色直方图法。 对颜色特征的表达方式有许多种,我们采用直方图进行特征描述。常见的直方图有两种:统计直方图,累积直方图。我们将分别实验两种直方图在图像聚类和检索中的性能。 统计直方图 为利用图像的特征描述图像,可借助特征的统计直方图。图像特征的统计直方图实际是一个1-D的离散函数,即: 上式中k代表图像的特征取值,L是特征可取值个数,是图像中具有特征值为k的像素的个数,N是图像像素的总数,一个示例如下图:其中有8个直方条,对应图像中的8种灰度像素在总像素中的比例。 /. #include "stdafx.h" #include "mymfc.h" #include "mymfcDlg.h" #include "afxdialogex.h" #include CmymfcDlg::CmymfcDlg(CWnd* pParent /*=NULL*/) : CDialogEx(CmymfcDlg::IDD, pParent) , TheImage(NULL) , rePath(_T("")) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CmymfcDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CmymfcDlg, CDialogEx) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_ReadImg, &CmymfcDlg::OnBnClickedReadimg) ON_BN_CLICKED(IDC_EdgeDetect, &CmymfcDlg::OnBnClickedEdgedetect) ON_BN_CLICKED(IDC_Refresh, &CmymfcDlg::OnBnClickedRefresh) ON_BN_CLICKED(IDC_GrayProcess, &CmymfcDlg::OnBnClickedGrayprocess) ON_BN_CLICKED(IDC_Sobel, &CmymfcDlg::OnBnClickedSobel) ON_BN_CLICKED(IDC_Laplace, &CmymfcDlg::OnBnClickedLaplace) ON_BN_CLICKED(IDC_FFT2, &CmymfcDlg::OnBnClickedFft2) ON_BN_CLICKED(IDC_CImage, &CmymfcDlg::OnBnClickedCimage) ON_BN_CLICKED(IDC_Mirror, &CmymfcDlg::OnBnClickedMirror) ON_BN_CLICKED(IDC_CColor, &CmymfcDlg::OnBnClickedCcolor) ON_BN_CLICKED(IDC_MedianBlur, &CmymfcDlg::OnBnClickedMedianblur) ON_BN_CLICKED(IDC_Gaussian, &CmymfcDlg::OnBnClickedGaussian) ON_BN_CLICKED(IDC_BothSide, &CmymfcDlg::OnBnClickedBothside) ON_BN_CLICKED(IDC_Equally, &CmymfcDlg::OnBnClickedEqually) ON_BN_CLICKED(IDC_Corrosion, &CmymfcDlg::OnBnClickedCorrosion) ON_BN_CLICKED(IDC_Dilate, &CmymfcDlg::OnBnClickedDilate) END_MESSAGE_MAP() // CmymfcDlg 消息处理程序 BOOL CmymfcDlg::OnInitDialog() { CDialogEx::OnInitDialog(); 1、训练程序整体流程 (1)读输入参数并打印相关信息 (2)进入训练程序最外层入口classifier.train 1)读正负样本,将正负样本放入imgLiast中,先读正样本,后读负样本 2)load( dirName )判断之前是否有已训练好的xml文件,若有,不在重新训练该stage的xml文件,没有返回false,初始化参数 3)计算requiredLeafFARate = pow(maxFalseAlarm,numStages)/max_depth,该参数是stage停止条件(利用训练样本集来计算tempLeafFARate,若 tempLeafFARate小于这一参数,则退出stage训练循环); 4)Stage训练循环 5)更新训练样本集,计算tempLeafFARate(负样本被预测为正样本的个数除以读取负样本的次数,第一次没有训练之前,这个比值为1,因为没训练之前, 所有负样本都被预测成了正样本,当第一层训练好以后,负样本采集时会先 用第一层的分类器预测一次,若能分类,则不选用,选用负样本的数目是固 定的,但选用这么多负样本总共要选的次数会随着层数的增多而加大,因为 层数越大,分类器的分类能力也要求越大,说需要的样本就是前面分类器所 不恩呢该识别的,故在采集时也比较困难。) 6)判断stage是否退出训练,若tempLeafFARate %直接帧间差分,计算阈值并进行二值化处理(效果不好) clc; clear; Im1 = double(imread('lena.TIF')); %读取背景图片 Im2 = double(imread('lena.TIF'); %读取当前图片 [X Y Z] = size(Im2); %当前图片的各维度值 DIma = zeros(X,Y); for i = 1:X for j = 1:Y DIma(i,j) =Im1(i,j) - Im2(i,j); %计算过帧间差分值 end end figure,imshow(uint8(DIma)) %显示差分图像 title('DIma') med = median(DIma); %计算二值化阈值:差值图像中值 mad = abs(mean(DIma) - med); %中值绝对差 T = mean(med + 3*1.4826*mad) %初始阈值 Th =5*T; %调整阈值 BW = DIma <= Th; %根据阈值对图像进行二值化处理 figure,imshow(BW) %se = strel('disk',2); %膨胀处理 %BW = imopen(BW,se); %figure,imshow(BW) %title('BW') [XX YY] = find(BW==0); %寻找有效像素点的最大边框 handle = rectangle('Position',[min(YY),min(XX) ,max(YY)-min(YY),max(XX)-min(XX)]); set(handle,'EdgeColor',[0 0 0]); hei = max(XX)-min(XX); %边框高度 mark = min(YY)+1; while mark < max(YY)-1 %从边框左边开始到右边物质循环,寻找各个人体边缘 left = 0;right = 0; for j = mark:max(YY)-1 ynum = 0; for i = min(XX)+1 : max(XX)-1 if BW(i,j) == 0; ynum = ynum + 1; 基于opencv 对图像的预处理 1.问题描述 本次设计是基于opencv 结合c++语言实现的对图像的预处理,opencv 是用于开发实时的图像处理、计算机视觉及模式识别程序;其中图像的预处理也就是利用opencv 对图像进行简单的编辑操作;例如对图像的对比度、亮度、饱和度进行调节,同时还可以对图像进行缩放和旋转,这些都是图像预处理简单的处理方法;首先通过opencv 加载一幅原型图像,显示出来;设置五个滑动控制按钮,当拖动按钮时,对比度、亮度、饱和度的大小也会随之改变,也可以通过同样的方式调节缩放的比例和旋转的角度,来控制图像,对图像进行处理,显示出符合调节要求的图像,进行对比观察他们的之间的变化。 2.模块划分 此次设计的模块分为五个模块,滑动控制模块、对比度和亮度调节模块、饱和度调节模块、缩放调节模块、旋转调节模块,他们之间的关系如下所示: 图一、各个模块关系图 调用 调用 调用 调用 滑动控制模块 对比度和亮度调节模块 饱和度调节模块 缩放调节模块 旋转调节模块 滑动控制模块处于主函数之中,是整个设计的核心部分,通过createTrackbar创建五个滑动控制按钮并且调用每个模块实现对图像相应的调节。 3.算法设计 (1)滑动控制: 滑动控制是整个设计的核心部分,通过创建滑动控制按钮调节大小来改变相应的数据,进行调用函数实现对图像的编辑,滑动控制是利用createTrackbar(),函数中包括了滑动控制的名称,滑动控制显示在什么窗口上,滑动变量的地址和它调节的最大围,以及每个控制按钮应该调用什么函数实现什么功能; (2)对比度和亮度的调节: 对比度和亮度的调节的原理是依照线性理论,它的公式如下所示:g(x)=a* f(x) +b,其中f(x)表示源图像的像素,g(x)表示输出图像的像素,参数a(需要满足a>0)被称为增益(gain),常常被用来控制图像的对比度,参数b通常被称为偏置(bias),常常被用来控制图像的亮度; (3)饱和度的调节: 饱和度调节利用cvCvtColor( src_image, dst_image, CV_BGR2HSV )将RGB 颜色空间转换为HSV颜色空间,其中“H=Hue”表示色调,“S=Saturation”表示饱和度,“V=Value ”表示纯度;所以饱和度的调节只需要调节S的大小,H 和V的值不需要做任何的改变; (4)旋转的调节: 旋转是以某参考点为圆心,将图像的个点(x,y)围绕圆心转动一个逆时针角度θ,变为新的坐标(x1,y1),x1=rcos(α+θ),y1=rsin(α+θ),其中r是图像的极径,α是图像与水平的坐标的角度的大小; (5)缩放的调节: 首先得到源图像的宽度x和高度y,变换后新的图像的宽度和高度分别为x1和y1,x1=x*f,y1=y*f,其中f是缩放因子; 4.函数功能描述 (1)主函数main()用来设置滑动控制按钮,当鼠标拖动按钮可以得到相应的数据大小,实现手动控制的功能,当鼠标拖动对比度和亮度调节是,主函数调用MATLAB特征提取代码讲课稿
matlab程序代码 关于医学图像分割处理 边缘检测 阈值法
图像颜色特征提取原理
图像处理opencv代码
MATLAB特征提取代码
图像分割程序设计汇总
图像特征提取总结
opencv函数目录-Cv图像处理
人脸检测算法原理及OPENCV人脸检测程序分析
MATLAB特征提取代码
两个matlab实现最大熵法图像分割程序
图像特征提取综述
图像管理方案计划opencv代码
opencv adaboost人脸检测训练程序阅读笔记(LBP特征)
图像特征提取matlab程序
基于opencv对图像的预处理