Chinaunix首页 | 论坛 | 博客
  • 博客访问: 434400
  • 博文数量: 53
  • 博客积分: 6243
  • 博客等级: 大校
  • 技术积分: 567
  • 用 户 组: 普通用户
  • 注册时间: 2006-07-08 18:00
文章分类

全部博文(53)

文章存档

2013年(1)

2011年(20)

2010年(28)

2007年(3)

2006年(1)

分类: C/C++

2011-02-23 19:44:35


      以前我用 gabor 和 adaboost 做过图像识别,

现在用另一种方法试试。首先把做卷积的 gabor 核改一下加强方向性。
  1. ZeGabor::ZeGabor(double dPhi, double dNu, double dSigma, double dF)
  2. {
  3.     double Sigma = dSigma;
  4.     double F = dF;

  5.     double Kmax = PI/2;

  6.     // Absolute value of K
  7.     double K = Kmax / pow(F, dNu);
  8.     double Phi = dPhi;

  9.         double dModSigma = Sigma/K;

  10.         double dWidth = cvRound(dModSigma*6 + 1);

  11.         if (fmod(dWidth, 2.0)==0.0) dWidth++;

  12.     Width = (long)dWidth;

  13.     Real = cvCreateMat( Width, Width, CV_32FC1);
  14.     Imag = cvCreateMat( Width, Width, CV_32FC1);

  15.         CvMat *mReal, *mImag;
  16.         mReal = cvCreateMat( Width, Width, CV_32FC1);
  17.         mImag = cvCreateMat( Width, Width, CV_32FC1);

  18.         double a, b;
  19.         double c;
  20.         double x, y;
  21.         double ra, rb;
  22.         double dReal;
  23.         double dImag;
  24.         double dTemp1, dTemp2, dTemp3;

  25.         a = 0.4;
  26.         b = 1.0;
  27.         c = dPhi;


  28.         for (int i = 0; i < Width; i++)
  29.         {
  30.             for (int j = 0; j < Width; j++)
  31.             {
  32.                 x = i-(Width-1)/2;
  33.                 y = j-(Width-1)/2;

  34.                 ra = x*cos(c) + y*sin(c);
  35.                 rb = -x*sin(c) + y*cos(c);

  36.                 dTemp1 = (K*K/Sigma*Sigma)*exp(-(ra*ra/(a*a)+rb*rb/(b*b))*K*K/(2*Sigma*Sigma));
  37.                 dTemp2 = cos(K*cos(Phi)*1.5*x + K*sin(Phi)*1.5*y) - exp(-(pow(Sigma,2)/2));
  38.                 dTemp3 = sin(K*cos(Phi)*1.5*x + K*sin(Phi)*1.5*y);


  39.                 dReal = dTemp1*dTemp2;
  40.                 dImag = dTemp1*dTemp3;

  41.                 cvSetReal2D((CvMat*)mReal, i, j, dReal );
  42.                 cvSetReal2D((CvMat*)mImag, i, j, dImag );
  43.             }
  44.         }
  45.         /**************************** Gabor Function ****************************/
  46.         cvCopy(mReal, Real, NULL);
  47.         cvCopy(mImag, Imag, NULL);
  48.         //printf("A %d x %d Gabor kernel with %f PI in arc is created.\n", Width, Width, Phi/PI);
  49.         cvReleaseMat( &mReal );
  50.         cvReleaseMat( &mImag );
  51. }


这图经过放大,实际用的卷积核比这个小很多。用一组不同方向的 ZeGabor 核和图像作卷积,在卷积结果
图中,图像的边沿部分的坐标点上的不同方向结果中会有某一个或几个比平均值大很多,取这样的点做特征
点,这些方向做特征值,可以构成一组特征用于图像识别。



这是要识别的目标图像的标准图,右图上的黄点是取得的特征点,特征点上的特征值是此点上的图像边沿方
向。

提取标准图的特征:
  1. IplImage *img_gray = cvCreateImage( cvGetSize(img_src), 8, 1 );

  2.         cvCvtColor(img_src, img_gray, CV_BGR2GRAY);

  3.         CvMat *mat_edge = cvCreateMat(img_gray->height, img_gray->width, CV_32FC1);
  4.         CvMat *mat_dire = cvCreateMat(img_gray->height, img_gray->width, CV_32SC1);
  5.         CvMat *mat_mask = cvCreateMat(img_gray->height, img_gray->width, CV_32FC1);

  6.         CvMat *mat_max_dire = cvCreateMat(img_gray->height, img_gray->width, CV_32SC1);

  7.         CvMat *mat_mags[ZGDIRES];

  8.         for (int i=0; i<ZGDIRES; i++)
  9.         {
  10.                 mat_mags[i] = cvCreateMat(img_gray->height, img_gray->width, CV_32FC1);
  11.         }

  12.         ZeGabor *gabors[ZGDIRES];

  13.         double Sigma = 2*PI;
  14.         double F = sqrt(2.0);
  15.         double dn = ZGDN;

  16.         for (int n=0; n<ZGDIRES; n++)
  17.         {
  18.                 gabors[n] = new ZeGabor((PI/ZGDIRES)*n, dn, Sigma, F);
  19.         }

  20.         for (int n=0; n<ZGDIRES; n++)
  21.         {
  22.                 gabors[n]->conv_mat_mag(img_gray, mat_mags[n]);
  23.         }

  24.         for (int y=0; y<img_gray->height; y++)
  25.         {
  26.                 for (int x=0; x<img_gray->width; x++)
  27.                 {
  28.                         float sum;
  29.                         float average;
  30.                         float max_ve;
  31.                         int dire;

  32.                         sum = 0.0;
  33.                         dire = 0;
  34.                         max_ve = CV_MAT_ELEM(*mat_mags[0], float, y, x);

  35.                         for (int n=0; n<ZGDIRES; n++)
  36.                         {
  37.                                 float ve = CV_MAT_ELEM(*mat_mags[n], float, y, x);
  38.                                 sum += ve;
  39.                                 if (ve > max_ve)
  40.                                 {
  41.                                         max_ve = ve;
  42.                                         dire = n;
  43.                                 }
  44.                         }

  45.                         average = sum/ZGDIRES;

  46.                         CV_MAT_ELEM(*mat_edge, float, y, x) = 0;
  47.                         CV_MAT_ELEM(*mat_dire, int, y, x) = dire;

  48.                         if (max_ve > 4.0*average) CV_MAT_ELEM(*mat_edge, float, y, x) = 255;
  49.                 }
  50.         }

  51.         ZPoint zpoint;

  52.         for (int y=5; y<img_gray->height-5; y+=2)
  53.         {
  54.                 for (int x=5; x<img_gray->width-5; x+=2)
  55.                 {
  56.                         if (CV_MAT_ELEM(*mat_edge, float, y, x) > 254)
  57.                         {
  58.                                 zpoint.x = x;
  59.                                 zpoint.y = y;

  60.                                 zpoint.dire = CV_MAT_ELEM(*mat_dire, int, y, x);

  61.                                 filter_zpoints.push_back(zpoint);
  62.                         }
  63.                 }
  64.         }

  65.         std::cout << "filter_zpoints.size : " << filter_zpoints.size() << std::endl;

  66.         for (int i=0; i<ZGDIRES; i++)
  67.         {
  68.                 cvReleaseMat(&mat_mags[i]);
  69.         }
检测目标图像:
  1. IplImage *img_gray = cvCreateImage( cvGetSize(img_src), 8, 1 );
  2.         cvCvtColor(img_src, img_gray, CV_BGR2GRAY);

  3.         ZGFeature *p_zg_features = new ZGFeature[img_gray->height*img_gray->width];

  4.         CvMat *mat_edge = cvCreateMat(img_gray->height, img_gray->width, CV_32FC1);
  5.         CvMat *mat_dire = cvCreateMat(img_gray->height, img_gray->width, CV_32SC1);
  6.         CvMat *mat_mask = cvCreateMat(img_gray->height, img_gray->width, CV_32FC1);

  7.         CvMat *mat_mags[ZGDIRES];

  8.         for (int i=0; i<ZGDIRES; i++)
  9.         {
  10.                 mat_mags[i] = cvCreateMat(img_gray->height, img_gray->width, CV_32FC1);
  11.         }

  12.         ZeGabor *gabors[ZGDIRES];

  13.         double Sigma = 2*PI;
  14.         double F = sqrt(2.0);
  15.         double dn = ZGDN;

  16.         for (int n=0; n<ZGDIRES; n++)
  17.         {
  18.                 gabors[n] = new ZeGabor((PI/ZGDIRES)*n, dn, Sigma, F);
  19.         }

  20.         for (int n=0; n<ZGDIRES; n++)
  21.         {
  22.                 gabors[n]->conv_mat_mag(img_gray, mat_mags[n]);
  23.         }

  24.         for (int y=0; y<img_gray->height; y++)
  25.         {
  26.                 for (int x=0; x<img_gray->width; x++)
  27.                 {
  28.                         float sum;
  29.                         float average;
  30.                         float max_ve;
  31.                         int dire;

  32.                         sum = 0.0;
  33.                         dire = 0;
  34.                         max_ve = CV_MAT_ELEM(*mat_mags[0], float, y, x);

  35.                         ZGFeature *p_zg_f = p_zg_features + y*img_gray->width + x;

  36.                         for (int n=0; n<ZGDIRES; n++)
  37.                         {
  38.                                 float ve = CV_MAT_ELEM(*mat_mags[n], float, y, x);

  39.                                 p_zg_f->dire_ves[n] = ve;

  40.                                 sum += ve;
  41.                                 if (ve > max_ve)
  42.                                 {
  43.                                         max_ve = ve;
  44.                                         dire = n;
  45.                                 }
  46.                         }

  47.                         average = sum/ZGDIRES;

  48.                         p_zg_f->ve_average = average;

  49.                         CV_MAT_ELEM(*mat_edge, float, y, x) = 0;
  50.                         CV_MAT_ELEM(*mat_dire, int, y, x) = dire;
  51.                 }
  52.         }

  53.         for (int i=0; i<ZGDIRES; i++)
  54.         {
  55.                 cvReleaseMat(&mat_mags[i]);
  56.         }

  57.         int num_zpoints = filter_zpoints.size();

  58.         ScanPoint scan_point;

  59.         for (int y=0; y<img_gray->height-100; y+=2)
  60.         {
  61.                 for(int x=0; x<img_gray->width-100; x+=2)
  62.                 {
  63.                         int zclass = 0;

  64.                         for (std::vector<ZPoint>::iterator i = filter_zpoints.begin(); i != filter_zpoints.end(); i++)
  65.                         {
  66.                                 int x1 = x + i->x;
  67.                                 int y1 = y + i->y;

  68.                                 ZGFeature *p_zg_f = p_zg_features + y1*img_gray->width + x1;

  69.                                 int num_mask = p_zg_f->num_mask;
  70.                                 int dire = i->dire;

  71.                                 if(p_zg_f->dire_ves[dire] > 2.0*p_zg_f->ve_average)
  72.                                 {
  73.                                        zclass++;
  74.                                 }
  75.                         }

  76.                         if ((float)zclass/(float)num_zpoints > SCANTHRE)
  77.                         {
  78.                                 scan_point.x = x+IMGTW/2;
  79.                                 scan_point.y = y+IMGTH/2;

  80.                                 scan_points.push_back(scan_point);
  81.                         }
  82.                 }

  83.                 std::cout << y << std::endl;
  84.         }
运行截图:


检测结果,目标被蓝圈标识出来了。

    这个方法需要算一组检测图的卷积,这部分计算量比较大,但是如果使用 OpenCL 等并行计算技术应
该可以大大加速,下一步我准备处理目标的大小和方向变化这部分可能还比较简单,然后准备处理立体的目
标,这个可能比较复杂,目前的想法是对一个立体目标的不同角度分别取特征处理,只是这样计算量会比较
大。

                                                                            zhujiang
                                                                           2011.02.23

----------------------------------------------------------------------------------------

    这几天又做了些实验,这个算法效果还不错,对光线变化和局部遮挡也不大敏感,就是速度比较慢,T6670 2.2G CPU 单线程检测一幅 800*600 的图像,旋转范围左右大约各 20 度,缩放 1.0 到 1.5 倍,大约用几十秒。


    这样如果要根据一组不同角度的照片的特征去识别一个立体目标就必须加快处理速度,算法应该还可以改进,再有就是用 OpenCL 等平行处理技术了,这个局部边沿方向特征算法应该是适合并行化的,理论上中高端显卡上的 GPU 跑并行化的算法可以提速几十到几百倍,不过我的 4570 入门级小显卡估计效果有限。 :-)

                                                                            zhujiang
                                                                            2011.3.3

                                                                        

阅读(5591) | 评论(8) | 转发(0) |
给主人留下些什么吧!~~

网络安全服务2011-10-25 09:13:50

zhujiang732011-04-04 13:55:36

Josephine_wang: 请问博主有没有做过边缘检测方面的东西?~也是用matlab实现的?~~~请问有没好的建议?~
gabor 可以做边缘检测,优点是对噪声不太敏感,但是计算量比较大。没用过 matlab 我一般是用 C/C++ 和 OpenCV 。

Josephine_wang2011-04-04 08:59:01

请问博主有没有做过边缘检测方面的东西?~也是用matlab实现的?~~~请问有没好的建议?~

zhujiang732011-04-02 10:35:11

abyssecho: 您好,能否给我一份完整的工程文件,因为毕设继续用,谢谢您啊!真的很着急,我一直没做出来abyssecho@hotmail.com
要拿我这个对付你们教授?这样不好吧。

abyssecho2011-04-02 09:13:46

您好,能否给我一份完整的工程文件,因为毕设继续用,谢谢您啊!真的很着急,我一直没做出来abyssecho@hotmail.com