2015-07-13 134 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

非常感谢您的帮助。我得到了我需要的确切结果。再次感谢.. –