我的sobel_y(和sobel_x,但我认为他们也有同样的问题)过滤器存在一些问题,因为它一直给我一个图像,基本上只有黑白图像。我必须为一个类重写此函数,所以不,我不能使用内置函数并使它正常运行,减去一些细微的调整,因为输出图像看起来有些奇怪,尽管原本应该假定它仍然是黑白的被转换回来。我想出了解决方法,在此过程中我弄乱了东西,弄坏了它,即使仅输出黑白图像,似乎也无法使其恢复工作。我一直得到黑色图像,顶部附近到处都有一些白线。我尝试将Mat灰度类型(第三个参数)更改为所有不同的值,
即使在运行Studentfilter2D之后出现问题,我仍然认为图像的灰度是一个问题,尽管每次调试时,它似乎都可以正常工作。这也是因为我不得不编写其他两个使用Studentfilter2D的过滤函数,它们都给了我预期的结果。我的sobel_y函数如下所示:
// Convert the image in bgr to grayscale OK to use the OpenCV function.
// Find the coefficients used by the OpenCV function, and give a link where you found it.
// Note: This student function expects the matrix gray to be preallocated with the same width and
// height, but with 1 channel.
void BGR2Gray(Mat& bgr, Mat& gray)
{
// Y = .299 * R + .587 * G + .114 * B, from http://docs.opencv.org/modules/imgproc/doc/miscellaneous_transformations.html#cvtcolor
// Some extra assistance, for the third parameter for the InputArray, from http://docs.opencv.org/trunk/modules/core/doc/basic_structures.html#inputarray
// Not sure about the fourth parameter, but was just trying it to see if that may be the issue as well
cvtColor(bgr, gray, CV_BGR2GRAY, 1);
return;
}
// Convolve image with kernel - this routine will be called from the other
// subroutines! (gaussian, sobel_x and sobel_y)
// image is single channel. Do not use the OpenCV filter2D!!
// Implementation can be with the .at or similar to the
// basic method found in the Chapter 2 of the OpenCV tutorial in CANVAS,
// or online at the OpenCV documentation here:
// http://docs.opencv.org/doc/tutorials/core/mat-mask-operations/mat-mask operations.html
// In our code the image and the kernel are both floats (so the sample code will need to change)
void Studentfilter2D (Mat& image, Mat& kernel)
{
int kCenterX = kernel.cols / 2;
int kCenterY = kernel.rows / 2;
// Algorithm help from http://www.songho.ca/dsp/convolution/convolution.html
for (int iRows = 0; iRows < image.rows; iRows++)
{
for (int iCols = 0; iCols < image.cols; iCols++)
{
float result = 0.0;
for (int kRows = 0; kRows < kernel.rows; kRows++)
{
// Flip the rows for the convolution
int kRowsFlipped = kernel.rows - 1 - kRows;
for (int kCols = 0; kCols < kernel.cols; kCols++)
{
// Flip the columns for the convolution
int kColsFlipped = kernel.cols - 1 - kCols;
// Indices of shifting around the convolution
int iRowsIndex = iRows + kRows - kCenterY;
int iColsIndex = iCols + kCols - kCenterX;
// Check bounds using the indices
if (iRowsIndex >= 0 && iRowsIndex < image.rows && iColsIndex >= 0 && iColsIndex < image.cols)
{
result += image.at<float>(iRowsIndex, iColsIndex) * kernel.at<float>(kRowsFlipped, kColsFlipped);
}
}
}
image.at<float>(iRows, iCols) = result;
}
}
return;
}
void sobel_y (Mat& image, int)
{
// Note, the filter parameter int is unused.
Mat mask = (Mat_<float>(3, 3) << 1, 2, 1,
0, 0, 0,
-1, -2, -1) / 3;
//Mat grayscale(image.rows, image.cols, CV_32FC1);
BGR2Gray(image, image);
Studentfilter2D(image, mask);
// Here is the documentation on normalize http://docs.opencv.org/modules/core/doc/operations_on_arrays.html#normalize
normalize(image, image, 0, 1, NORM_MINMAX);
cvtColor(image, image, CV_GRAY2BGR);
return;
}
就像我说的那样,我之前曾做过这项工作,只是想找一些新鲜的眼睛看一下,看看我可能会缺少什么。在过去的4天里,我一直在看相同的代码,以至于我只是想念一些东西。万一有人怀疑,我也尝试过更改过滤器的掩码值,但无济于事。
有两件事值得一提。
首先是您没有适当注意矩阵/图像的类型。Studentfilter2D
in的输入sobel_y
是8位灰度图像,其类型CV_8UC1
表示数据是的数组unsigned char
。Studentfilter2D
但是,您的函数正在索引此输入图像,就像它是type一样float
。这意味着它选择了错误的像素进行处理。
如果上述方法不能立即解决您的问题,则应考虑最终衍生图像的范围。由于它是导数,因此将不再在[0,255]范围内。相反,它甚至可能包含负数。尝试形象化该图像时,除非首先对图像进行标准化,否则您将遇到问题。如果您在文档中四处浏览,则内置函数可以在OpenCV中执行此操作。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句