Hello Mat

 找回密码
 立即注册
查看: 7102|回复: 0

Sift尺度不变特征变换(Scale-invariant feature transform)图像特征

[复制链接]

1323

主题

1551

帖子

0

金钱

管理员

Rank: 9Rank: 9Rank: 9

积分
22647
发表于 2017-8-24 23:58:39 | 显示全部楼层 |阅读模式
Sift图像特征
代码下载:http://pan.baidu.com/s/1nu6nBuD

视频链接:
【1】http://pan.baidu.com/s/1o79AkWE
【2】http://pan.baidu.com/s/1eSNDR70
录制的视频是算法底层原理讲解,底层代码实现,方便大家真正掌握算法实质,开发出更加出色的算法。录制视频的初衷是:避免读者朋友利用大把时间学习已有常见算法,本系列视频旨在让读者朋友快速深入了解这些常见算法原理,有更多的时间去研究更加高大上算法(价值)。

具体链接在halcom.cn论坛,联系人QQ:3283892722
该论坛是一个学习交流平台,我会逐一的和大家分享学习。
欢迎大家录制视频,并提交给我,我来设置视频,你可在论坛进行打赏分享。
视频专用播放器:http://halcom.cn/forum.php?mod=viewthread&tid=258&extra=page%3D1

运行环境:win7+32bit+matlab2014a

Step1:构建金字塔模型-对于各组图像而言,不同层采用不同高斯核函数进行滤波模糊化,各组所用sigma相同,具体看SigmaIJ
% 层数为scales+3
  1. function [PytImages, SigmaIJ] = Pyt_Scale( image1, octaves, scales, initialBlurSigma,  kernelSize )
  2. if size(image1,3)>1
  3.     image1 = rgb2gray(image1);
  4. end
  5. image1 = im2double(image1); % double(image1)/double(255.0);
  6. initialDoubleSizeImage = imresize(image1, 2, 'bilinear'); % 放大2倍
  7. % octaves = 4;  % 4组
  8. % scales = 3;   % 每组的层数
  9. totScales = scales + 3;   % 总层数
  10. PytImages = cell( octaves, 1 );      % 初始化金字塔图
  11. SigmaIJ = zeros(octaves, totScales); % 初始化
  12. % initialBlurSigma = 0.5;  % 高斯方差
  13. % kernelSize = 15;         % 基宽
  14. initialSigma = sqrt(2);
  15. for i=1:octaves
  16.     currentSigma = initialBlurSigma;
  17.     for j=1:totScales
  18.         k = (2^(j/scales));
  19.         bluredImage = gaussianBlur(initialDoubleSizeImage,currentSigma,kernelSize);
  20.         PytImages{i}(:, :, :, j) = bluredImage;
  21.         currentSigma = initialSigma*k;
  22.         SigmaIJ(i,j) = currentSigma;
  23.     end
  24.     initialDoubleSizeImage = DownSampling( PytImages{i}(:,:,:,totScales-3) );  % 下采样
  25. end
复制代码
Step2:高斯差分模型,两个高斯模型的差
% 层数为scales+2
  1. function PytImagesDOG = Pyt_DOG( PytImages )
  2. % 高斯差分金字塔
  3. % http://halcom.cn/forum.php?mod=viewthread&tid=855&extra=page%3D1
  4. PytImagesDOG = cell( size(PytImages,1), 1 );
  5. for i=1:size(PytImages,1) % 组数
  6.     PytImage = PytImages{i};
  7.     for j=2:size( PytImage, 4 )
  8.         PytImagesDOG{i}(:,:,:,j-1) = PytImage(:,:,:,j) - PytImage(:,:,:,j-1);
  9.     end
  10. end
复制代码
Step3:计算关键节点
% 层数为scales
(1)计算极大值点和极小值点,判断为keyPoints
(2)排除contrastLimit点(可理解为光溜溜的背景噪点);
(3)排除边缘效应节点(根据二阶差分简化计算得到);
  1. function [keypointsMap, count] = Key_Points( PytImagesDOG )
  2. contrastLimit = 0.03;
  3. isKeypoint = false;
  4. count = 0;
  5. keypointsMap = cell(size(PytImagesDOG,1), size(PytImagesDOG{1},4)-2); % 层数为scales
  6. for i=1:size(PytImagesDOG,1)            % 组数
  7.     for j=2:size(PytImagesDOG{1},4)-1   % 尺度层数
  8.         image = PytImagesDOG{i}(:,:,:,j);  % 高斯滤波模糊图像
  9.         keypointsMap{i, j-1} = zeros( size(image,1), size(image,2) );
  10.         for row = 2:size(image,1)-1
  11.             for column = 2:size(image,2)-1
  12.                 isKeypoint = false;
  13.                 % 极大值点比较
  14.                 if PytImagesDOG{i}(row,column,1,j) > PytImagesDOG{i}(row-1,column,1,j) && ...
  15.                         PytImagesDOG{i}(row,column,1,j) > PytImagesDOG{i}(row-1,column-1,1,j) && ...
  16.                         PytImagesDOG{i}(row,column,1,j) > PytImagesDOG{i}(row,column-1,1,j) && ...
  17.                         PytImagesDOG{i}(row,column,1,j) > PytImagesDOG{i}(row+1,column-1,1,j) && ...
  18.                         PytImagesDOG{i}(row,column,1,j) > PytImagesDOG{i}(row+1,column,1,j) && ...
  19.                         PytImagesDOG{i}(row,column,1,j) > PytImagesDOG{i}(row+1,column+1,1,j) && ...
  20.                         PytImagesDOG{i}(row,column,1,j) > PytImagesDOG{i}(row,column+1,1,j) && ...
  21.                         PytImagesDOG{i}(row,column,1,j) > PytImagesDOG{i}(row-1,column+1,1,j) && ...
  22.                         PytImagesDOG{i}(row,column,1,j) > PytImagesDOG{i}(row-1,column,1,j-1) && ...
  23.                         PytImagesDOG{i}(row,column,1,j) > PytImagesDOG{i}(row-1,column-1,1,j-1) && ...
  24.                         PytImagesDOG{i}(row,column,1,j) > PytImagesDOG{i}(row,column-1,1,j-1) && ...
  25.                         PytImagesDOG{i}(row,column,1,j) > PytImagesDOG{i}(row+1,column-1,1,j-1) && ...
  26.                         PytImagesDOG{i}(row,column,1,j) > PytImagesDOG{i}(row+1,column,1,j-1) && ...
  27.                         PytImagesDOG{i}(row,column,1,j) > PytImagesDOG{i}(row+1,column+1,1,j-1) && ...
  28.                         PytImagesDOG{i}(row,column,1,j) > PytImagesDOG{i}(row,column+1,1,j-1) && ...
  29.                         PytImagesDOG{i}(row,column,1,j) > PytImagesDOG{i}(row-1,column+1,1,j-1) && ...
  30.                         PytImagesDOG{i}(row,column,1,j) > PytImagesDOG{i}(row,column,1,j-1) && ...
  31.                         PytImagesDOG{i}(row,column,1,j) > PytImagesDOG{i}(row-1,column,1,j+1) && ...
  32.                         PytImagesDOG{i}(row,column,1,j) > PytImagesDOG{i}(row-1,column-1,1,j+1) && ...
  33.                         PytImagesDOG{i}(row,column,1,j) > PytImagesDOG{i}(row,column-1,1,j+1) && ...
  34.                         PytImagesDOG{i}(row,column,1,j) > PytImagesDOG{i}(row+1,column-1,1,j+1) && ...
  35.                         PytImagesDOG{i}(row,column,1,j) > PytImagesDOG{i}(row+1,column,1,j+1) && ...
  36.                         PytImagesDOG{i}(row,column,1,j) > PytImagesDOG{i}(row+1,column+1,1,j+1) && ...
  37.                         PytImagesDOG{i}(row,column,1,j) > PytImagesDOG{i}(row,column+1,1,j+1) && ...
  38.                         PytImagesDOG{i}(row,column,1,j) > PytImagesDOG{i}(row-1,column+1,1,j+1) && ...
  39.                         PytImagesDOG{i}(row,column,1,j) > PytImagesDOG{i}(row,column,1,j+1)
  40.                     if(keypointsMap{i,j-1}(row,column) == 0)
  41.                         keypointsMap{i,j-1}(row,column) = 1;   % 关键特征点
  42.                         count = count + 1;
  43.                         isKeypoint = true;
  44.                     end
  45.                 end
  46.                
  47.                 % 极小值点
  48.                 if PytImagesDOG{i}(row,column,1,j) < PytImagesDOG{i}(row-1,column,1,j) && ...
  49.                         PytImagesDOG{i}(row,column,1,j) < PytImagesDOG{i}(row-1,column-1,1,j) && ...
  50.                         PytImagesDOG{i}(row,column,1,j) < PytImagesDOG{i}(row,column-1,1,j) && ...
  51.                         PytImagesDOG{i}(row,column,1,j) < PytImagesDOG{i}(row+1,column-1,1,j) && ...
  52.                         PytImagesDOG{i}(row,column,1,j) < PytImagesDOG{i}(row+1,column,1,j) && ...
  53.                         PytImagesDOG{i}(row,column,1,j) < PytImagesDOG{i}(row+1,column+1,1,j) && ...
  54.                         PytImagesDOG{i}(row,column,1,j) < PytImagesDOG{i}(row,column+1,1,j) && ...
  55.                         PytImagesDOG{i}(row,column,1,j) < PytImagesDOG{i}(row-1,column+1,1,j) && ...
  56.                         PytImagesDOG{i}(row,column,1,j) < PytImagesDOG{i}(row-1,column,1,j-1) && ...
  57.                         PytImagesDOG{i}(row,column,1,j) < PytImagesDOG{i}(row-1,column-1,1,j-1) && ...
  58.                         PytImagesDOG{i}(row,column,1,j) < PytImagesDOG{i}(row,column-1,1,j-1) && ...
  59.                         PytImagesDOG{i}(row,column,1,j) < PytImagesDOG{i}(row+1,column-1,1,j-1) && ...
  60.                         PytImagesDOG{i}(row,column,1,j) < PytImagesDOG{i}(row+1,column,1,j-1) && ...
  61.                         PytImagesDOG{i}(row,column,1,j) < PytImagesDOG{i}(row+1,column+1,1,j-1) && ...
  62.                         PytImagesDOG{i}(row,column,1,j) < PytImagesDOG{i}(row,column+1,1,j-1) && ...
  63.                         PytImagesDOG{i}(row,column,1,j) < PytImagesDOG{i}(row-1,column+1,1,j-1) && ...
  64.                         PytImagesDOG{i}(row,column,1,j) < PytImagesDOG{i}(row,column,1,j-1) && ...
  65.                         PytImagesDOG{i}(row,column,1,j) < PytImagesDOG{i}(row-1,column,1,j+1) && ...
  66.                         PytImagesDOG{i}(row,column,1,j) < PytImagesDOG{i}(row-1,column-1,1,j+1) && ...
  67.                         PytImagesDOG{i}(row,column,1,j) < PytImagesDOG{i}(row,column-1,1,j+1) && ...
  68.                         PytImagesDOG{i}(row,column,1,j) < PytImagesDOG{i}(row+1,column-1,1,j+1) && ...
  69.                         PytImagesDOG{i}(row,column,1,j) < PytImagesDOG{i}(row+1,column,1,j+1) && ...
  70.                         PytImagesDOG{i}(row,column,1,j) < PytImagesDOG{i}(row+1,column+1,1,j+1) && ...
  71.                         PytImagesDOG{i}(row,column,1,j) < PytImagesDOG{i}(row,column+1,1,j+1) && ...
  72.                         PytImagesDOG{i}(row,column,1,j) < PytImagesDOG{i}(row-1,column+1,1,j+1) && ...
  73.                         PytImagesDOG{i}(row,column,1,j) < PytImagesDOG{i}(row,column,1,j+1)
  74.                     if(keypointsMap{i,j-1}(row,column) == 0)
  75.                         keypointsMap{i,j-1}(row,column) = 1;   % 关键特征点
  76.                         count = count + 1;
  77.                         isKeypoint = true;
  78.                     end
  79.                 end
  80.                
  81.                 if isKeypoint==true
  82.                     if(abs(PytImagesDOG{i}(row,column,1,j))<contrastLimit)
  83.                         keypointsMap{i,j-1}(row,column) = 0;   % 不是关键特征点
  84.                         isKeypoint = false;
  85.                         count = count - 1;
  86.                     end
  87.                 end
  88.                
  89.                 % 排除边缘效应点
  90.                 if isKeypoint==true
  91.                     % 差分
  92.                     DerivativeYY = (PytImagesDOG{i}(row-1,column,1,j) + ...
  93.                         PytImagesDOG{i}(row+1, column, 1, j) - ...
  94.                         2.0*PytImagesDOG{i}(row, column, 1, j));
  95.                     DerivativeXX = (PytImagesDOG{i}(row,column-1,1,j) + ...
  96.                         PytImagesDOG{i}(row, column+1, 1, j) - ...
  97.                         2.0*PytImagesDOG{i}(row, column, 1, j));
  98.                     DerivativeXY = (PytImagesDOG{i}(row-1,column-1,1,j) + ...
  99.                         PytImagesDOG{i}(row+1,column+1,1,j) - ...
  100.                         PytImagesDOG{i}(row+1, column-1, 1, j) - ...
  101.                         PytImagesDOG{i}(row-1, column+1, 1, j))/4;
  102.                     trTerm = DerivativeXX + DerivativeYY;
  103.                     DeterminantH = DerivativeXX * DerivativeYY - DerivativeXY*DerivativeXY;
  104.   
  105.                     ratio = (trTerm*trTerm)/DeterminantH;
  106.                     threshold = ((5+1)^2)/5;
  107.                     if(ratio>=threshold || DeterminantH<0)
  108.                         keypointsMap{i,j-1}(row,column) = 0;      % 不是关键特征点
  109.                         isKeypoint = false;
  110.                         count = count -1;
  111.                     end
  112.                 end
  113.                
  114.                
  115.             end
  116.         end
  117.         
  118.     end
  119. end
复制代码
Step4:关键点定位---相位信息
(1)求解每一层金字塔图像的幅值和相位;
(2)提取每一层金字塔图像的关键特征点,对每一个关键特征点进行15x15大小的掩膜计算;
(3)对15x15的掩膜,计算HoG统计直方图(可等价为HoG理解);
(4)求解直方图的极值点,以及对应的角度值;
  1. function [orientationDescriptor, MagPhase] = Phase_Hist(PytImages, keypointDescriptor, SigmaIJ)
  2. % 关键节点特征求解(相位角)
  3. MagPhase = cell( size( keypointDescriptor,1 ), size( keypointDescriptor,2 ), 2 );
  4. for i=1:size( keypointDescriptor,1 )      % 组数
  5.     for j=1:size( keypointDescriptor,2 )  % 组内层数
  6.         % X方向滤波
  7.         filterDiffX = [0 0 0; -1 0 1; 0 0 0];
  8.         diffXMat = imfilter(PytImages{i}(:,:,1,j), filterDiffX);
  9.         % Y方向滤波
  10.         filterDiffY = [0 1 0; 0 0 0; 0 -1 0];
  11.         diffYMat = imfilter(PytImages{i}(:,:,1,j), filterDiffY);
  12.         % 幅值
  13.         magnMat = sqrt(diffXMat.*diffXMat + diffYMat.*diffYMat);
  14.         % 相位
  15.         orientMat = atan2(diffYMat, diffXMat);
  16.         
  17.         %store magnitude and orientation, so they can be used later on
  18.         MagPhase{i}{j}{1} = magnMat;
  19.         MagPhase{i}{j}{2} = orientMat;
  20.     end
  21. end

  22. orientationDescriptor = cell(size(keypointDescriptor, 1),size(keypointDescriptor,2));
  23. hist = zeros(36,1);
  24. cant = 0;
  25. for i=1:size( keypointDescriptor,1 )      % 组数
  26.     for j=1:size( keypointDescriptor,2 )  % 组内层数
  27.         [rowKpt, colKpt] = find(keypointDescriptor{i, j} == 1); % 找出全部的关键特征点
  28.         % 高斯核函数
  29.         accumSigma = SigmaIJ(i, j)*1.5;
  30.         weightKernel = fspecial('gaussian',[round(accumSigma*6-1), round(accumSigma*6-1)], accumSigma);
  31.         knlHeight = size(weightKernel,1);
  32.         knlWidth = size(weightKernel,2);
  33. %         % 图像宽、高
  34. %         winHeight = size(MagPhase{i}{j}{1}, 1);
  35. %         winWidth = size(MagPhase{i}{j}{1}, 2);
  36.         for keypoint = 1: length( rowKpt )
  37.             xfrom = round(colKpt(keypoint)-knlWidth/2);
  38.             xto = round(colKpt(keypoint)+knlWidth/2-1);
  39.             
  40.             yfrom = round(rowKpt(keypoint)-knlHeight/2);
  41.             yto = round(rowKpt(keypoint)+knlHeight/2-1);
  42.             
  43.             truncXKnlLeft = 0;
  44.             truncXKnlRight = 0;
  45.             truncYKnlTop = 0;
  46.             truncYKnlBottom = 0;
  47.             
  48.             % 可能此处需要对truncXKnlLeft、truncXKnlRight、truncYKnlTop、truncYKnlBottom、
  49.             % xfrom、xto、yfrom、yto进行判断,防止越界
  50.             weightKernelEval = weightKernel((1+truncYKnlTop):(size(weightKernel,1)-truncYKnlBottom),  ...
  51.                 (1+truncXKnlLeft):(size(weightKernel,2)-truncXKnlRight));
  52.             weightKernelEval = weightKernelEval./max(max( weightKernelEval ));
  53.             
  54.             cant=cant+1;
  55.             magnitudes = MagPhase{i}{j}{1}(yfrom:yto,xfrom:xto);
  56.             magnitudes = weightKernelEval.*magnitudes;   % 幅值给出权重,联合DPM可变部件算法进行理解
  57.             orientations = MagPhase{i}{j}{2}(yfrom:yto,xfrom:xto);
  58.             orientations = (orientations.*180)./pi;      % 转为角度
  59.             
  60.             % 角度区间统计计算(可对比HOG算法进行理解)
  61.             for bucket=1:36
  62.                 bucketRangeFrom = (bucket-19)*10;
  63.                 bucketRangeTo = (bucket-18)*10;
  64.                 [rowOr, colOr] = find(orientations<bucketRangeTo & orientations>=bucketRangeFrom);
  65.                 for rc = 1:length( rowOr )
  66.                     hist(bucket) = hist(bucket) + magnitudes( rowOr(rc), colOr(rc) );
  67.                 end
  68.             end
  69.             
  70.             % 基于hist,找出hist里面最大的N个值所对应的下标
  71.             % 关键点的精确定位,插值算法
  72.             posMaxHist = find(hist==max(hist));
  73.             posOtherHist = find(hist>(max(hist)-max(hist)*0.2)&hist~=hist(posMaxHist(1)));
  74.             posAllHist = zeros(1,1);
  75.             if(size(posOtherHist,1)>0)
  76.                 posAllHist = cat(2,posMaxHist,posOtherHist.');   % 合并操作
  77.                 %                 posAllHist = 【posAllHist, posOtherHist】  % 等价操作
  78.             else
  79.                 posAllHist = posMaxHist;
  80.             end
  81.             interpolatedOrientations = zeros(size(posAllHist,1),1);
  82.             for currentBestHist = 1:size(posAllHist, 2)
  83.                 posHist = posAllHist(currentBestHist);
  84.                 x1 = posHist-1;
  85.                 x2 = posHist;
  86.                 x3 = posHist+1;
  87.                
  88.                 y1 = 0;
  89.                 y2 = hist(x2);
  90.                 y3 = 0;
  91.                
  92.                 %in order not to lose the topology
  93.                 if(x1<1)
  94.                     y1 = hist(36);
  95.                 else
  96.                     y1 = hist(x1);
  97.                 end
  98.                
  99.                 if(x3>36)
  100.                     y3 = hist(1);
  101.                 else
  102.                     y3 = hist(x3);
  103.                 end
  104.                
  105.                 valsX = [x1-0.5 x2-0.5 x3-0.5];
  106.                 %                    valsX = [x1 x2 x3];
  107.                 valsY = [y1 y2 y3];
  108.                
  109.                 pars = polyfit(valsX,valsY,2);  % 二次抛物线插值
  110.                
  111.                 %result of derivative = 0 to see where is the parabolic maxima
  112.                 xMax = (pars(2)*(-1))/(2*pars(1));
  113.                 if(xMax<0)
  114.                     xMax = 36+xMax;
  115.                 end
  116.                 if(xMax>36)
  117.                     xMax = xMax-36;
  118.                 end
  119.                
  120.                 % convert to degrees, Hist是10度一个区间
  121.                 xMax = xMax * 10;
  122.                 interpolatedOrientations(currentBestHist) = xMax;
  123.             end
  124.             
  125.             % creates the structure with the data
  126.             histDescriptor = struct('octave', i, ...
  127.                 'layer', j, ...
  128.                 'position',[rowKpt(keypoint) colKpt(keypoint)], ...
  129.                 'histogram', hist, ...
  130.                 'bestHist', posAllHist.', ...
  131.                 'interpOrien', interpolatedOrientations.', ...
  132.                 'theBestHist', posMaxHist);
  133.             orientationDescriptor{i}{j}(rowKpt(keypoint),colKpt(keypoint)) = histDescriptor;
  134.             
  135.         end
  136.         
  137.     end
  138. end
复制代码

Step5:关键点特征
(1)获取关键特征点、金字塔图像幅值、相位图等信息;
(2)将金字塔图像关键特征点旋转变换,在此利用了旋转矩阵,旋转角为Step4中的特征直方图最大极值对应的角度值,具体看代码注释;
(3)以变换后的关键特征点,进行Block块分析,主要为(幅值图像)权值叠加过程(可结合DPM算法进行理解);
(4)对关键点特征进行归一化处理,截断归一化处理;
  1. function kptDescriptors = siftDescriptors( keypointDescriptor, keypointsCount, orientationDescriptor, MagPhase)
  2. % 特征求解
  3. BlockSize = 16;  % 特征窗口大小
  4. % keypointDescriptor = keypointsMap;
  5. kptDescriptors = repmat(struct('octave',0,'kptLayer',0,'kptDescriptor',zeros(4,4,8), ...
  6.     'kptX',0,'kptY',0),keypointsCount,1);
  7. cont = 0;
  8. for i=1:size( keypointDescriptor,1 )      % 组数
  9.     for j=1:size( keypointDescriptor,2 )  % 组内层数
  10.         [rowKpt, colKpt] = find(keypointDescriptor{i, j} == 1); % 找出全部的关键特征点
  11.         if(size(rowKpt,1)==0)
  12.             continue;
  13.         end
  14.         % 取出关键特征点、图像幅值和相位角
  15.         keypointData = orientationDescriptor{i}{j};
  16.         magnitudes = MagPhase{i}{j}{1};
  17.         orientations = MagPhase{i}{j}{2};
  18.         
  19.         for keypoint = 1: length( rowKpt )
  20.             keypointDetail = keypointData(rowKpt(keypoint),colKpt(keypoint));
  21.             for orient = 1:size(keypointDetail.bestHist,1)
  22.                 kptDescriptor = zeros(128,1);  % 初始化
  23.                 cont = cont+1;
  24.                
  25.                 % 旋转操作,以关键节点为圆心
  26.                 row = rowKpt(keypoint);
  27.                 col = colKpt(keypoint);
  28.                 degrees = keypointDetail.interpOrien(orient);
  29.                 rotAngle = 360 - degrees;  % 旋转角
  30.                 v=[row, col]';  % 关键节点坐标
  31.                 c=[size(magnitudes,1)/2, size(magnitudes,2)/2]' ;  % 旋转中心
  32.                 % 旋转图像
  33.                 rotMagnitudes= imrotate(magnitudes,rotAngle);
  34.                 rotOrientations= imrotate(orientations,rotAngle);
  35.                 % 旋转矩阵
  36.                 RM=[cosd(rotAngle) -sind(rotAngle)
  37.                     sind(rotAngle) cosd(rotAngle)];
  38.                 temp_v = RM*(v-c);  % 向量旋转
  39.                 rot_v = temp_v+c;   % 迭加到中心点坐标上,旋转后的新的原图(尺寸不变的理论原图)关键坐标点
  40.                 % 旋转后,rotMagnitudes图像尺寸变化
  41.                 difmat = [(size(rotMagnitudes,1) - size(magnitudes,1))/2, (size(rotMagnitudes,2) - size(magnitudes,2))/2]';
  42.                 rot_v2 = rot_v + difmat;  % 拉伸后的坐标
  43.                 % 新的关键点坐标
  44.                 rotRow = rot_v2(1);
  45.                 rotCol = rot_v2(2);
  46.                
  47.                 gaussWeight = getGaussWeights(BlockSize, BlockSize/2);  % 高斯核函数
  48.                 % 以新的关键点坐标为圆心,构建新的Block块,计算特征(可结合HOG算法进行理解)
  49.                 for x = 0:BlockSize-1
  50.                     for y = 0:BlockSize-1
  51.                         subregAxisX = floor(x/4);
  52.                         subregAxisY = floor(y/4);
  53.                         yCoord = rotRow + y - BlockSize/2;
  54.                         xCoord = rotCol + x - BlockSize/2;
  55.                         yCoord = round(yCoord);
  56.                         xCoord = round(xCoord);
  57.                         % get the magnitude
  58.                         if(yCoord>0&&xCoord>0 && yCoord<=size(rotMagnitudes,1) && xCoord<=size(rotMagnitudes,2))
  59.                             magn = rotMagnitudes(yCoord,xCoord);
  60.                             magn = magn*gaussWeight(y+1,x+1);
  61.                             orientation = rotOrientations(yCoord,xCoord);
  62.                             orientation = orientation + pi;
  63.                             bucket = (orientation)*(180/pi);
  64.                             bucket = ceil(bucket/45);
  65.                             kptDescriptor((subregAxisY*4+subregAxisX)*8 + bucket) = ...
  66.                                 kptDescriptor((subregAxisY*4+subregAxisX)*8 + bucket) + magn;
  67.                         end
  68.                     end
  69.                 end
  70.                
  71.                 % 归一化操作
  72.                 sqKptDescriptor = kptDescriptor.^2;
  73.                 kptDescriptor = kptDescriptor./sqrt( sum(sqKptDescriptor) );
  74.                 % 截断阈值分析
  75.                 kptDescriptor(find(kptDescriptor>0.2))=0.2;
  76.                 % 归一化操作
  77.                 sqKptDescriptor = kptDescriptor.^2;
  78.                 kptDescriptor = kptDescriptor./sqrt( sum(sqKptDescriptor) );
  79.                
  80.                 kptDescriptors(cont) = struct('octave',i,'kptLayer',j, ...
  81.                     'kptDescriptor',kptDescriptor, ...
  82.                     'kptX',colKpt(keypoint),'kptY',rowKpt(keypoint));
  83.             end
  84.             
  85.         end
  86.         
  87.     end
  88. end
复制代码




参考:http://www.360doc.com/content/14/1013/15/18306241_416576994.shtml













本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
算法QQ  3283892722
群智能算法链接http://halcom.cn/forum.php?mod=forumdisplay&fid=73
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Python|Opencv|MATLAB|Halcom.cn ( 蜀ICP备16027072号 )

GMT+8, 2024-11-22 22:48 , Processed in 0.239678 second(s), 25 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表