jeudi 28 avril 2022

How reduce false detection in my code and how to improve tracking accuracy?

Code is working fine but not accurate

Step: 1

  1. Read Frame from Camera
  2. Select ROI(Region of Interest)
  3. After that start KCF tracker with Sobal Features Extractor
  4. Tracking the selected object.

Step: 2

  1. Failure detect
  2. After that call template matching function called MatchingMethod()
  3. Run template matching
  4. Get x, y value from template matching
  5. After that reinitialize KCF tracker with Sobal Features Extractor.

This code is fine for still object when the object is moving the tracker false detection. I want to improve accuracy and reduce false detection.

#include <opencv2/core/utility.hpp>
#include <opencv2/tracking.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/core/ocl.hpp>
#include <iostream>
#include <cstring>
#include <unistd.h>
#include "sample_utility.hpp"
#include <thread>
#include <opencv2/cudaimgproc.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/calib3d.hpp>
#include <opencv2/cudaarithm.hpp>
#include <iomanip>
#include <stdlib.h>
#include <unistd.h>
//////////////////////////////
    
using namespace cv;
using namespace std;
    
////////////////////////////
// Convert to string
#define SSTR( x ) static_cast< std::ostringstream & >( \
( std::ostringstream() << std::dec << x ) ).str()
/// Global Variables
struct Array {
    int arr[2];
    };
Mat img;
Mat templ;
Mat result_h;

bool flag = true;    
int match_method = 5;
int i=0;
int max_Trackbar = 5;
float fps;
int seconds = 0;
// Function Headers
void delay();
// prototype of the functino for feature extractor
void sobelExtractor(const Mat img, const Rect roi, Mat& feat);
struct Array MatchingMethod( int, void* );
int main(int argc, char **argv)
    {
    TrackerKCF::Params param;
    param.compress_feature = true;
    param.compressed_size = 2;
    param.desc_npca = 0;
    param.desc_pca = TrackerKCF::GRAY | TrackerKCF::CN;
    param.detect_thresh = 0.8;
    // create a tracker object
    Ptr<TrackerKCF> tracker = TrackerKCF::create(param);
    tracker->setFeatureExtractor(sobelExtractor);
    VideoCapture cap(0);
    // Exit if video is not opened
    if(!cap.isOpened())
        {
        //cout << "Could not read video file" << endl;
        return 1;
        }
    
    // Read first frame
    Mat frame;
    bool ok = cap.read(frame);
    // Define initial bounding box
    //Rect bbox(x, y, w, h);
    // Uncomment the line below to select a different bounding box
    Rect bbox = selectROI(frame, false);
    // Display bounding box.
    rectangle(frame, bbox, Scalar( 255, 0, 0 ), 2, 1 );
    ///////////////////////////
    int H, W, cW, cH;
    // print(f"hight {H} , Width {W}")
    H = display_height;
    W = display_width;
    // Center point of the screen
    cW = int(W / 2);
    cH = int(H / 2);
    Point p1(cW, cH);
    // get bounding box
    Mat imCrop = frame(bbox);
    imwrite("1.png", imCrop);
    //quit if ROI was not selected
    if(bbox.width==0 || bbox.height==0)
        return 0;
    //////////////////////////
    //imshow("Tracking", frame);
    tracker->init(frame, bbox);
    while(true)
        {
        Mat frame;
        cap >> frame;
        circle(frame, p1, 3, Scalar(0,255,0), -1);
        // Start timer
        if(bbox.width!=0 || bbox.height!=0){
            double timer = (double)getTickCount();
            // Update the tracking result
            /////////////////////////////////////
            bool ok = tracker->update(frame, bbox);
            //////////////////////////////////////
            //ok, bbox = tracker->update(frame);
            // Calculate Frames per second (FPS)
            fps = getTickFrequency() / ((double)getTickCount() - timer);
            if (ok)
                {
                // Tracking success : Draw the tracked object
                rectangle(frame, bbox, Scalar( 255, 0, 0 ), 2, 1 );
                ///////////////////////////////////////////////////
                int xxx, yyy, height, width;
                xxx = bbox.x;
                yyy = bbox.y;
                height = bbox.height;
                width = bbox.width;
                int diffX, diffY;
                float cxROI, cyROI;
                cxROI = int((xxx + (xxx + width)) / 2);
                cyROI = int((yyy + (yyy + height)) / 2);
                diffX = cxROI - cW;
                diffY = cH - cyROI;
                //cout<<diffX<<"\n";
                //cout<<diffY<<"\n";
                Point p(cxROI, cyROI);
                circle(frame, p, 3, Scalar(128,0,0), -1);
                putText(frame, "FPS : " + SSTR(int(fps)), Point(100,20), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(50,170,50), 2);
                putText(frame, "Difference From X-Axis: "+SSTR(int(diffX)), Point(100, 50), FONT_HERSHEY_SIMPLEX, 0.6, Scalar(100, 200, 200), 2);
                putText(frame, "Difference From Y-Axis: "+SSTR(int(diffY)), Point(100, 80), FONT_HERSHEY_SIMPLEX, 0.6, Scalar(100, 200, 200), 2);
                }
                else
                {
                // Tracking failure detected.
                putText(frame, "Tracking failure detected", Point(100,110), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(0,0,255),2);
                templ = imread( "1.png", 1 );
                img=frame.clone();
                struct Array a = MatchingMethod( 0, 0 );
                cout<<"X: "<<a.arr[0]<<"\n";
                cout<<"Y: "<<a.arr[1]<<"\n";
                cout<<"Width: "<<w<<"\n";
                cout<<"Height: "<<h<<"\n";
                int xx, yy, ww, hh;
                xx = a.arr[0];
                yy = a.arr[1];
                ww = w;
                hh = h;
                Rect bbox(xx, yy, ww, hh);
                tracker.release();
                tracker = TrackerKCF::create(param);
                tracker->setFeatureExtractor(sobelExtractor);
                tracker->init(frame, bbox);
                //roi.x = MatchingMethod.
                //waitKey(30);
                rectangle(frame, bbox, Scalar( 255, 0, 0 ), 2, 1 );
                ////////////////////////////////////////////////////////////////////////
                int diffX, diffY;
                float cxROI, cyROI;
                cxROI = int((xx + (xx + ww)) / 2);
                cyROI = int((yy + (yy + hh)) / 2);
                diffX = cxROI - cW;
                diffY = cH - cyROI;
                //cout<<diffX<<"\n";
                //cout<<diffY<<"\n";
                Point p(cxROI, cyROI);
                circle(frame, p, 3, Scalar(128,0,0), -1);
                ///////////////////////////////////////////////////////////////////////////
                }
        }
        else{
    
        }
                
                // Display frame.
                imshow("Tracking", frame);
                // Exit if ESC pressed.
                int k = waitKey(1);
                if(k == 27)
                   {
                    break;
                    }
        }
return 0;
}
///////////////////////
void sobelExtractor(const Mat img, const Rect roi, Mat& feat){
    Mat sobel[2];
    Mat patch;
    Rect region=roi;
    // extract patch inside the image
    if(roi.x<0){region.x=0;region.width+=roi.x;}
    if(roi.y<0){region.y=0;region.height+=roi.y;}
    if(roi.x+roi.width>img.cols)region.width=img.cols-roi.x;
    if(roi.y+roi.height>img.rows)region.height=img.rows-roi.y;
    if(region.width>img.cols)region.width=img.cols;
    if(region.height>img.rows)region.height=img.rows;
    patch=img(region).clone();
    cvtColor(patch,patch, COLOR_BGR2GRAY);
    // add some padding to compensate when the patch is outside image border
    int addTop,addBottom, addLeft, addRight;
    addTop=region.y-roi.y;
    addBottom=(roi.height+roi.y>img.rows?roi.height+roi.y-img.rows:0);
    addLeft=region.x-roi.x;
    addRight=(roi.width+roi.x>img.cols?roi.width+roi.x-img.cols:0);
             
    copyMakeBorder(patch,patch,addTop,addBottom,addLeft,addRight,BORDER_REPLICATE);
    
    Sobel(patch, sobel[0], CV_32F,1,0,1);
    Sobel(patch, sobel[1], CV_32F,0,1,1);
    
    merge(sobel,2,feat);
    
    feat=feat/255.0-0.5; // normalize to range -0.5 .. 0.5
}
////////////////////////////////////////////////////
struct Array MatchingMethod( int, void* )
    {
    /// Source image to display
    Mat frame;
    struct Array a;
    /////////
    for(int i=1; i<=4; i++){
    img.copyTo( frame );
    //  break;
    //}
    //////////////////////////
    cv::cuda::setDevice(0); // initialize CUDA  
    // convert from mat to gpumat
    cv::cuda::GpuMat image_d(img);
    cv::cuda::GpuMat templ_d(templ);
    cv::cuda::GpuMat result;
    // GPU -> NG
    cv::Ptr<cv::cuda::TemplateMatching> alg = 
    cv::cuda::createTemplateMatching(image_d.type(), cv::TM_CCOEFF_NORMED);
    alg->match(image_d, templ_d, result);  // no return.
    
    //cv::cuda::normalize(result, result, 0, 1, cv::NORM_MINMAX, -1);
    double max_value, min_value;
    cv::Point location;
    cv::cuda::minMaxLoc(result, &min_value, &max_value, 0, &location);
    /////////////////////////
    double THRESHOLD = 3e-09;  //0.3;
    
    if( min_value <= THRESHOLD) {
        //struct Array a;
        a.arr[0] = location.x;
        a.arr[1] = location.y;
        cout<<"Hi"<<endl;
    }   
 }
    if(flag==true){
    return a;
    flag = false;
        }
       
      //}
    }

*//https://github.com/opencv/opencv_contrib/blob/master/modules/tracking/samples/samples_utility.hpp
    // Opencv link 
    // https://techawarey.com/programming/install-opencv-c-c-in-ubuntu-18-04-lts-step-by-step-guide/#Summary
    // Compile command
    // g++ test.cpp -o testoutput -std=c++11 `pkg-config --cflags --libs opencv`
    // ./testoutput*

Aucun commentaire:

Enregistrer un commentaire