使用OpenCV作圖像處理與分析的時候,常常會遇到須要進行曲線擬合與圓擬合的場景,不少OpenCV開發者對此倒是束手無策,其實OpenCV中是有現成的函數來實現圓擬合與直線擬合的,並且還會告訴你擬合的圓的半徑是多少,簡直是超級方便,另一個經常使用到的場景就是曲線擬合,常見的是基於多項式擬合,能夠根據設定的多項式冪次生成多項式方程,而後根據方程進行一系列的點生成,造成完整的曲線,這個車道線檢測,輪廓曲線擬合等場景下特別有用。下面就經過兩個簡單的例子來分別學習一下曲線擬合與圓擬合的應用。html
基於Numpy包的polyfit函數實現,其支持的三個參數分別是x點集合、y點集合,以及多項式的冪次。獲得多項式方程之後,就能夠完整擬合曲線,圖中有以下四個點:
java
調用polyfit生成的二階多項式以下:
ide
擬合結果以下:
函數
使用三階多項式擬合,調用polyfit生成的多項式方程以下:
學習
生成的擬合曲線以下:
ui
使用polyfit進行曲線擬合時候須要注意的是,多項式的冪次最大是數據點數目N - 1冪次多項式,好比有4個點,最多生成3階多項式擬合。上述演示的完整代碼實現以下:code
def circle_fitness_demo(): image = np.zeros((400, 400, 3), dtype=np.uint8) x = np.array([30, 50, 100, 120]) y = np.array([100, 150, 240, 200]) for i in range(len(x)): cv.circle(image, (x[i], y[i]), 3, (255, 0, 0), -1, 8, 0) cv.imwrite("D:/curve.png", image) poly = np.poly1d(np.polyfit(x, y, 3)) print(poly) for t in range(30, 250, 1): y_ = np.int(poly(t)) cv.circle(image, (t, y_), 1, (0, 0, 255), 1, 8, 0) cv.imshow("fit curve", image) cv.imwrite("D:/fitcurve.png", image)
圓的擬合是基於輪廓發現的結果,對發現的近似圓的輪廓,經過圓擬合能夠獲得比較好的顯示效果,輪廓發現與擬合的API分別爲findContours與fitEllipse,
有圖像以下:
視頻
使用輪廓發現與圓擬合處理結果以下:
htm
紅色表示擬合的圓,藍色是圓的中心位置
上述完整的演示代碼以下:blog
def circle_fitness_demo(): src = cv.imread("D:/javaopencv/c2.png") cv.imshow("input", src) src = cv.GaussianBlur(src, (3, 3), 0) gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY) ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU) cv.imshow("binary", binary) image, contours, hierachy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE) for i in range(len(contours)): rrt = cv.fitEllipse(contours[i]) cv.ellipse(src, rrt, (0, 0, 255), 2, cv.LINE_AA) x, y = rrt[0] cv.circle(src, (np.int(x), np.int(y)), 4, (255, 0, 0), -1, 8, 0) cv.imshow("fit circle", src) cv.imwrite("D:/fitcircle.png", src)
學習OpenCV Python 系列課程
OpenCV Python零基礎入門視頻教程
OpenCV Python圖像處理進階視頻教程
吾心信其可行,則移山填海之難,終有成功之日;吾心信其不可行,則反掌折枝之易,亦無收效之期也