我正在尝试使用openCV来实现一种卷积算法,例如schar,sobel或preWitt。OpenCV已经具有非常有效地执行此操作的Funcitons,但是它们不会在"一个步骤"中计算重新填充。
例如。对于Sobel过滤器,必须以"三个步骤"处理。1(X轴(SX(上的Sobel2(y轴(SY(上的Sobel3(协会(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的过滤器是可分离的过滤器。在该算法中,我不使用该属性,因为SE我很认为该简单算法是什么问题。
作为@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)
}