<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                ## OpenCV 學習(直線擬合) Hough 變換可以提取圖像中的直線。但是提取的直線的精度不高。而很多場合下,我們需要精確的估計直線的參數,這時就需要進行直線擬合。 直線擬合的方法很多,比如一元線性回歸就是一種最簡單的直線擬合方法。但是這種方法不適合用于提取圖像中的直線。因為這種算法假設每個數據點的X 坐標是準確的,Y 坐標是帶有高斯噪聲的。可實際上,圖像中的每個數據點的XY 坐標都是帶有噪聲的。 下面就來講講適用于提取圖像中直線的直線擬合算法。 一個點 (xi,yi) 到直線的距離用 ri 來表示。 所謂直線擬合,就是找到一條直線,使得: ∑ρ(ri) 最小。 ρ(r) 是距離函數。ρ(r) 函數取不同的形式,對應不同的直線擬合方法。OpenCV 中支持 6 種不同的ρ(r) 函數形式。分別是: CV_DIST_L2 ρ(r)=r22 這種方法是以距離平方和為擬合判據。也就是常見的最小二乘擬合算法,運行速度也最快。但是這個算法也有個很大的問題,就是當干擾點離直線較遠時,一個干擾點就可能將整條擬合直線拉偏了。簡單的說就是對干擾點的魯棒性不夠。所以后來又提出了其他的函數。 CV_DIST_L1 ρ(r)=r CV_DIST_L12 ρ(r)=2(1+r22??????√?1) CV_DIST_FAIR ρ(r)=C2(rC?log(1+rC)) 其中 C = 1.3998 CV_DIST_WELSCH ρ(r)=C22(1?exp(?(rC)2)) 其中 C = 2.9846 CV_DIST_HUBER ρ(r)={r22C(r?C2)if??r<C,otherwise. 其中 C = 1.345 后面這 5 種函數我知道第一種,其他的不知道是怎么來的。OpenCV 的幫助文檔給出了一個鏈接:[M-estimator](https://en.wikipedia.org/wiki/M-estimator) 但是這個頁面也被墻了。 下面來說說 OpenCV 提供的直線擬合函數。函數原型如下: ~~~ void fitLine( InputArray points, OutputArray line, int distType, double param, double reps, double aeps ); ~~~ distType 指定擬合函數的類型,可以取 CV_DIST_L2、CV_DIST_L1、CV_DIST_L12、CV_DIST_FAIR、CV_DIST_WELSCH、CV_DIST_HUBER。 param 就是 CV_DIST_FAIR、CV_DIST_WELSCH、CV_DIST_HUBER 公式中的C。如果取 0,則程序自動選取合適的值。 reps 表示直線到原點距離的精度,建議取 0.01。 aeps 表示直線角度的精度,建議取 0.01。 計算出的直線信息存放在 line 中,為 cv::Vec4f 類型。line[0]、line[1] 存放的是直線的方向向量。line[2]、line[3] 存放的是直線上一個點的坐標。 如果直線用 y=kx+b 來表示,那么 k = line[1]/line[0],b = line[3] - k * line[2]。 如果直線用 ρ=xcosθ+ysinθ 來表示, 那么 θ=arctank+π2 下面是個測試圖像: ![這里寫圖片描述](https://box.kancloud.cn/2016-04-26_571f1db6b28d6.jpg "") 圖像中有一條直線和一些干擾圖案。 下面的代碼可以從圖像中提取出需要的坐標點。 ~~~ std::vector<cv::Point> getPoints(cv::Mat &image, int value) { int nl = image.rows; // number of lines int nc = image.cols * image.channels(); std::vector<cv::Point> points; for (int j = 0; j < nl; j++) { uchar* data = image.ptr<uchar>(j); for (int i = 0; i < nc; i++) { if(data[i] == value) { points.push_back(cv::Point(i, j)); } } } return points; } ~~~ 下面的代碼可以在圖中畫一條直線。 ~~~ void drawLine(cv::Mat &image, double theta, double rho, cv::Scalar color) { if (theta < PI/4. || theta > 3.*PI/4.)// ~vertical line { cv::Point pt1(rho/cos(theta), 0); cv::Point pt2((rho - image.rows * sin(theta))/cos(theta), image.rows); cv::line( image, pt1, pt2, cv::Scalar(255), 1); } else { cv::Point pt1(0, rho/sin(theta)); cv::Point pt2(image.cols, (rho - image.cols * cos(theta))/sin(theta)); cv::line(image, pt1, pt2, color, 1); } } ~~~ 下面的代碼是程序的主體。 ~~~ int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); cv::Mat image = imread("c:\\line_test.png", cv::IMREAD_GRAYSCALE); std::vector<cv::Point> points = getPoints(image, 0); cv::Vec4f line; cv::fitLine(points, line, CV_DIST_HUBER , 0, 0.01, 0.01); double cos_theta = line[0]; double sin_theta = line[1]; double x0 = line[2], y0 = line[3]; double phi = atan2(sin_theta, cos_theta) + PI / 2.0; double rho = y0 * cos_theta - x0 * sin_theta; std::cout << "phi = " << phi / PI * 180 << std::endl; std::cout << "rho = " << rho << std::endl; drawLine(image, phi, rho, cv::Scalar(0)); double k = sin_theta / cos_theta; double b = y0 - k * x0; double x = 0; double y = k * x + b; std::cout << k << std::endl; std::cout << b << std::endl; //cv::line(image, Point(x0,y0), Point(x,y), cv::Scalar(255), 1); imshow("", image); return a.exec(); } ~~~ ![這里寫圖片描述](https://box.kancloud.cn/2016-04-26_571f1db6c8af1.jpg "") 如果直線擬合類型選擇 CV_DIST_L2。那么效果就沒這么好了。代碼不貼了,就貼個結果。 ![這里寫圖片描述](https://box.kancloud.cn/2016-04-26_571f1db6de85e.jpg "")
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看