[英]How to detect the presence of an object in a non-stationary background using Opencv in Android?
我正在開發一個應用程序來處理幀,並在 Android 中使用 Opencv 實時進行分割和圖像匹配。
主要問題是,只有當要處理的對象在相機幀中可用並且背景不穩定時,我才需要開始此圖像處理,這使我的任務更加困難。
我嘗試了許多解決方案,例如使用absdiff
運動檢測,這是代碼
imgSource = inputFrame.rgba().t();
Core.transpose(imgSource, imgSource);
//imgSource.convertTo(enhancedMat, imgSource.type(), 1.3);
gray = imgSource;
Imgproc.cvtColor(imgSource, gray, Imgproc.COLOR_BGR2GRAY);
Imgproc.GaussianBlur(gray, gray, new Size(25, 25), 5);
if (firstframe == null) {
firstframe = gray;
}
Core.absdiff(firstframe, gray, frameDelta);
Imgproc.threshold(frameDelta, frameDelta, 25, 255, Imgproc.THRESH_BINARY);
for (int i =0 ; i <2 ; i++)
Imgproc.dilate(frameDelta, frameDelta, Imgproc.getStructuringElement(Imgproc.THRESH_BINARY, new Size(3, 3)));
Imgproc.findContours(frameDelta, abs_contours, abs_hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
for (int idx = 0; idx < abs_contours.size(); idx++) {
double a = Imgproc.contourArea(abs_contours.get(idx)); //Find the area of contour
if (a < 10000) {
continue;
}
Rect rect = Imgproc.boundingRect(abs_contours.get(idx));
Imgproc.rectangle(imgSource, rect.tl(), rect.br(), new Scalar(0, 255, 0), 2);
}
我還嘗試使用此createBackgroundSubtractorMOG2
方法createBackgroundSubtractorMOG2
背景減法。
他們都沒有工作,因為背景也在移動,所以這些邏輯根本不健壯。
對於此類問題,我必須遵循任何方法或任何解決方案嗎?
我希望你們能指導我找到一個好的解決方案,並在此先感謝你們。
為了解決這個問題,我使用了光流。
您可以使用calcOpticalFlowFarneback
計算每個幀上的光流。
然后,您將獲得圖像的每個像素的 2 個分量矩陣(x 方向和 y 方向的梯度)。
我計算了每個點atan2(flow_y,flow_x)
並將其存儲在vector<Point2f>
。
然后,只需使用 kmeans 和 2 個標簽進行聚類。 (將背景與序列中的前景移動對象區分開來)。
kmeans 返回的矩陣為您提供標簽。
希望能幫助到你 !
編輯 :
我一直在使用 OpenCV C++,但這是我的代碼
int calculateOptFlow(Mat prev_frame, Mat frame, Mat& output)
{
Mat flow;
//the algorithm uses gray images
cvtColor(frame,frame,CV_BGR2GRAY);
cvtColor(prev_frame,prev_frame,CV_BGR2GRAY);
calcOpticalFlowFarneback(prev_frame, frame, flow,0.4, 1, 12, 2, 8, 1.2, 0);
Mat angle(flow.rows,flow.cols,CV_32FC1);
Mat dst(flow.rows,flow.cols,CV_32FC1);
vector<Point2f> samples(flow.rows*flow.cols);
int n=0;
for(int y=0;y<flow.rows;y++)
{
for(int x=0;x<flow.cols ; x++)
{
angle.at<float>(y,x) = (atan2(flow.at<Point2f>(y,x).y,flow.at<Point2f>(y,x).x));
samples[n++] = flow.at<Point2f>(y,x);
}
}
// split into 2 clusters : background and foreground
Mat labels,centers;
kmeans(samples,2,labels,TermCriteria(TermCriteria::EPS+TermCriteria::COUNT,10,1.0),3,KMEANS_PP_CENTERS,centers);
// create a B&W matrix from the labels
for(int i=0;i<(int)samples.size();i++)
{
int row = static_cast<int>(i/dst.cols);
int col = i%dst.cols;
if(labels.at<int>(i) == 1)
{
dst.at<float>(row,col) = 255;
}
else
{
dst.at<float>(row,col) = 0;
}
}
//conversion for the use of findContours afterwards
dst.convertTo(output,CV_8UC1);
return 1;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.