Skip to content

Instantly share code, notes, and snippets.

@eudoxos
Last active March 22, 2019 13:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eudoxos/b88f36e27eb782c6c60f25481c642aaf to your computer and use it in GitHub Desktop.
Save eudoxos/b88f36e27eb782c6c60f25481c642aaf to your computer and use it in GitHub Desktop.
sobel gradient filter kernel (along X), integral and floating-point (c++17, Eigen)
#include<Eigen/Core>
#include<iostream>
#include<numeric>
// based on and verified with https://stackoverflow.com/a/46262628/761090
// works for size 11 with int and 15 with long int (on amd64)
template<typename Int>
std::tuple<Eigen::Matrix<Int,Eigen::Dynamic,Eigen::Dynamic>,Int> sobelGradFilterX_int(int sz){
assert(sz>0);
assert(sz%2==1);
Int sz2=sz/2;
Int denom=1;
for(Int i=0; i<=sz2; i++){
for(Int j=0; j<=sz2; j++){
Int d=(Int)(i*i+j*j);
if(d==0) continue;
denom=std::lcm(denom,d/std::gcd(d,i));
}
}
Eigen::Matrix<Int,Eigen::Dynamic,Eigen::Dynamic> ret; ret.setZero(sz,sz);
Int ww=0;
for(int i0=0; i0<sz; i0++){
for(int j0=0; j0<sz; j0++){
int i=i0-sz2, j=j0-sz2;
Int d=(Int)(i*i+j*j);
if(i==0) continue;
assert((denom*i)%d==0);
Int w=denom*i/d;
ww+=i*w;
ret(j0,i0)=w;
}
}
return std::make_tuple(ret,ww);
}
template<typename Scalar>
Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic> sobelGradFilterX(int sz){
assert(sz>0);
assert(sz%2==1);
int sz2=sz/2;
int denom=1;
for(int i=0; i<=sz2; i++){
for(int j=0; j<=sz2; j++){
int d=(int)(i*i+j*j);
if(d==0) continue;
denom=std::lcm(denom,d/std::gcd(d,i));
}
}
Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic> ret; ret.setZero(sz,sz);
Scalar ww=0;
for(int i0=0; i0<sz; i0++){
for(int j0=0; j0<sz; j0++){
int i=i0-sz2, j=j0-sz2;
Scalar d=i*i+j*j;
if(i==0) continue;
Scalar w=denom*i*1./d;
ww+=i*w;
ret(j0,i0)=i*1./d;
}
}
return denom*ret/ww;
}
int main(void){
auto [K,w]=sobelGradFilterX_int<int>(11);
std::cerr<<K<<std::endl<<w<<std::endl;
auto K2=sobelGradFilterX<double>(13);
std::cerr<<K2<<std::endl;
}
@eudoxos
Copy link
Author

eudoxos commented Mar 22, 2019

Example output from g++ mat2.cc -std=c++17 -Wall -O3 -o mat2 -I/usr/include/eigen3 && ./mat2

 -15766140  -15381600  -13911300  -10873200   -6063900          0    6063900   10873200   13911300   15381600   15766140
 -19227000  -19707675  -18919368  -15766140   -9274200          0    9274200   15766140   18919368   19707675   19227000
 -23185500  -25225824  -26276900  -24255600  -15766140          0   15766140   24255600   26276900   25225824   23185500
 -27183000  -31532280  -36383400  -39415350  -31532280          0   31532280   39415350   36383400   31532280   27183000
 -30319500  -37096800  -47298420  -63064560  -78830700          0   78830700   63064560   47298420   37096800   30319500
 -31532280  -39415350  -52553800  -78830700 -157661400          0  157661400   78830700   52553800   39415350   31532280
 -30319500  -37096800  -47298420  -63064560  -78830700          0   78830700   63064560   47298420   37096800   30319500
 -27183000  -31532280  -36383400  -39415350  -31532280          0   31532280   39415350   36383400   31532280   27183000
 -23185500  -25225824  -26276900  -24255600  -15766140          0   15766140   24255600   26276900   25225824   23185500
 -19227000  -19707675  -18919368  -15766140   -9274200          0    9274200   15766140   18919368   19707675   19227000
 -15766140  -15381600  -13911300  -10873200   -6063900          0    6063900   10873200   13911300   15381600   15766140

869749408

 -1.0365e-11  -1.0195e-11 -9.56765e-12 -8.29196e-12 -6.21897e-12 -3.36161e-12            0  3.36161e-12  6.21897e-12  8.29196e-12  9.56765e-12   1.0195e-11   1.0365e-11
 -1.2234e-11 -1.24379e-11 -1.21346e-11 -1.09747e-11 -8.57789e-12 -4.78382e-12            0  4.78382e-12  8.57789e-12  1.09747e-11  1.21346e-11  1.24379e-11   1.2234e-11
-1.43515e-11 -1.51682e-11 -1.55474e-11 -1.49255e-11 -1.24379e-11 -7.31644e-12            0  7.31644e-12  1.24379e-11  1.49255e-11  1.55474e-11  1.51682e-11  1.43515e-11
-1.65839e-11 -1.82911e-11 -1.99007e-11 -2.07299e-11 -1.91353e-11 -1.24379e-11            0  1.24379e-11  1.91353e-11  2.07299e-11  1.99007e-11  1.82911e-11  1.65839e-11
-1.86569e-11 -2.14447e-11 -2.48759e-11 -2.87029e-11 -3.10949e-11 -2.48759e-11            0  2.48759e-11  3.10949e-11  2.87029e-11  2.48759e-11  2.14447e-11  1.86569e-11
-2.01696e-11 -2.39191e-11 -2.92657e-11 -3.73138e-11 -4.97518e-11 -6.21897e-11            0  6.21897e-11  4.97518e-11  3.73138e-11  2.92657e-11  2.39191e-11  2.01696e-11
-2.07299e-11 -2.48759e-11 -3.10949e-11 -4.14598e-11 -6.21897e-11 -1.24379e-10            0  1.24379e-10  6.21897e-11  4.14598e-11  3.10949e-11  2.48759e-11  2.07299e-11
-2.01696e-11 -2.39191e-11 -2.92657e-11 -3.73138e-11 -4.97518e-11 -6.21897e-11            0  6.21897e-11  4.97518e-11  3.73138e-11  2.92657e-11  2.39191e-11  2.01696e-11
-1.86569e-11 -2.14447e-11 -2.48759e-11 -2.87029e-11 -3.10949e-11 -2.48759e-11            0  2.48759e-11  3.10949e-11  2.87029e-11  2.48759e-11  2.14447e-11  1.86569e-11
-1.65839e-11 -1.82911e-11 -1.99007e-11 -2.07299e-11 -1.91353e-11 -1.24379e-11            0  1.24379e-11  1.91353e-11  2.07299e-11  1.99007e-11  1.82911e-11  1.65839e-11
-1.43515e-11 -1.51682e-11 -1.55474e-11 -1.49255e-11 -1.24379e-11 -7.31644e-12            0  7.31644e-12  1.24379e-11  1.49255e-11  1.55474e-11  1.51682e-11  1.43515e-11
 -1.2234e-11 -1.24379e-11 -1.21346e-11 -1.09747e-11 -8.57789e-12 -4.78382e-12            0  4.78382e-12  8.57789e-12  1.09747e-11  1.21346e-11  1.24379e-11   1.2234e-11
 -1.0365e-11  -1.0195e-11 -9.56765e-12 -8.29196e-12 -6.21897e-12 -3.36161e-12            0  3.36161e-12  6.21897e-12  8.29196e-12  9.56765e-12   1.0195e-11   1.0365e-11

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment