clustering image segments in opencv

后端 未结 4 1605
遥遥无期
遥遥无期 2021-02-06 02:11

I am working on motion detection with non-static camera using opencv. I am using a pretty basic background subtraction and thresholding approach to get a broad sense of all that

4条回答
  •  你的背包
    2021-02-06 02:45

    this problem can be almost perfectly solved by dbscan clustering algorithm. Below, I provide the implementation and result image. Gray blob means outlier or noise according to dbscan. I simply used boxes as input data. Initially, box centers were used for distance function. However for boxes, it is insufficient to correctly characterize distance. So, the current distance function use the minimum distance of all 8 corners of two boxes.

    #include "opencv2/opencv.hpp"
    using namespace cv;
    #include 
    #include 
    
    template 
    inline std::string to_string (const T& t)
    {
        std::stringstream ss;
        ss << t;
        return ss.str();
    }
    
    class DbScan
    {
    public:
        std::map labels;
        vector& data;
        int C;
        double eps;
        int mnpts;
        double* dp;
        //memoization table in case of complex dist functions
    #define DP(i,j) dp[(data.size()*i)+j]
        DbScan(vector& _data,double _eps,int _mnpts):data(_data)
        {
            C=-1;
            for(int i=0;i neighbours = regionQuery(i);
                    if(neighbours.size() neighbours)
        {
            labels[p]=C;
            for(int i=0;i neighbours_p = regionQuery(neighbours[i]);
                    if (neighbours_p.size() >= mnpts)
                    {
                        expandCluster(neighbours[i],neighbours_p);
                    }
                }
            }
        }
    
        bool isVisited(int i)
        {
            return labels[i]!=-99;
        }
    
        vector regionQuery(int p)
        {
            vector res;
            for(int i=0;i > getGroups()
        {
            vector > ret;
            for(int i=0;i<=C;i++)
            {
                ret.push_back(vector());
                for(int j=0;j= 1.0f)
                fH = 0.0f;
    
            fH *= 6.0; // sector 0 to 5
            fI = floor( fH ); // integer part of h (0,1,2,3,4,5 or 6)
            iI = (int) fH; // " " " "
            fF = fH - fI; // factorial part of h (0 to 1)
    
            p = fV * ( 1.0f - fS );
            q = fV * ( 1.0f - fS * fF );
            t = fV * ( 1.0f - fS * ( 1.0f - fF ) );
    
            switch( iI ) {
            case 0:
                fR = fV;
                fG = t;
                fB = p;
                break;
            case 1:
                fR = q;
                fG = fV;
                fB = p;
                break;
            case 2:
                fR = p;
                fG = fV;
                fB = t;
                break;
            case 3:
                fR = p;
                fG = q;
                fB = fV;
                break;
            case 4:
                fR = t;
                fG = p;
                fB = fV;
                break;
            default: // case 5 (or 6):
                fR = fV;
                fG = p;
                fB = q;
                break;
            }
        }
    
        // Convert from doubles to 8-bit integers
        int bR = (int)(fR * double_TO_BYTE);
        int bG = (int)(fG * double_TO_BYTE);
        int bB = (int)(fB * double_TO_BYTE);
    
        // Clip the values to make sure it fits within the 8bits.
        if (bR > 255)
            bR = 255;
        if (bR < 0)
            bR = 0;
        if (bG >255)
            bG = 255;
        if (bG < 0)
            bG = 0;
        if (bB > 255)
            bB = 255;
        if (bB < 0)
            bB = 0;
    
        // Set the RGB cvScalar with G B R, you can use this values as you want too..
        return cv::Scalar(bB,bG,bR); // R component
    }
    
    int main(int argc,char** argv )
    {
        Mat im = imread("c:/data/football.png",0);
        std::vector > contours;
        std::vector hierarchy;
        findContours(im.clone(), contours, hierarchy, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
    
        vector boxes;
        for(size_t i = 0; i < contours.size(); i++)
        {
            Rect r = boundingRect(contours[i]);
            boxes.push_back(r);
        }
        DbScan dbscan(boxes,20,2);
        dbscan.run();
        //done, perform display
    
        Mat grouped = Mat::zeros(im.size(),CV_8UC3);
        vector colors;
        RNG rng(3);
        for(int i=0;i<=dbscan.C;i++)
        {
            colors.push_back(HSVtoRGBcvScalar(rng(255),255,255));
        }
        for(int i=0;i

    result

提交回复
热议问题