我试图用OpenCV来实现像SCHAR、SOBEL或PREWITT这样的过程梯度滤波器的卷积算法。OpenCV已经有了非常高效的功能,但是他们没有在“一步”中计算执政官。
例如,对于sobel滤波器,它必须按“三个步骤”处理。1) x轴上的Sobel (Sx) 2) y轴上的Sobel (Sy) 3)缔合(frequently 0.5 * sqrt(Sx^2 * Sy^2) )
我写了一个天真的算法来做它,但它返回一个黑色的图像,我真的不明白为什么。
cv::Mat kt = (cv::Mat1f(3,3)<<1,2,1,0,0,0,-1,-2,-1);
cv::Mat kt2 = kt.t();
cv::Mat img = cv::imread("Lena.png", cv::IMREAD_GRAYSCALE);
img.convertTo(img, CV_32F);
// Extand the borders in order to simplify the border management.
cv::copyMakeBorder(img, img, 1,1,1,1, cv::BORDER_ISOLATED, cv::Scalar::all(0.));
// Get a sub region of the same size as the original image from the first row first column WITHOUT copy :)
img = img(cv::Rect(1,1, img.cols-1, img.rows-1));
for(int r=0;r<img.rows;r++)
for(int c=0;c<img.cols;c++)
{
float dx = 0.f;
float dy = 0.f;
for(int kr = -1; kr<=1;kr++)
for(int kc = -1; kc<=1;kc++)
{
float value = img.at<float>(r+kr,c+kc);
dx += 0.25f * value * kt.at<float>(kr+1, kc+1);
dy += 0.25f * value * kt2.at<float>(kr+1, kc+1);
}
img.at<float>(r,c) = std::hypot(dx,dy); // sqrt(dx^2 + dy^2)
}
其结果主要是一幅nan图像。我并不是很清楚为什么。提前感谢您的帮助。
注意,Schar,Sobel,和Prewitt的滤波器是可分离的滤波器。在那个算法中,我没有使用那个属性,因为我是相互关联的,以理解这个简单算法的问题所在。
发布于 2017-11-12 06:26:19
正如“小猪”所指出的,我的问题终于很简单了。我正在努力把输出写在正在处理的图像中。因为处理涉及到邻域,它也会影响输出。解决这一问题的一个方法就是将处理结果写在与我正在处理的图像不同的图像中。
cv::Mat kt = (cv::Mat1f(3,3)<<1,2,1,0,0,0,-1,-2,-1);
cv::Mat kt2 = kt.t();
cv::Mat img = cv::imread("Lena.png", cv::IMREAD_GRAYSCALE);
cv::Mat img2 = cv::Mat::zeros(img.size(),CV_32F);
img.convertTo(img, CV_32F);
// Extand the borders in order to simplify the border management.
cv::copyMakeBorder(img, img, 1,1,1,1, cv::BORDER_ISOLATED, cv::Scalar::all(0.));
// Get a sub region of the same size as the original image from the first row first column WITHOUT copy :)
img = img(cv::Rect(1,1, img.cols-1, img.rows-1));
for(int r=0;r<img.rows;r++)
for(int c=0;c<img.cols;c++)
{
float dx = 0.f;
float dy = 0.f;
for(int kr = -1; kr<=1;kr++)
for(int kc = -1; kc<=1;kc++)
{
float value = img.at<float>(r+kr,c+kc);
dx += 0.25f * value * kt.at<float>(kr+1, kc+1);
dy += 0.25f * value * kt2.at<float>(kr+1, kc+1);
}
img2.at<float>(r,c) = std::hypot(dx,dy); // sqrt(dx^2 + dy^2)
}
https://stackoverflow.com/questions/43711837
复制