本文介绍了OpenCV:高效的高斯差分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试实施(DoG),针对特定案例边缘检测。正如算法的名称所暗示的那样,它实际上相当简单:

I am trying to implement difference of guassians (DoG), for a specific case of edge detection. As the name of the algorithm suggests, it is actually fairly straightforward:

Mat g1, g2, result;
Mat img = imread("test.png", CV_LOAD_IMAGE_COLOR); 
GaussianBlur(img, g1, Size(1,1), 0);
GaussianBlur(img, g2, Size(3,3), 0);
result = g1 - g2;

但是,我觉得这可以更有效地完成。是否可以通过较少的数据传递来完成?

However, I have the feeling that this can be done more efficiently. Can it perhaps be done in less passes over the data?

教会了我关于可分离过滤器的知识,但在这种情况下,我太了解了如何应用它们的图像处理新手。

The question here has taught me about separable filters, but I'm too much of an image processing newbie to understand how to apply them in this case.

任何人都可以给予关于如何优化它的一些指示?

Can anyone give me some pointers on how one could optimise this?

推荐答案

可分离滤波器的工作方式与普通高斯滤波器相同。当图像尺寸较大时,可分离滤波器比普通高斯滤波器快。滤波器内核可以通过分析形成,滤波器可以分为两个1维矢量,一个水平,一个垂直。

Separable filters work in the same way as normal gaussian filters. The separable filters are faster than normal Gaussian when the image size is large. The filter kernel can be formed analytically and the filter can be separated into two 1 dimensional vectors, one horizontal and one vertical.

例如......

认为过滤器是

1 2 1
2 4 2
1 2 1

此滤波器可分为水平向量(H)1 2 1和垂直矢量(V)1 2 1.现在将这两组滤波器应用于图像。矢量H应用于水平像素,V应用于垂直像素。然后将结果加在一起以获得高斯模糊。我正在提供一个可分离的高斯模糊函数。 (请不要问我评论,我太懒了:P)

this filter can be separated into horizontal vector (H) 1 2 1 and vertical vector(V) 1 2 1. Now these sets of two filters are applied to the image. Vector H is applied to the horizontal pixels and V to the vertical pixels. The results are then added together to get the Gaussian Blur. I'm providing a function that does the separable Gaussian Blur. (Please dont ask me about the comments, I'm too lazy :P)

Mat sepConv(Mat input, int radius)
{


Mat sep;
Mat dst,dst2;

int ksize = 2 *radius +1;
double sigma = radius / 2.575;

Mat gau = getGaussianKernel(ksize, sigma,CV_32FC1);

Mat newgau = Mat(gau.rows,1,gau.type());
gau.col(0).copyTo(newgau.col(0));


filter2D(input, dst2, -1, newgau);


filter2D(dst2.t(), dst, -1, newgau);


return dst.t();


}

另一种改善计算方法高斯模糊是使用FFT。如果数据量非常大,基于FFT的卷积比可分离的内核方法快得多。

One more method to improve the calculation of Gaussian Blur is to use FFT. FFT based convolution is much faster than the separable kernel method, if the data size is pretty huge.

快速谷歌搜索为我提供了以下功能

A quick google search provided me with the following function

Mat Conv2ByFFT(Mat A,Mat B)
{
Mat C;
// reallocate the output array if needed
C.create(abs(A.rows - B.rows)+1, abs(A.cols - B.cols)+1, A.type());
Size dftSize;
// compute the size of DFT transform
dftSize.width = getOptimalDFTSize(A.cols + B.cols - 1);
dftSize.height = getOptimalDFTSize(A.rows + B.rows - 1);

// allocate temporary buffers and initialize them with 0's
Mat tempA(dftSize, A.type(), Scalar::all(0));
Mat tempB(dftSize, B.type(), Scalar::all(0));

// copy A and B to the top-left corners of tempA and tempB, respectively
Mat roiA(tempA, Rect(0,0,A.cols,A.rows));
A.copyTo(roiA);
Mat roiB(tempB, Rect(0,0,B.cols,B.rows));
B.copyTo(roiB);

// now transform the padded A & B in-place;
// use "nonzeroRows" hint for faster processing
Mat Ax = computeDFT(tempA);
Mat Bx = computeDFT(tempB);

// multiply the spectrums;
// the function handles packed spectrum representations well
mulSpectrums(Ax, Bx, Ax,0,true);

// transform the product back from the frequency domain.
// Even though all the result rows will be non-zero,
// we need only the first C.rows of them, and thus we
// pass nonzeroRows == C.rows
//dft(Ax, Ax, DFT_INVERSE + DFT_SCALE, C.rows);

updateMag(Ax);
Mat Cx = updateResult(Ax);

//idft(tempA, tempA, DFT_SCALE, A.rows + B.rows - 1 );
// now copy the result back to C.
Cx(Rect(0, 0, C.cols, C.rows)).copyTo(C);
//C.convertTo(C, CV_8UC1);
// all the temporary buffers will be deallocated automatically
return C;

}

希望这会有所帮助。 :)

Hope this helps. :)

这篇关于OpenCV:高效的高斯差分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-11 22:02