opencv Sobel算子是否计算相关性,而不是卷积? 我知道filter2D函数计算相关性,我刚刚发现(基于代码的结果)Sobel算子也计算相关性。这是预期的吗?我错过了什么吗?
href
答案 0 :(得分:0)
修改强>
要获取OpenCV Sobel内核,您可以调用cv::getDerivKernels
来获取两个可分离的内核(let d = Dining.make(blah blah) as! Dining
实际上是在cv::sepFilter2D
或英特尔的OpenCV代码中调用的IPP Sobel或任何其他后端(如果存在)并且确实执行了相关性。
下面提到的内核已经过时,但测试代码仍然有用!
最好的选择是测试以避免意外:
cv::Sobel
输出:
{
cv::RNG(0); //fix RNG
cv::Mat img(8, 8, CV_8U);
cv::randu(img, 0, 256);
cv::Mat sobel_x;
cv::Sobel(img, sobel_x, CV_64F, 1, 0);
cv::Mat sobel_filter;
cv::Mat kern = (cv::Mat_<double>(3, 3) << 1, 0, -1,
2, 0, -2,
1, 0, -1);
cv::filter2D(img, sobel_filter, CV_64F, kern);
cv::Mat kern_flip, sobel_filter_conv;
cv::flip(kern, kern_flip, -1);
cv::filter2D(img, sobel_filter_conv, CV_64F, kern_flip);
std::cout << "img:\n" << img << std::endl;
std::cout << "sobel_x:\n" << sobel_x << std::endl;
std::cout << "sobel_filter:\n" << sobel_filter << std::endl;
std::cout << "sobel_filter_conv:\n" << sobel_filter_conv << std::endl;
cv::Mat diff = sobel_x - sobel_filter;
cv::Mat diff2 = sobel_x - sobel_filter_conv;
std::cout << "Diff sobel_x - sobel_filter: " << cv::sum( diff )[0] << std::endl;
std::cout << "Diff sobel_x - sobel_filter_conv: " << cv::sum( diff2 )[0] << std::endl;
}
{
cv::RNG(0); //fix RNG
cv::Mat img(8, 8, CV_8U);
cv::randu(img, 0, 256);
cv::Mat sobel_y;
cv::Sobel(img, sobel_y, CV_64F, 0, 1);
cv::Mat sobel_filter;
cv::Mat kern = (cv::Mat_<double>(3, 3) << 1, 2, 1,
0, 0, 0,
-1, -2, -1);
cv::filter2D(img, sobel_filter, CV_64F, kern);
cv::Mat kern_flip, sobel_filter_conv;
cv::flip(kern, kern_flip, -1);
cv::filter2D(img, sobel_filter_conv, CV_64F, kern_flip);
std::cout << "img:\n" << img << std::endl;
std::cout << "sobel_y:\n" << sobel_y << std::endl;
std::cout << "sobel_filter:\n" << sobel_filter << std::endl;
std::cout << "sobel_filter_conv:\n" << sobel_filter_conv << std::endl;
cv::Mat diff = sobel_y - sobel_filter;
cv::Mat diff2 = sobel_y - sobel_filter_conv;
std::cout << "Diff sobel_y - sobel_filter: " << cv::sum( diff )[0] << std::endl;
std::cout << "Diff sobel_y - sobel_filter_conv: " << cv::sum( diff2 )[0] << std::endl;
}
答案 1 :(得分:0)
这是我写的测试,输出说实话。 cv :: Sobel计算相关性而不是卷积。 我使用了以下内核,它与cv :: Sobel
使用的内核相同kern = [-1, 0, 1;
-2, 0, 2;
-1, 0, 1]
结果表明sobelx和filter2d(相关)的输出是相同的。
void test_sobel(){
cv::RNG(0);
cv::Mat src(4,4, CV_8U);
cv::randu(src, 0, 256);
cv::Mat sobelx, dest_corr,dest_conv;
cv::Sobel(src, sobelx, CV_32F,1,0,3);
// sobel uses a 3x3 filter shown as below
Mat kern = (Mat_<float>(3,3)<<-1,0,1,-2,0,2,-1,0,1);
// filter2D computes correlation
cv::filter2D(src,dest_corr,CV_32F,kern);
//flip the kernel in x and y direction for convolution
cv::Mat kern_conv;
cv::flip(kern,kern_conv, -1);
cv::filter2D(src,dest_conv,CV_32F,kern_conv);
std::cout << "kern = \n" << kern<< std::endl;
std::cout << "kern_conv = \n" << kern_conv<< std::endl;
std::cout << "src = \n" << src << std::endl;
std::cout << "sobelx = \n" << sobelx<< std::endl;
std::cout << "dest_corr = \n" << dest_corr<< std::endl;
std::cout << "dest_conv =\n" << dest_conv << std::endl;
cv::Mat diff1 = sobelx - dest_corr;
cv::Mat diff2 = sobelx - dest_conv;
std::cout << "sobelx - dest_corr = " << cv::sum( diff1 )[0] << std::endl;
std::cout << "sobelx - dest_conv = " << cv::sum( diff2 )[0] << std::endl;
}
输出:
kern =
[-1, 0, 1;
-2, 0, 2;
-1, 0, 1]
kern_conv =
[1, 0, -1;
2, 0, -2;
1, 0, -1]
src =
[246, 156, 192, 7;
165, 166, 2, 179;
231, 212, 171, 230;
93, 138, 123, 80]
sobelx =
[0, -434, -272, 0;
0, -440, -105, 0;
0, -253, -9, 0;
0, -60, -80, 0]
dest_corr =
[0, -434, -272, 0;
0, -440, -105, 0;
0, -253, -9, 0;
0, -60, -80, 0]
dest_conv =
[0, 434, 272, 0;
0, 440, 105, 0;
0, 253, 9, 0;
0, 60, 80, 0]
sobelx - dest_corr = 0
sobelx - dest_conv = -3306