我遇到了一些問題,我的sobel_y(和sobel_x,但我認爲他們有相同的問題)過濾器,它不斷給我一個圖像,它基本上只有黑色和白色。我不得不爲這個類重寫這個函數,所以我不能使用內置的函數,並且讓它工作,減去一些小的調整,因爲輸出圖像看起來有點奇怪,儘管它應該是黑白的被轉回。我想出瞭如何解決這個問題,並且在這個過程中,我搞砸了一些東西並破壞了它,即使只有黑白圖像輸出,也似乎無法讓它恢復正常工作。我一直在看黑色的圖像,在這裏和附近有一些白線。我曾嘗試將Mat灰度類型(第三個參數)更改爲所有不同的值,正如我的教授在課上提到的那樣,我們使用的是32位浮點圖像,但這也沒有幫助。OpenCV Sobel過濾器導致幾乎完全黑色的圖像
即使運行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()?你能告訴我們你的代碼嗎? – 2015-02-10 05:13:45
@BalajiR添加了Studentfilter2D。它只是圖像與指定掩碼/內核的二維卷積。 – JMoser 2015-02-10 05:58:57
除了破損的'image.at'(見下面的答案),你不能在8bit-uchar映像上原地執行此操作。由於sobel產生的值超過了255並且也是負值,所以你需要單獨的具有更高的帶符號的範圍的輸出Mat,例如,甚至CV_16S或CV_32F。 –
berak
2015-02-10 12:16:31