我正在尝试使用OpenCV为过程梯度过滤器实现卷积算法,例如SCHAR,SOBEL或PREWITT。 OpenCV已经具备了非常有效的功能,但是他们不会在一步中计算出结果"。
E.g。对于索贝尔滤波器,它必须在"三个步骤"中处理。
1)Sobel在x轴上(Sx)
2)Sobel在y轴上(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)
}
结果主要是纳米图像。我真的不明白为什么。 提前感谢您的帮助。
注意Schar,Sobel和Prewitt的过滤器是可分离的过滤器。在那个算法中我不使用那个属性 我很想知道这个简单算法有什么问题。
答案 0 :(得分:0)
正如@piglet所说,我的问题终于很简单了。 我正在尝试在图像中编写输出。 因为处理涉及邻域,所以它也影响输出。 解决这个问题的方法就是将处理结果写入与我正在处理的图像不同的图像中。
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)
}