2015-02-10 199 views
-1

我遇到了一些問題,我的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天我一直在看這個相同的代碼,我認爲我只是缺少了一些東西。如果有人想知道,我也嘗試更改過濾器的掩碼值,但無濟於事。

+0

Studentfilter2D()?你能告訴我們你的代碼嗎? – 2015-02-10 05:13:45

+0

@BalajiR添加了Studentfilter2D。它只是圖像與指定掩碼/內核的二維卷積。 – JMoser 2015-02-10 05:58:57

+0

除了破損的'image.at '(見下面的答案),你不能在8bit-uchar映像上原地執行此操作。由於sobel產生的值超過了255並且也是負值,所以你需要單獨的具有更高的帶符號的範圍的輸出Mat,例如,甚至CV_16S或CV_32F。 – berak 2015-02-10 12:16:31

回答

1

有兩件事值得一提。

首先是你沒有正確照顧你的矩陣/圖像的類型。 sobel_y中的Studentfilter2D的輸入是類型爲CV_8UC1的8位灰度圖像,這意味着數據是unsigned char的數組。 但是,您的Studentfilter2D函數正在將此輸入圖像編入索引,就好像它是float類型。這意味着它正在挑選錯誤的像素與一起使用。

如果上述內容不能立即解決您的問題,則應考慮最終衍生圖片的範圍。由於它是一個衍生物,它將不再處於[0,255]的範圍內。相反,它甚至可能包含負數。當您嘗試將此可視化時,除非您先將標準化爲圖像,否則將遇到問題。 如果您在文檔中查看,則可以在OpenCV中完成此功能。

+0

好的,謝謝!你的第一點是我已經認爲是錯誤的,並嘗試過使用CV_32FC1,但沒有奏效,所以我沒有保留它。我會嘗試正常化它,看看是否修復它。 – JMoser 2015-02-10 11:49:27

+0

所以我做了一些改變並測試了它們,但似乎沒有任何不同之處,例如規範化仍然無法正常工作,但不確定我是否正確使用該功能。我在上面添加了我的更改。 – JMoser 2015-02-10 12:10:49

+0

這個答案,同時意識到我的Studentfilter2D的一部分覆蓋我的圖像,因爲它正在處理結果是問題。謝謝您的幫助 – JMoser 2015-02-10 22:24:42

相關問題