title: Opencv - how does the filter2D() method actually work?
body: <p>I did look for the source code to Filter2D but could not find it.  Neither could Visual c++.
  Are there any experts on the filter2D algorithm here? I know <a href="http://docs.opencv.org/modules/imgproc/doc/filtering.html#filter2d" rel="noreferrer">how it's supposed to work</a> but not how it actually works. I made my own filter2d() function to test things, and the results are substantially different from opencvs filter2D(). Here's my code:</p>
  
  <pre><code>Mat myfilter2d(Mat input, Mat filter){
  
  Mat dst = input.clone();
  cout &lt;&lt; " filter data successfully found.  Rows:" &lt;&lt; filter.rows &lt;&lt; " cols:" &lt;&lt; filter.cols &lt;&lt; " channels:" &lt;&lt; filter.channels() &lt;&lt; "\n";
  cout &lt;&lt; " input data successfully found.  Rows:" &lt;&lt; input.rows &lt;&lt; " cols:" &lt;&lt; input.cols &lt;&lt; " channels:" &lt;&lt; input.channels() &lt;&lt; "\n";
  
  for (int i = 0-(filter.rows/2);i&lt;input.rows-(filter.rows/2);i++){
      for (int j = 0-(filter.cols/2);j&lt;input.cols-(filter.cols/2);j++){  //adding k and l to i and j will make up the difference and allow us to process the whole image
          float filtertotal = 0;
          for (int k = 0; k &lt; filter.rows;k++){
              for (int l = 0; l &lt; filter.rows;l++){
                  if(i+k &gt;= 0 &amp;&amp; i+k &lt; input.rows &amp;&amp; j+l &gt;= 0 &amp;&amp; j+l &lt; input.cols){  //don't try to process pixels off the endge of the map
                      float a = input.at&lt;uchar&gt;(i+k,j+l);
                      float b = filter.at&lt;float&gt;(k,l);
                      float product = a * b;
                      filtertotal += product;
                  }
              }
          }
          //filter all proccessed for this pixel, write it to dst
          st.at&lt;uchar&gt;(i+(filter.rows/2),j+(filter.cols/2)) = filtertotal;
  
      }
  }
  return dst;
  }
  </code></pre>
  
  <p>Anybody see anything wrong with my implementation?  (besides being slow)</p>
  
  <p>Here is my execution:</p>
  
  <pre><code>  cvtColor(src,src_grey,CV_BGR2GRAY);
    Mat dst = myfilter2d(src_grey,filter);
    imshow("myfilter2d",dst);
    filter2D(src_grey,dst2,-1,filter);
    imshow("filter2d",dst2);
  </code></pre>
  
  <p>Here is my kernel:</p>
  
  <pre><code>float megapixelarray[basesize][basesize] = {
              {1,1,-1,1,1},
              {1,1,-1,1,1},
              {1,1,1,1,1},
              {1,1,-1,1,1},
              {1,1,-1,1,1}
              };
  </code></pre>
  
  <p>And <a href="http://screencast.com/t/0PGEtbDHxse" rel="noreferrer">here are the (substantially different) results:</a></p>
  
  <p>Thoughts, anyone?</p>
  
  <p>EDIT:  Thanks to Brians answer I added this code:</p>
  
  <pre><code>//normalize the kernel so its sum = 1
  Scalar mysum = sum(dst);
  dst = dst / mysum[0];   //make sure its not 0
  dst = dst * -1;  //show negetive
  </code></pre>
  
  <p>and filter2d worked better.  Certain filters give an exact match, and other filters, like the Sobel, <a href="http://screencast.com/t/qwQviq7sfQZM" rel="noreferrer">fail miserably.</a></p>
  
  <p>I'm getting close to the actual algorithm, but not there yet.  Anyone else with any ideas?</p>