Prob. in Multi Object Detection using Kalman Filter
Hi All, i am succeed to recognize single object using KalmanFilter, and trying to detect Multiple objects but i am facing prob. Here's my code and attachment. This code works fine but instead of detecting whole object as one it is detecting sub objects in that. as you can see in image, i just want to draw only single rectangle on Nut, but unfortunately i am failed, and one more thing i have downloaded this code on Net and tried some modifications.
#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/video/tracking.hpp>
using namespace std;
using namespace cv;
int H_MIN = 0;
int H_MAX = 256;
int S_MIN = 0;
int S_MAX = 256;
int V_MIN = 0;
int V_MAX = 256;
const string trackbarWindowName = "Trackbars";
#define drawCross( img, center, color, d )\
line(img, Point(center.x - d, center.y - d), Point(center.x + d, center.y + d), color, 2, CV_AA, 0);\
line(img, Point(center.x + d, center.y - d), Point(center.x - d, center.y + d), color, 2, CV_AA, 0 )\
int main()
{
Mat frame, thresh_frame;
vector<Mat> channels;
VideoCapture capture;
vector<Vec4i> hierarchy;
vector<vector<Point> > contours;
capture.open(0);
if(!capture.isOpened())
cerr << "Problem opening video source" << endl;
KalmanFilter KF(4, 2, 0);
Mat_<float> state(4, 1);
Mat_<float> processNoise(4, 1, CV_32F);
Mat_<float> measurement(2,1); measurement.setTo(Scalar(0));
KF.statePre.at<float>(0) = 0;
KF.statePre.at<float>(1) = 0;
KF.statePre.at<float>(2) = 0;
KF.statePre.at<float>(3) = 0;
KF.transitionMatrix = *(Mat_<float>(4, 4) << 1,0,1,0, 0,1,0,1, 0,0,1,0, 0,0,0,1); // Including velocity
KF.processNoiseCov = *(cv::Mat_<float>(4,4) << 0.2,0,0.2,0, 0,0.2,0,0.2, 0,0,0.3,0, 0,0,0,0.3);
setIdentity(KF.measurementMatrix);
setIdentity(KF.processNoiseCov, Scalar::all(1e-4));
setIdentity(KF.measurementNoiseCov, Scalar::all(1e-1));
setIdentity(KF.errorCovPost, Scalar::all(.1));
while((char)waitKey(1) != 'q' && capture.grab())
{
capture.retrieve(frame);
cvtColor(frame,thresh_frame,COLOR_BGR2GRAY);
Canny(thresh_frame,thresh_frame,100,200,3);//Detect Edges.
imshow("Edge Detection",thresh_frame);
medianBlur(thresh_frame, thresh_frame, 5);
findContours(thresh_frame, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
Mat drawing = Mat::zeros(thresh_frame.size(), CV_8UC1);
for(size_t i = 0; i < contours.size(); i++)
{
// cout << contourArea(contours[i]) << endl;
if(contourArea(contours[i]) > 500)
drawContours(drawing, contours, i, Scalar::all(255), CV_FILLED, 8, vector<Vec4i>(), 0, Point());
}
thresh_frame = drawing;
// Get the moments
vector<Moments> mu(contours.size() );
for( size_t i = 0; i < contours.size(); i++ )
{ mu[i] = moments( contours[i], false ); }
// Get the mass centers:
vector<Point2f> mc( contours.size() );
for( size_t i = 0; i < contours.size(); i++ )
{ mc[i] = Point2f( mu[i].m10/mu[i].m00 , mu[i].m01/mu[i].m00 ); }
Mat prediction = KF.predict();
Point predictPt(prediction.at<float>(0),prediction.at<float>(1));
for(size_t i = 0; i < mc.size(); i++)
{
drawCross(frame, mc[i], Scalar(255, 0, 0), 5);//Scalar is color for predicted ...
you need one KF per element.
(currently, you just overwrite your measurement in the loop , so it will only hold the last one)
@berak, can you just post the changes , i am newbee to OpenCV. Please find attached image.
hehe, unfortunately not so easy.
but you do understand, that the Kalman Filter builds/holds a state for your object, so for different objects you need one Kalman Filter each. ?
wait is that some kind of conveyor belt above ? things can only move in one direction then ? also, all got the same velocity ?
@berak, Thanks for your suggestion, its not the belt these objects kept on table.