我想从提取的前景中为每个对象分割一个实体blob,并用一个框绑定每个对象。但是我的代码显示了许多在1个对象上绑定随机blob的方框,因为我的blob对于1个对象来说并不牢固,而且还有很多小blob。
我们转到我的代码:
#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;
}
结果如下: Frame
那么如何为从提取的前景中找到的每个对象分割实体blob,并将该对象与该框一起绑定?
一个实心斑点意味着像这里一样坚实的白色斑点:xxx
我会在这里给予任何帮助。
NB:抱歉我的英语不好。 :)
=================
这是我编辑过的代码!
#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;
}
,结果如下:FRAME
感谢elactic。 :)
答案 0 :(得分:1)
您可以尝试将博客与形态学关闭(这是对二进制图像的扩张的侵蚀)进行合并。您可以使用CV函数erode
和dilate
。
This tutorial应该可以帮到你。 我假设在此之后你仍然需要按大小过滤blob。