霍夫圆形变换

时间:2018-05-02 17:09:06

标签: c++ opencv hough-transform

我试图使用渐变方向实现Hough变换。我知道OpenCv中有一个实现,但我想自己做。

我正在使用Sobel获得X和Y渐变。然后为每个像素

  • magnitute ---> sqrt(sobelX^2 + sobelY^2)
  • 指示 - > atan2(sobelY,sobelX) * 180/PI

如果幅度高于220(几乎是黑色),这就是边缘。 然后方向用于圆方程。

但结果是不可接受的。有什么帮助吗?

我知道有cv::polarcv::cartToPolar,但我想优化代码,以便所有方程式都可以在飞行中计算,没有空循环。

Result of HoughTransform

cv::Mat sobelX,sobelY;
        Sobel(mat, sobelX, CV_32F, 1, 0, kernelSize, 1, 0, cv::BORDER_REPLICATE);
        Sobel(mat, sobelY, CV_32F, 0, 1, kernelSize, 1, 0, cv::BORDER_REPLICATE);
        //cv::Canny(mat,mat,100,200,kernelSize,false);
        debug::showImage("sobelX",sobelX);
        debug::showImage("SobelY",sobelY);
        debug::showImage("MAT",mat);
        cv::Mat magnitudeMap,angleMap;
    magnitudeMap = cv::Mat::zeros(mat.rows,mat.cols,mat.type());
    angleMap = cv::Mat::zeros(mat.rows,mat.cols,mat.type());
        std::vector<cv::Mat> hough_spaces(max);
        for(int i=0; i<max; ++i)
        {
            hough_spaces[i] = cv::Mat::zeros(mat.rows,mat.cols,mat.type());
        }
        for(int x=0; x<mat.rows; ++x)
        {
            for(int y=0; y<mat.cols; ++y)
            {

                const float magnitude = sqrt(sobelX.at<uchar>(x,y)*sobelX.at<uchar>(x,y)+sobelY.at<uchar>(x,y)*sobelY.at<uchar>(x,y));
                const float theta= atan2(sobelY.at<uchar>(x,y),sobelX.at<uchar>(x,y)) * 180/CV_PI;
                magnitudeMap.at<uchar>(x,y) = magnitude;
                if(magnitude > 225)//mat.at<const uchar>(x,y) == 255)
                {
                    for(int radius=min; radius<max; ++radius)
                    {

                        const int a = x - radius * cos(theta);//lookup::cosArray[static_cast<int>(theta)];//+ 0.5f;
                        const int b = y - radius * sin(theta);//lookup::sinArray[static_cast<int>(theta)]; //+ 0.5f;
                        if(a >= 0 && a <hough_spaces[radius].rows && b >= 0 && b<hough_spaces[radius].cols)                             {
                            hough_spaces[radius].at<uchar>(a,b)+=10;
                        }


                    }
                }
            }
        }
        debug::showImage("magnitude",magnitudeMap);
        for(int radius=min; radius<max; ++radius)
        {
            double min_f,max_f;
            cv::Point min_loc,max_loc;
            cv::minMaxLoc(hough_spaces[radius],&min_f,&max_f,&min_loc,&max_loc);
            if(max_f>=treshold)
            {
                circles.emplace_back(cv::Point3f(max_loc.x,max_loc.y,radius));
                // debug::showImage(std::to_string(radius).c_str(),hough_spaces[radius]);

            }
        }
        circles.shrink_to_fit();

0 个答案:

没有答案