due reason, have write filter function myself. following convolution function.
void convolve (cv::mat& f, cv::mat& w, cv::mat& output) { output = f.clone(); int height = f.rows; int width = f.cols; int = (w.rows - 1) / 2; int b = (w.cols- 1) / 2; cv::mat f2 = f.clone(); (int x = a; x < height - a; ++x) { (int y = b; y < width - b; ++y) { float sum = 0.0; (int s = -a; s <= a; ++s) { (int t = -b; t <= b; ++t) { sum += w.at<float>(s+a, t+b) * f2.at<float>(x+s, y+t); } } output.at<float>(x, y) = sum; } } }
then compare using function , cv::filter2d function, , discover different after filtering. filtered image same when theta , psi 0 not others.
int main() { cv::mat in = cv::imread("something.jpg", 0); cv::mat dest, dest1; cv::mat src_f; in.convertto(src_f, cv_32f); int kernel_size = 31; double sig = 1.0, th = 0.2, lm = 1.0, gm = 0.02, ps = 0.0; cv::mat kernel = cv::getgaborkernel(cv::size(kernel_size,kernel_size), sig, th, lm, gm, ps); cv::filter2d(src_f, dest1, cv_32f, kernel); convolve(src_f, kernel, dest); cv::mat viz; dest.convertto(viz, cv_8u, 1.0/255.0); cv::mat viz1; dest1.convertto(viz1, cv_8u, 1.0/255.0); imshow("my dest", viz); imshow("k dest", viz1); cv::waitkey(); }
any suggestion self-contained convolution ? 0 padding part ignored.
you access kernel in convolution implementations matrix of floats, composed of doubles (ksize
set cv_64f
default, according doc). looks opencv smart enough detect , perform conversion/correct memory access during convolution of matrices different element types, that's why produces correct results.
in order fix snippet added line
kernel.convertto(kernel, cv_32f);
this produces visually equivalent result (up padding).
another option explicitly set ktype
cv_32f
.
also, when working big kernels (~11x11 , larger) opencv's filter2d
implementation performs convolution using dft-based algorithm (in frequency domain), may different results , timings.
Comments
Post a Comment