2015-07-13 37 views
3

我使用OpenCV C++在視頻/實時流/圖像中執行特徵檢測。照明條件因視頻的不同部分而異,導致在將RGB圖像轉換爲二進制圖像時某些部分被忽略。在opencv中檢測非均勻照明中的對象C++

視頻特定部分的照明條件也隨着視頻的變化而變化。我嘗試了'直方圖均衡'功能,但它沒有幫助。

我在下面的鏈接在MATLAB工作的解決方案:

http://in.mathworks.com/help/images/examples/correcting-nonuniform-illumination.html

然而,大多數在上面的鏈接中使用的功能不可用在OpenCV中。

你可以在OpenCV C++中建議這個MATLAB代碼的替代嗎?

+0

在上述鏈接**中使用的大多數功能**都可以在OpenCV中使用。 – Miki

+0

是的,試試這個cv :: morphologyEx –

回答

2

OpenCV的在框架中提供該自適應閾值的範例:http://docs.opencv.org/modules/imgproc/doc/miscellaneous_transformations.html#adaptivethreshold

函數原型看起來像:

void adaptiveThreshold(InputArray src, OutputArray dst, 
         double maxValue, int adaptiveMethod, 
         int thresholdType, int blockSize, double C); 

前兩個參數是輸入圖像和存儲在輸出閾值的圖像的位置。 maxValue是分配給輸出像素的閾值,如果它通過條件,adaptiveMethod是用於自適應閾值處理的方法,thresholdType是要執行的閾值類型(稍後),blockSize是要檢查的窗口大小(稍後),並且C是從每個窗口中減去的常量。我從來沒有真正需要使用這個,我通常將其設置爲0。

的默認方法adaptiveThreshold是分析blockSize x blockSize窗口以及該窗口被C減去內計算平均強度。如果此窗口的中心高於平均強度,則輸出圖像輸出位置中的相應位置設置爲maxValue,否則相同位置設置爲0.這應該對抗非均勻照明問題,而不是應用圖像的全局閾值,您要對局部像素鄰域執行閾值處理。

你可以閱讀其他方法對其他參數的文件,而是讓你開始,你可以做這樣的事情:

// Include libraries 
#include <cv.h> 
#include <highgui.h> 

// For convenience 
using namespace cv; 

// Example function to adaptive threshold an image 
void threshold() 
{ 
    // Load in an image - Change "image.jpg" to whatever your image is called 
    Mat image; 
    image = imread("image.jpg", 1); 

    // Convert image to grayscale and show the image 
    // Wait for user key before continuing 
    Mat gray_image; 
    cvtColor(image, gray_image, CV_BGR2GRAY); 

    namedWindow("Gray image", CV_WINDOW_AUTOSIZE); 
    imshow("Gray image", gray_image); 
    waitKey(0); 

    // Adaptive threshold the image 
    int maxValue = 255; 
    int blockSize = 25; 
    int C = 0; 
    adaptiveThreshold(gray_image, gray_image, maxValue, 
        CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY, 
        blockSize, C); 

    // Show the thresholded image 
    // Wait for user key before continuing 
    namedWindow("Thresholded image", CV_WINDOW_AUTOSIZE); 
    imshow("Thresholded image", gray_image); 
    waitKey(0); 
} 

// Main function - Run the threshold function 
int main(int argc, const char** argv) 
{ 
    threshold(); 
} 
+0

感謝您的回覆 –

1

adaptiveThreshold應該是您的第一選擇。

但是在這裏我報告了從Matlab到OpenCV的「翻譯」,因此您可以輕鬆地移植您的代碼。正如你所看到的,大部分函數都可以在Matlab和OpenCV中使用。

#include <opencv2\opencv.hpp> 
using namespace cv; 

int main() 
{ 
    // Step 1: Read Image 
    Mat1b img = imread("path_to_image", IMREAD_GRAYSCALE); 

    // Step 2: Use Morphological Opening to Estimate the Background 
    Mat kernel = getStructuringElement(MORPH_ELLIPSE, Size(15,15)); 
    Mat1b background; 
    morphologyEx(img, background, MORPH_OPEN, kernel); 

    // Step 3: Subtract the Background Image from the Original Image 
    Mat1b img2; 
    absdiff(img, background, img2); 

    // Step 4: Increase the Image Contrast 
    // Don't needed it here, the equivalent would be cv::equalizeHist 

    // Step 5(1): Threshold the Image 
    Mat1b bw; 
    threshold(img2, bw, 50, 255, THRESH_BINARY); 

    // Step 6: Identify Objects in the Image 
    vector<vector<Point>> contours; 
    findContours(bw.clone(), contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE); 


    for(int i=0; i<contours.size(); ++i) 
    { 
     // Step 5(2): bwareaopen 
     if(contours[i].size() > 50) 
     { 
      // Step 7: Examine One Object 
      Mat1b object(bw.size(), uchar(0)); 
      drawContours(object, contours, i, Scalar(255), CV_FILLED); 

      imshow("Single Object", object); 
      waitKey(); 
     } 
    } 

    return 0; 
} 
+0

非常感謝您的幫助。我得到了我需要的確切結果。再次感謝.. –