Estimate Image line gradient ( not pixel gradient)

烈酒焚心 提交于 2019-12-06 15:36:27

Here is a small program that computes the tangent at each contour pixel location in a very simple way (there exist other and probably better ways! the easy ones are: http://en.wikipedia.org/wiki/Finite_difference#Forward.2C_backward.2C_and_central_differences):

  1. for a contour pixel c_{i} get the neighbors c_{i-1} and c_{i+1}
  2. tangent direction at c_i is (c_{i-1} - c_{i+1}

So this is all on CONTOUR PIXELS but maybe you could so something similar if you compute the orthogonal to the full image pixel gradient... not sure about that ;)

here's the code:

int main()
{
    cv::Mat input = cv::imread("../inputData/ContourTangentBin.png");

    cv::Mat gray;
    cv::cvtColor(input,gray,CV_BGR2GRAY);

    // binarize
    cv::Mat binary = gray > 100;

    // find contours
    std::vector<std::vector<cv::Point> > contours;
    std::vector<cv::Vec4i> hierarchy;
    findContours( binary.clone(), contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE );    // CV_CHAIN_APPROX_NONE to get each single pixel of the contour!!


    for( int i = 0; i< contours.size(); i++ )
    {
        std::vector<cv::Point> & cCont = contours[i];
        std::vector<cv::Point2f> tangents;

        if(cCont.size() < 3) continue;

        // 1. compute tangent for first point
        cv::Point2f cPoint = cCont.front();
        cv::Point2f tangent = cCont.back() - cCont.at(1);   // central tangent => you could use another method if you like to
        tangents.push_back(tangent);

        // display first tangent
        cv::Mat tmpOut = input.clone();
        cv::line(tmpOut, cPoint + 10*tangent, cPoint-10*tangent, cv::Scalar(0,0,255),1);
        cv::imshow("tangent",tmpOut);
        cv::waitKey(0);

        for(unsigned int j=1; j<cCont.size(); ++j)
        {
            cPoint = cCont[j];
            tangent = cCont[j-1] - cCont[(j+1)%cCont.size()];   // central tangent => you could use another method if you like to
            tangents.push_back(tangent);

            //display current tangent:
            tmpOut = input.clone();
            cv::line(tmpOut, cPoint + 10*tangent, cPoint-10*tangent, cv::Scalar(0,0,255),1);
            cv::imshow("tangent",tmpOut);
            cv::waitKey(0);
            //if(cv::waitKey(0) == 's') cv::imwrite("../outputData/ContourTangentTangent.png", tmpOut);
        }

        // now there are all the tangent directions in "tangents", do whatever you like with them
    }

    for( int i = 0; i< contours.size(); i++ )
    {
        drawContours( input, contours, i, cv::Scalar(0,255,0), 1, 8, hierarchy, 0 );
    }

    cv::imshow("input", input);
    cv::imshow("binary", binary);
    cv::waitKey(0);
    return 0;
}

I used this image:

and got outputs like:

in the result you get a vector with a 2D tangent information (line direction) for each pixel of that contour.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!