opencv实现阈值分割
文章目錄
- 基礎函數
- 直方圖閾值
- 實現
- threshold 函數使用
- 三角法閾值
- 實現
- 迭代法閾值
- 算法步驟
- Python語法補充
- 實現
- 大津法
- 理論
- cv實現
- 底層復現
- 自適應閾值
- 理論
- 具體操作步驟
- 優化
- CV實現
- 底層復現
基礎函數
在此列出,后面將直接使用,不再贅述
直方圖閾值
算法描述:根據圖像灰度直方圖,人工尋找閾值
算法特點:適用雙峰圖像
實現
導入圖片
img = cv.imread('pic/eagle.jpg', 0) show(img)
畫出直方圖
二值化
threshold 函數使用
三角法閾值
論文:AUTOMATIC MEASUREMENT OF SISTER CHROMATID EXCHANGE FREQUENCY
算法思想:幾何法,適用單峰圖像
距離最遠的點,即為分割點
實現
img = cv.imread('pic/blossom', 0) show(img) plt.hist(img.flattern(), np.arange(-0.5, 256, 1), color='g') plt.show() th, img_ = cv.threshold(img, 0, 255, cv.THRESH_TRIANGLE) print(th) show(np.hstack([img, img_bin])三角法自動尋找閾值,第二個參數隨便寫就行
迭代法閾值
算法步驟
前景為>T>T>T的部分,背景為<T<T<T的部分
Python語法補充
a = np.random.randint(0, 10, (4, 4)) a[a <= 5] a[a <= 5].mean()實現
img = cv.imread('pic/eagle', 0)T = img.mean()while True:t0 = img[img < T].mean() // 背景平均灰度值t1 = img[img >= T].mean() // 前景平均灰度值t = (t0 + t1) / 2print(T, t)if T == t: // 可適當放寬條件, abs(T-t) < 1breakT = t T = int(T) // 浮點數沒有用print(f"Best Threshold = {T}")Best Threshold = 120
大津法
理論
算法思想:最大類間方差
對于給定閾值TTT,可以將圖像分為目標和背景。其中背景點數占圖像比例為p0p_0p0?,平均灰度值為m0m_0m0?。而且標定數占圖像比例為p1p_1p1?,平均灰度值為m1m_1m1?,其中滿足
p0+p1=1p_0+p_1=1p0?+p1?=1
整幅圖像的平均灰度值為常數,跟閾值無關,且為
mˉ=p0m0+p1m1\bar m = p_0m_0+p_1m_1mˉ=p0?m0?+p1?m1?
類間方差為
σ2=p0(m0?mˉ)2+p1(m1?mˉ)2\sigma^2=p_0(m_0-\bar m)^2+p_1(m_1-\bar m)^2σ2=p0?(m0??mˉ)2+p1?(m1??mˉ)2
代入p0+p1=1和mˉp_0+p_1=1和\bar mp0?+p1?=1和mˉ可簡化為
σ2=p0p1(m0?m1)2\sigma^2=p_0p_1(m_0-m_1)^2σ2=p0?p1?(m0??m1?)2
遍歷灰度值,找出能使σ2\sigma^2σ2最大的值
cv實現
img = cv.imread('pic/eagle.jpg', 0)th, img_bin = cv.threshod(img, -1, 255, cv.THRESH_OTSU) print(th) show(img_bin)底層復現
img = cv.imread('pic/eagle', 0)Sigma = -1 T = 0for t in range(0, 256):bg = img[img <= t]obj = img[img > t]p0 = bg.size / img.sizep1 = obj.size / img.sizem0 = 0 if obj.size==0 else bg.mean()m1 = 0 if obj.size==0 else obj.mean()sigma = p0*p1*(m0-m1)**2if sigma > Sigma:Sigma = sigmaT = t自適應閾值
理論
算法思想:局部二值化
全局二值化容易受陰影影響,所以可以局部二值化。自適應閾值分割的本質就是局部二值化。
具體操作步驟
優化
注:鄰域大小一般要大于目標大小,但也不能太大,否則效果不好。
CV實現
img = cv.imread('pic/page', 0) show(img) img_bin = cv.adaptiveThreshold(img, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 21, 6) show(img_bin)6 就是上面的C,21就是核大小
底層復現
一. 通過超參數C實現
img = cv.imrad('pic/page', 0)C = 0 winSize = 21 // 和一個字體差不多大img_blur = cv.blur(img, (winSize, winSize)) show(img > img_blur) C = 6img_bin = np.uint8(img>img_blur.astype(np.int) - C) * 255show(img_bin)
二. 通過超參數α\alphaα實現
對于參數不是很敏感
總結
以上是生活随笔為你收集整理的opencv实现阈值分割的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 中国生物能源行业运行现状调研及未来发展前
- 下一篇: 常见物质相对介电常数(室温,频率低于1k