opencv C+中非均匀照明下的目标检测+; 我使用OpenCV C++在视频/直播流/图像中进行特征检测。视频的不同部分的照明条件不同,导致在将RGB图像转换为二值图像时忽略某些部分

opencv C+中非均匀照明下的目标检测+; 我使用OpenCV C++在视频/直播流/图像中进行特征检测。视频的不同部分的照明条件不同,导致在将RGB图像转换为二值图像时忽略某些部分,c++,matlab,opencv,image-processing,C++,Matlab,Opencv,Image Processing,视频特定部分中的照明条件也会在视频过程中发生变化。我尝试了“直方图均衡化”功能,但没用 我在以下链接中获得了MATLAB中的工作解决方案: 但是,上面链接中使用的大多数函数在OpenCV中不可用 可在OpenCV C++中提出备选方案吗? < P> OpenCV在框架中有自适应阈值范例: 函数原型如下所示: void adaptiveThreshold(InputArray src, OutputArray dst, double maxValue

视频特定部分中的照明条件也会在视频过程中发生变化。我尝试了“直方图均衡化”功能,但没用

我在以下链接中获得了MATLAB中的工作解决方案:

但是,上面链接中使用的大多数函数在OpenCV中不可用


可在OpenCV C++中提出备选方案吗?

< P> OpenCV在框架中有自适应阈值范例:

函数原型如下所示:

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();
}
//包含库
#包括
#包括
//为了方便
使用名称空间cv;
//图像自适应阈值的示例函数
无效阈值()
{
//加载图像-将“image.jpg”更改为图像的名称
Mat图像;
image=imread(“image.jpg”,1);
//将图像转换为灰度并显示图像
//等待用户密钥,然后继续
Mat灰度图像;
CVT颜色(图像、灰度图像、CV灰度);
namedWindow(“灰色图像”,CV_窗口_自动调整大小);
imshow(“灰度图像”,灰度图像);
等待键(0);
//图像的自适应阈值
int maxValue=255;
int blockSize=25;
int C=0;
自适应阈值(灰度图像、灰度图像、最大值、,
CV_自适应_阈值_均值_C,CV_阈值_二进制,
块大小,C);
//显示阈值图像
//等待用户密钥,然后继续
namedWindow(“阈值图像”,CV\u窗口\u自动调整大小);
imshow(“阈值图像”,灰度图像);
等待键(0);
}
//主功能-运行阈值功能
int main(int argc,常量字符**argv)
{
阈值();
}

自适应阈值应该是您的首选

但是在这里,我报告了从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;
}
#包括
使用名称空间cv;
int main()
{   
//步骤1:读取图像
Mat1b img=imread(“路径到图像”,imread\U灰度);
//第2步:使用形态学打开来估计背景
Mat kernel=getStructuringElement(变形椭圆,大小(15,15));
Mat1b背景;
形态学(img,背景,形态开放,内核);
//步骤3:从原始图像中减去背景图像
Mat1b-img2;
absdiff(img、背景、img2);
//步骤4:增加图像对比度
//这里不需要它,等价物应该是cv::equalizeHist
//步骤5(1):对图像设置阈值
Mat1b bw;
阈值(img2,bw,50255,阈值二进制);
//步骤6:识别图像中的对象
矢量等值线;
findContours(bw.clone()、等高线、CV\u RETR\u列表、CV\u CHAIN\u近似值\u NONE);
对于(int i=0;i 50)
{
//步骤7:检查一个对象
Mat1b对象(bw.size(),uchar(0));
绘制轮廓(对象、轮廓、i、标量(255)、CV_填充);
imshow(“单个对象”,对象);
waitKey();
}
}
返回0;
}

以上链接中使用的大多数函数都可以在OpenCV中找到。是的,请尝试此cv::MorphologyExt非常感谢您的帮助。我得到了我需要的确切结果。再次感谢……谢谢你的回复