Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 #ifndef canny_edges_h_DEFINED
00036 #define canny_edges_h_DEFINED
00037 
00038 #include <opencv2/core/core.hpp>
00039 #include <opencv2/imgproc/imgproc.hpp>
00040 #include <opencv2/highgui/highgui.hpp>
00041 #include "abstract_feature.h"
00042 #include <vector>
00043 #include <iostream>
00044 
00045 
00046 
00047 namespace cpl_visual_features
00048 {
00049 class CannyEdges : public AbstractFeature<std::vector<int> >
00050 {
00051  public:
00052   CannyEdges(int num_orientations = 8) : num_orientations_(num_orientations),
00053                                          thresh1_(2100.0), thresh2_(2300.0)
00054   {
00055   }
00056 
00057   virtual void operator()(cv::Mat& patch, cv::Rect& window)
00058   {
00059     cv::Mat patch_bw(patch.size(), CV_8UC1);
00060     cv::Mat edges(patch.size(), CV_8UC1);
00061     cv::Mat edges_dx(patch.size(), CV_64FC1);
00062     cv::Mat edges_dy(patch.size(), CV_64FC1);
00063     cv::Mat orientations(patch.size(), CV_64FC1, 0.0);
00064 
00065     if (patch.channels() == 3)
00066     {
00067       cv::cvtColor(patch, patch_bw, CV_BGR2GRAY);
00068     }
00069     else
00070     {
00071       patch_bw = patch;
00072     }
00073 
00074     cv::Canny(patch_bw, edges, thresh1_, thresh2_, 5);
00075 
00076     
00077     cv::Sobel(edges, edges_dx, edges_dx.depth(), 1, 0, 3);
00078     cv::Sobel(edges, edges_dy, edges_dy.depth(), 0, 1, 3);
00079 
00080     
00081     for(int r = 0; r < orientations.rows; ++r)
00082     {
00083       for(int c = 0; c < orientations.cols; ++c)
00084       {
00085         orientations.at<double>(r,c) = atan2(edges_dy.at<double>(r,c),
00086                                              edges_dx.at<double>(r,c));
00087       }
00088     }
00089 
00090     
00091     std::vector<int> descriptor(num_orientations_, 0);
00092 
00093     for(int r = 0; r < orientations.rows; ++r)
00094     {
00095       for(int c = 0; c < orientations.cols; ++c)
00096       {
00097         
00098         if (edges.at<uchar>(r,c) != 0)
00099         {
00100           
00101           for (int i = 0; i < num_orientations_; i++)
00102           {
00103             if ( (M_PI/num_orientations_*(i+1)) >=
00104                  std::abs(orientations.at<double>(r,c)) )
00105             {
00106               descriptor[i]++;
00107               break;
00108             }
00109           }
00110         }
00111       }
00112     }
00113 
00114     
00115     descriptor_ = descriptor;
00116 
00117 #ifdef CANNY_EDGES_SHOW_IMAGES
00118     
00119     cv::imshow("edges", edges);
00120     cv::imshow("edges_dx", edges_dx);
00121     cv::imshow("edges_dy", edges_dy);
00122     cv::imshow("orientations", orientations);
00123     cv::waitKey();
00124 #endif // CANNY_EDGES_SHOW_IMAGES
00125   }
00126 
00127   virtual std::vector<int> getDescriptor() const
00128   {
00129     return descriptor_;
00130   }
00131 
00132  protected:
00133   std::vector<int> descriptor_;
00134   int num_orientations_;
00135   double thresh1_;
00136   double thresh2_;
00137 };
00138 }
00139 #endif // canny_edges_h_DEFINED