Opencv 如何使用findcontours为每个对象获取实心水滴?

Opencv 如何使用findcontours为每个对象获取实心水滴?,opencv,blob,contour,object-detection,Opencv,Blob,Contour,Object Detection,我想从提取的前景中为每个对象分割一个实心斑点,并用一个长方体包围每个对象。但我的代码显示了许多框,它们包围着一个对象上的随机斑点,因为我的斑点对于一个对象来说不是实心的,而且还有许多小斑点 下面是我的代码: #include"stdafx.h" #include<vector> #include<iostream> #include<opencv2/opencv.hpp> #include<opencv2/core/core.hpp> #inclu

我想从提取的前景中为每个对象分割一个实心斑点,并用一个长方体包围每个对象。但我的代码显示了许多框,它们包围着一个对象上的随机斑点,因为我的斑点对于一个对象来说不是实心的,而且还有许多小斑点

下面是我的代码:

#include"stdafx.h"
#include<vector>
#include<iostream>
#include<opencv2/opencv.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>

int main(int argc, char *argv[])
{
    cv::Mat frame;                                              
    cv::Mat fg;                                                 
    cv::Mat thresholded;
    cv::Mat thresholded2;
    cv::Mat result;
    cv::Mat bgmodel;                                            
    cv::namedWindow("Frame");                                   
    cv::namedWindow("Background Model");                        
    cv::VideoCapture cap(0);                                    

    cv::BackgroundSubtractorMOG2 bgs;                           

        bgs.nmixtures = 2;                                      
        bgs.history = 60;
        bgs.varThreshold = 15;
        bgs.bShadowDetection = true;                            
        bgs.nShadowDetection = 0;                               
        bgs.fTau = 0.5;                                         

    std::vector<std::vector<cv::Point>> contours;               

    for(;;)
    {
        cap >> frame;                                           

        cv::blur(frame,frame,cv::Size(10,10));

        bgs.operator()(frame,fg);                           
        bgs.getBackgroundImage(bgmodel);                    

        cv::erode(fg,fg,cv::Mat());                         
        cv::dilate(fg,fg,cv::Mat());                        

        cv::threshold(fg,thresholded,70.0f,255,CV_THRESH_BINARY);
        cv::threshold(fg,thresholded2,70.0f,255,CV_THRESH_BINARY);

        cv::findContours(thresholded,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE);
        cv::cvtColor(thresholded2,result,CV_GRAY2RGB);

        int cmin= 50; 
        int cmax= 10000;

        std::vector<std::vector<cv::Point>>::iterator itc=contours.begin();

        while (itc!=contours.end()) {       
                if (itc->size() < cmin || itc->size() > cmax){
                    itc= contours.erase(itc);} else{

                        std::vector<cv::Point> pts = *itc;
                        cv::Mat pointsMatrix = cv::Mat(pts);
                        cv::Scalar color( 0, 255, 0 );

                        cv::Rect r0= cv::boundingRect(pointsMatrix);
                        cv::rectangle(result,r0,color,2);

                        ++itc;
                    }
        }

        cv::imshow("Frame",result);
        cv::imshow("Background Model",bgmodel);
        if(cv::waitKey(30) >= 0) break;
    }
    return 0;
}
#包括“stdafx.h”
#包括
#包括
#包括
#包括
#包括
#包括
int main(int argc,char*argv[])
{
cv::垫架;
cv::Mat-fg;
cv::设定阈值的Mat;
cv::Mat阈值2;
cv::Mat结果;
cv::Mat-bgmodel;
cv::namedWindow(“框架”);
cv::namedWindow(“背景模型”);
cv::视频捕获上限(0);
cv::背景MOG2 bgs;
bgs.nmixtures=2;
bgs.history=60;
bgs.varThreshold=15;
bgs.bShadowDetection=true;
bgs.nShadowDetection=0;
bgs.fTau=0.5;
矢量轮廓;
对于(;;)
{
cap>>框架;
cv::模糊(帧,帧,cv::大小(10,10));
bgs.operator()(帧,fg);
getBackgroundImage(bgmodel);
侵蚀(fg,fg,cv::Mat());
扩张(fg,fg,cv::Mat());
cv::阈值(fg,阈值化,70.0f,255,cv_阈值二元);
cv::阈值(fg,阈值2,70.0f,255,cv_阈值二元);
cv::findContours(阈值、轮廓、cv_RETR_外部、cv_链_近似值_无);
cv::cvtColor(阈值2,结果,cv_GRAY2RGB);
int-cmin=50;
int cmax=10000;
std::vector::iterator itc=contours.begin();
while(itc!=contours.end()){
如果(itc->size()size()>cmax){
itc=等高线。擦除(itc);}其他{
标准:向量pts=*itc;
cv::Mat pointsMatrix=cv::Mat(pts);
cv::标量颜色(0,255,0);
cv::Rect r0=cv::boundingRect(pointsMatrix);
cv::矩形(结果,r0,颜色,2);
++国贸中心;
}
}
cv::imshow(“帧”,结果);
cv::imshow(“背景模型”,bgmodel);
如果(cv::waitKey(30)>=0)中断;
}
返回0;
}
结果如下:

那么,我如何为从提取的前景中找到的每个对象分割一个实心水滴,并用长方体将对象一个接一个地包围起来呢

实心水滴是指像这里这样的实心白色水滴:xxx

我将感谢您的帮助

注:对不起,我的英语不好。:)

=================

这是我编辑的代码

#include"stdafx.h"
#include<vector>
#include<iostream>
#include<opencv2/opencv.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>

int main(int argc, char *argv[])
{
    cv::Mat frame;                                              
    cv::Mat fg;     
    cv::Mat blurred;
    cv::Mat thresholded;
    cv::Mat thresholded2;
    cv::Mat result;
    cv::Mat bgmodel;                                            
    cv::namedWindow("Frame");                                   
    cv::namedWindow("Background Model");                        
    cv::VideoCapture cap(0);    

    cv::BackgroundSubtractorMOG2 bgs;                           

        bgs.nmixtures = 2;                                      
        bgs.history = 60;
        bgs.varThreshold = 15;
        bgs.bShadowDetection = true;                            
        bgs.nShadowDetection = 0;                               
        bgs.fTau = 0.5;                                         

    std::vector<std::vector<cv::Point>> contours;               

    for(;;)
    {
        cap >> frame;                                           

        cv::blur(frame,blurred,cv::Size(10,10));

        bgs.operator()(blurred,fg);                         
        bgs.getBackgroundImage(bgmodel);                                    

        cv::threshold(fg,thresholded,70.0f,255,CV_THRESH_BINARY);
        cv::threshold(fg,thresholded2,70.0f,255,CV_THRESH_BINARY);

        cv::Mat element50(50,50,CV_8U,cv::Scalar(1));
        cv::morphologyEx(thresholded,thresholded,cv::MORPH_CLOSE,element50);
        cv::morphologyEx(thresholded2,thresholded2,cv::MORPH_CLOSE,element50);

        cv::findContours(thresholded,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE);
        cv::cvtColor(thresholded2,result,CV_GRAY2RGB);

        int cmin= 50; 
        int cmax= 10000;

        std::vector<std::vector<cv::Point>>::iterator itc=contours.begin();

        while (itc!=contours.end()) {   

                if (itc->size() < cmin || itc->size() > cmax){
                    itc= contours.erase(itc);} else{ 

                        std::vector<cv::Point> pts = *itc;
                        cv::Mat pointsMatrix = cv::Mat(pts);
                        cv::Scalar color( 0, 255, 0 );

                        cv::Rect r0= cv::boundingRect(pointsMatrix);
                        cv::rectangle(result,r0,color,2);

                        ++itc;
                    }
        }

        cv::imshow("Frame",result);
        cv::imshow("Background Model",bgmodel);
        if(cv::waitKey(30) >= 0) break;
    }
    return 0;
}
#包括“stdafx.h”
#包括
#包括
#包括
#包括
#包括
#包括
int main(int argc,char*argv[])
{
cv::垫架;
cv::Mat-fg;
cv::Mat模糊;
cv::设定阈值的Mat;
cv::Mat阈值2;
cv::Mat结果;
cv::Mat-bgmodel;
cv::namedWindow(“框架”);
cv::namedWindow(“背景模型”);
cv::视频捕获上限(0);
cv::背景MOG2 bgs;
bgs.nmixtures=2;
bgs.history=60;
bgs.varThreshold=15;
bgs.bShadowDetection=true;
bgs.nShadowDetection=0;
bgs.fTau=0.5;
矢量轮廓;
对于(;;)
{
cap>>框架;
cv::模糊(帧,模糊,cv::大小(10,10));
bgs.operator()(模糊,前景);
getBackgroundImage(bgmodel);
cv::阈值(fg,阈值化,70.0f,255,cv_阈值二元);
cv::阈值(fg,阈值2,70.0f,255,cv_阈值二元);
cv::Mat元素50(50,50,cv_8U,cv::Scalar(1));
cv::morphologyEx(阈值化,阈值化,cv::Morpho_CLOSE,element50);
cv::morphologyEx(阈值2,阈值2,cv::Morphon_CLOSE,元素50);
cv::findContours(阈值、轮廓、cv_RETR_外部、cv_链_近似_简单);
cv::cvtColor(阈值2,结果,cv_GRAY2RGB);
int-cmin=50;
int cmax=10000;
std::vector::iterator itc=contours.begin();
while(itc!=contours.end()){
如果(itc->size()size()>cmax){
itc=等高线。擦除(itc);}否则{
标准:向量pts=*itc;
cv::Mat pointsMatrix=cv::Mat(pts);
cv::标量颜色(0,255,0);
cv::Rect r0=cv::boundingRect(pointsMatrix);
cv::矩形(结果,r0,颜色,2);
++国贸中心;
}
}
cv::imshow(“帧”,结果);
cv::imshow(“背景模型”,bgmodel);
如果(cv::waitKey(30)>=0)中断;
}
返回0;
}
结果如下:


多亏了elactic.:)

您可以尝试将博客与形态学关闭合并(这是二值图像膨胀的侵蚀)。您可以使用CV函数
腐蚀
扩张

我应该帮助你。 我想在此之后,您仍然需要按大小过滤水滴。

您能更明确地定义“实体”和“对象”吗?T