日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

opencv实现阈值分割

發布時間:2024/8/1 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 opencv实现阈值分割 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

      • 基礎函數
      • 直方圖閾值
        • 實現
        • threshold 函數使用
      • 三角法閾值
        • 實現
      • 迭代法閾值
        • 算法步驟
        • Python語法補充
        • 實現
      • 大津法
        • 理論
        • cv實現
        • 底層復現
      • 自適應閾值
        • 理論
        • 具體操作步驟
        • 優化
        • CV實現
        • 底層復現

基礎函數

在此列出,后面將直接使用,不再贅述

  • 導入庫
  • import cv2 as cv import numpy as np import matplotlib.pyplot as plt
  • 展示函數
  • def show(img):if img.ndim == 2:plt.imshow(img, cmap='gray', vmin=0, vmax=255)else:img = cv.cvtColor(img, cv.COLOR_BGR2RGB)plt.imshow(img)plt.show()

    直方圖閾值

    算法描述:根據圖像灰度直方圖,人工尋找閾值
    算法特點:適用雙峰圖像

    實現

    導入圖片

    img = cv.imread('pic/eagle.jpg', 0) show(img)


    畫出直方圖

    plt.hist(img.ravel(), 256, [0, 256]) plt.show()

    plt.hist(img.flatten(), np.arange(-0.5, 256, 1), color='g') plt.show()


    二值化

    _, img_bin = cv.threshold(img, 125, 255, cv.THRESH_BINARY) show(img_bin)

    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])

    三角法自動尋找閾值,第二個參數隨便寫就行

    迭代法閾值

    算法步驟

  • 選取初始分割閾值,通常可選圖像灰度平均值TTT
  • 根據閾值TTT將圖像像素分割為背景和前景,分別求出兩者的平均灰度T0和T1T_0和T_1T0?T1?
  • 計算新的閾值T′=T0+T12T'={T_0+T_1 \over 2}T=2T0?+T1??
  • T==T′T==T'T==T,則迭代結束,TTT即為最終閾值。否則令T=T′T=T'T=T,轉第(2)步。
  • 前景為>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?=1mˉ可簡化為
    σ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

    自適應閾值

    理論

    算法思想:局部二值化

    全局二值化容易受陰影影響,所以可以局部二值化。自適應閾值分割的本質就是局部二值化。

    具體操作步驟

  • 對某個像素值,原來為SSS,取其周圍的n×nn \times nn×n的區域,求區域均值或高斯加權值,記為T;
  • 對8位圖像,如果S>TS>TS>T,則該像素點二值化為255,否則為0.
  • 優化

  • 在實際操作中,通過卷積操作,即均值模糊或高斯模糊,實現求區域均值或高斯加權值;
  • 上面步驟中,增加超參數CCCCCC可以為任何實數,當S>T?CS>T-CS>T?C時,把原像素二值化為255.
  • 也可以設置超參數 α∈[0,1]\alpha \in [0,1]α[0,1],當S>(1?α)TS>(1-\alpha)TS>(1?α)T時把原像素點二值化為255,通常取α=0.15\alpha=0.15α=0.15
  • 注:鄰域大小一般要大于目標大小,但也不能太大,否則效果不好。

    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α實現

    img = cv.imread('pic/page.jpg', 0)alpha = 0.15 winSize = 21img_blur = cv.GaussianBlur(img, (winSize, winSize), 5) img_bin = np.uint8(img > (1-alpha) * img_blur) * 255 show(img_bin)

    對于參數不是很敏感

    總結

    以上是生活随笔為你收集整理的opencv实现阈值分割的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。