Finding the “fitLine ” of contours in OpenCV

后端 未结 2 1585
[愿得一人]
[愿得一人] 2021-02-02 02:22

I\'m a program that find contours in a stream, for example :

\"contours\"

I want to find \"set of points \

2条回答
  •  心在旅途
    2021-02-02 02:47

    Interesting task :) Here is my solution:

    enter image description here

    Here is code:

    #include 
    #include 
    #include 
    #include 
    #include 
    #include "opencv2/opencv.hpp"
    #include "fstream"
    #include "iostream"
    using namespace std;
    using namespace cv;
    
    
    int Thinning(unsigned char * ucBinedImg, unsigned char * ucThinnedImage, long lWidth, long lHeight, long lIterativeLimit)
    {
        if(ucBinedImg == NULL)
            return -1;
    
        if(ucThinnedImage == NULL)
            return -2;
    
        if(lIterativeLimit == -1)
            lIterativeLimit = 60000;
    
        unsigned char x1, x2, x3, x4, x5, x6, x7, x8, xp;
        unsigned char g1, g2, g3, g4;
        unsigned char b1, b2, b3, b4;
        unsigned char np1, np2, npm;
        unsigned char *pUp, *pDown, *pImg;
        long    lDeletedPoints = 0;
    
        // set border 
        memcpy(ucThinnedImage, ucBinedImg, lWidth*lHeight);
    
        for(long it=0; itnp2?np2:np1;
                    g2 = npm>=2 && npm<=3;
    
                    g3 = (x1 && (x2 || x3 || !x8)) == 0;
                    g4 = (x5 && (x6 || x7 || !x4)) == 0;
    
                    // first part
                    if(g1 && g2 && g3)
                    {
                        // delete this point
                        ucThinnedImage[lWidth*i + j] = 0;
                        ++lDeletedPoints;
                    }
                }
    
            }
    
            //syn
            memcpy(ucBinedImg, ucThinnedImage, lWidth*lHeight);
    
            for(long i=1; inp2?np2:np1;
                    g2 = npm>=2 && npm<=3;
    
                    g3 = (x1 && (x2 || x3 || !x8)) == 0;
                    g4 = (x5 && (x6 || x7 || !x4)) == 0;
    
                    // second part
                    if(g1 && g2 && g4)
                    {
                        // delete this point
                        ucThinnedImage[lWidth*i + j] = 0;
                        ++lDeletedPoints;
                    }
    
                }
    
            }
            //syn
            memcpy(ucBinedImg, ucThinnedImage, lWidth*lHeight);
    
            // if no points to be deleted
            if(lDeletedPoints == 0)
                break;
    
        }
    
        // clear edge bar
        for(long i=0; i=lHeight-16)
                    ucThinnedImage[i*lWidth+j] = 0;
                else if(j<16)
                    ucThinnedImage[i*lWidth+j] = 0;
                else if(j>=lWidth-16)
                    ucThinnedImage[i*lWidth+j] = 0;
            }
        }
    
        return 0;
    }
    
    void Thinning(Mat& src,Mat& dst,long IterativeLimit=-1)
    {
        Mat bin_img=src&1;
        if(!dst.empty()){dst.release();}
        dst=Mat::zeros(src.size(),CV_8UC1);
        Thinning(bin_img.data,dst.data,bin_img.cols,bin_img.rows,IterativeLimit);
        dst*=255;
    }
    
    int main(int argc, char* argv[])
    {
        namedWindow("source");
        namedWindow("result");
    
        Mat img=imread("raw_image.jpg",0);
        cv::threshold(img,img,128,255,cv::THRESH_BINARY);
    
        int erosion_size=5;
        Mat element = getStructuringElement( cv::MORPH_ELLIPSE,Size( 2*erosion_size + 1, 2*erosion_size+1 ),Point( erosion_size, erosion_size ) );
    
        cv::dilate(img,img,element);
    
        Mat thinned;
        Thinning(img,thinned);
    
        vector lines;
        HoughLines(thinned, lines, 0.5, CV_PI/360, 50, 0, 0 );
    
        float hist_theta[2]={0,0};
        float hist_rho[2]={0,0};
        float n[2]={0,0};
        for( size_t i = 0; i < lines.size(); i++ )
        {
            float rho = lines[i][0], theta = lines[i][1];
            if(fabs(theta-CV_PI/2)

    Here is a hack in this source it uses two 1D histograms for postprocessing. In real life application it should use 2D histogram for close lines averaging.

提交回复
热议问题