全解析:從Otsu到自適應(yīng)閾值的實(shí)戰(zhàn)指南)
1. 項(xiàng)目概述從像素到?jīng)Q策的“黑白分明”在圖像處理的世界里我們常常需要讓計(jì)算機(jī)“看懂”圖像并從中提取關(guān)鍵信息。無(wú)論是識(shí)別文檔上的文字、檢測(cè)生產(chǎn)線(xiàn)上的產(chǎn)品瑕疵還是從醫(yī)學(xué)影像中分割出病灶區(qū)域一個(gè)基礎(chǔ)且至關(guān)重要的步驟就是將一張色彩或灰度豐富的圖像簡(jiǎn)化為只有“黑”與“白”兩種顏色的圖像。這個(gè)過(guò)程就是“圖像二值化”。聽(tīng)起來(lái)簡(jiǎn)單不就是把圖變黑白嗎但實(shí)際操作中如何讓這個(gè)“黑白”分得恰到好處讓目標(biāo)信息清晰保留、背景干擾有效剔除這里面門(mén)道可深了。我處理過(guò)無(wú)數(shù)涉及圖像分析的工業(yè)項(xiàng)目可以說(shuō)二值化這一步的成敗直接決定了后續(xù)所有算法是“事半功倍”還是“事倍功半”甚至是“全盤(pán)皆輸”。圖像二值化的核心是找到一個(gè)“分水嶺”——我們稱(chēng)之為閾值。所有像素的亮度或顏色強(qiáng)度與這個(gè)閾值進(jìn)行比較大于閾值的歸為白色通常用255表示小于等于閾值的歸為黑色通常用0表示。這個(gè)“一刀切”的過(guò)程將連續(xù)的灰度信息離散化為非黑即白的二值信息極大地壓縮了數(shù)據(jù)量并突出了我們關(guān)心的輪廓、形狀或紋理特征。然而現(xiàn)實(shí)中的圖像往往光照不均、背景復(fù)雜、目標(biāo)與背景對(duì)比度低如何自動(dòng)、魯棒地確定這個(gè)“黃金閾值”就是二值化技術(shù)要解決的核心問(wèn)題。今天我們就來(lái)徹底拆解這個(gè)看似簡(jiǎn)單實(shí)則內(nèi)涵豐富的技術(shù)從原理到方法從經(jīng)典算法到實(shí)戰(zhàn)調(diào)參讓你不僅能“會(huì)用”更能“懂為什么這么用”在項(xiàng)目中做出最合適的選擇。2. 核心原理與全局閾值法尋找那個(gè)“神奇的數(shù)字”2.1 灰度化二值化的必經(jīng)之路在絕大多數(shù)情況下二值化處理的對(duì)象是灰度圖像而非彩色圖像。這是因?yàn)椴噬珗D像包含R、G、B三個(gè)通道直接二值化需要分別處理三個(gè)通道并合并結(jié)果往往不可控且意義不明確。因此第一步通常是將彩色圖像轉(zhuǎn)換為灰度圖像?;叶然皇呛?jiǎn)單取平均值。最符合人眼感知的經(jīng)典公式是Gray 0.299 * R 0.587 * G 0.114 * B這個(gè)權(quán)重系數(shù)源于人眼對(duì)綠色最敏感對(duì)藍(lán)色最不敏感。轉(zhuǎn)換后圖像中每個(gè)像素就只有一個(gè)0到255之間的灰度值代表了該點(diǎn)的亮度。注意在某些特定場(chǎng)景下例如需要基于特定顏色進(jìn)行分割如檢測(cè)紅色指示燈可能會(huì)直接在某個(gè)顏色通道或經(jīng)過(guò)特定顏色空間轉(zhuǎn)換如HSV中的H通道上進(jìn)行二值化但這屬于特例。通用流程仍是先灰度化。2.2 全局固定閾值最簡(jiǎn)單粗暴的“一刀切”這是最直觀(guān)的方法手動(dòng)指定一個(gè)閾值T。如果像素灰度值 T則置為255白。如果像素灰度值 T則置為0黑。在OpenCV中使用cv2.threshold函數(shù)并指定cv2.THRESH_BINARY模式即可實(shí)現(xiàn)。import cv2 # 讀取灰度圖像 gray_img cv2.imread(document.jpg, cv2.IMREAD_GRAYSCALE) # 手動(dòng)設(shè)定閾值為127 T 127 ret, binary_img cv2.threshold(gray_img, T, 255, cv2.THRESH_BINARY)這種方法何時(shí)有效當(dāng)圖像具有極高的對(duì)比度且光照非常均勻時(shí)。例如在受控光照環(huán)境下拍攝的黑白打印文檔。但它的局限性極其明顯無(wú)法適應(yīng)光照變化和背景復(fù)雜度。同一閾值對(duì)亮處圖像可能全白對(duì)暗處圖像可能全黑。2.3 經(jīng)典全局自適應(yīng)閾值算法Otsu大津法既然手動(dòng)設(shè)定不靠譜我們需要算法自動(dòng)尋找最佳全局閾值。Otsu算法是其中的翹楚其核心思想是最大化類(lèi)間方差。它將圖像像素按閾值T分為兩類(lèi)前景目標(biāo)和背景。一個(gè)好的閾值應(yīng)該使得前景和背景這兩類(lèi)內(nèi)部的像素灰度分布盡可能集中類(lèi)內(nèi)方差小而兩類(lèi)之間的差異盡可能大類(lèi)間方差大。Otsu算法就是遍歷所有可能的閾值0-255計(jì)算每個(gè)閾值對(duì)應(yīng)的類(lèi)間方差選擇使類(lèi)間方差最大的那個(gè)閾值作為最佳閾值。數(shù)學(xué)原理簡(jiǎn)述 假設(shè)閾值為T(mén)像素總數(shù)為N。前景像素占比 w0平均灰度 u0。背景像素占比 w1平均灰度 u1。圖像總平均灰度 u w0 * u0 w1 * u1。類(lèi)間方差 g w0 * (u0 - u)^2 w1 * (u1 - u)^2。 遍歷T從0到255找到使g最大的T。在OpenCV中調(diào)用極為簡(jiǎn)單ret, binary_img_otsu cv2.threshold(gray_img, 0, 255, cv2.THRESH_BINARY cv2.THRESH_OTSU) # 注意這里的第一個(gè)參數(shù)設(shè)定的閾值會(huì)被忽略ret變量會(huì)返回算法計(jì)算出的最佳閾值。 print(fOtsu算法計(jì)算出的最佳閾值為: {ret})Otsu算法的優(yōu)勢(shì)與局限優(yōu)勢(shì)完全自動(dòng)無(wú)需參數(shù)對(duì)于具有雙峰直方圖即前景和背景的灰度分布形成兩個(gè)明顯波峰的圖像效果極佳。局限它仍然是一個(gè)全局閾值算法。當(dāng)圖像光照不均、或前景/背景的灰度分布不是雙峰狀例如背景本身就有多種灰度時(shí)Otsu會(huì)失效可能得到完全錯(cuò)誤的結(jié)果。實(shí)操心得在嘗試任何二值化之前先畫(huà)出圖像的灰度直方圖cv2.calcHist或matplotlib的hist。如果直方圖呈現(xiàn)兩個(gè)分離的波峰那么恭喜你Otsu大概率能完美工作。如果直方圖是單峰、多峰或平坦的你就需要更高級(jí)的方法了。3. 局部自適應(yīng)閾值法應(yīng)對(duì)不均光照的“分區(qū)治理”當(dāng)光照從圖像一邊亮一邊暗或者背景存在復(fù)雜紋理時(shí)全局一個(gè)閾值顯然不夠用。這時(shí)就需要局部自適應(yīng)閾值。其核心思想是為圖像中的每一個(gè)像素點(diǎn)根據(jù)其周?chē)粋€(gè)鄰域窗口內(nèi)的像素灰度分布單獨(dú)計(jì)算一個(gè)閾值。3.1 均值自適應(yīng)閾值這是最常用的局部自適應(yīng)方法之一。對(duì)于圖像中的每個(gè)像素點(diǎn)(x, y)以其為中心取一個(gè)大小為block_size x block_size的鄰域窗口。計(jì)算該窗口內(nèi)所有像素灰度值的平均值mean。將該平均值減去一個(gè)常數(shù)C作為該像素點(diǎn)的局部閾值T(x,y) mean - C。比較該像素灰度值與T(x,y)進(jìn)行二值化。在OpenCV中對(duì)應(yīng)cv2.ADAPTIVE_THRESH_MEAN_Cbinary_mean cv2.adaptiveThreshold(gray_img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, block_size11, C2)參數(shù)解析與調(diào)參經(jīng)驗(yàn)block_size鄰域窗口大小。必須是正奇數(shù)如3, 5, 11, 25...。這是最重要的參數(shù)。值太小如3閾值會(huì)對(duì)噪聲極度敏感結(jié)果圖中會(huì)出現(xiàn)大量椒鹽噪聲。值太大如51可能會(huì)過(guò)度平滑導(dǎo)致大塊區(qū)域內(nèi)部閾值趨同失去“局部”自適應(yīng)的意義尤其會(huì)模糊掉細(xì)小目標(biāo)或文字的邊緣。經(jīng)驗(yàn)法則通常從11或15開(kāi)始嘗試。目標(biāo)尺寸越大、光照變化越平緩可以適當(dāng)增大目標(biāo)細(xì)節(jié)越豐富、越細(xì)小應(yīng)使用較小的值。C從計(jì)算出的均值中減去的常數(shù)。用于微調(diào)閾值的高低。值為正降低閾值使更多像素被歸為前景變白。在背景較亮、目標(biāo)較暗時(shí)使用。值為負(fù)提高閾值使更多像素被歸為背景變黑。在背景較暗、目標(biāo)較亮?xí)r使用。通常是一個(gè)較小的整數(shù)如2, 3, 5。需要根據(jù)實(shí)際情況微調(diào)。3.2 高斯加權(quán)自適應(yīng)閾值均值法將窗口內(nèi)所有像素一視同仁。而高斯法則認(rèn)為離中心點(diǎn)越近的像素對(duì)中心點(diǎn)閾值的影響應(yīng)該越大。它使用一個(gè)高斯窗口函數(shù)對(duì)鄰域內(nèi)像素進(jìn)行加權(quán)再計(jì)算加權(quán)平均值作為閾值計(jì)算的基礎(chǔ)。在OpenCV中對(duì)應(yīng)cv2.ADAPTIVE_THRESH_GAUSSIAN_Cbinary_gaussian cv2.adaptiveThreshold(gray_img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, block_size11, C2)均值法與高斯法的選擇均值法計(jì)算更快對(duì)于大多數(shù)光照漸變的情況效果足夠好。高斯法理論上更合理能更好地抑制噪聲對(duì)邊緣的響應(yīng)更平滑。在圖像噪聲較大或?qū)吘壻|(zhì)量要求較高時(shí)優(yōu)先考慮。實(shí)測(cè)下來(lái)在文本識(shí)別等場(chǎng)景中高斯法的效果通常略?xún)?yōu)于均值法尤其是對(duì)于筆畫(huà)粘連或斷裂的改善。3.3 局部自適應(yīng)閾值的典型問(wèn)題與優(yōu)化問(wèn)題1窗口尺寸block_size的“副作用”窗口尺寸選擇不當(dāng)會(huì)在目標(biāo)物體內(nèi)部產(chǎn)生“空洞”或“陰影”效應(yīng)。例如在一個(gè)大的黑色字符內(nèi)部中心區(qū)域的局部鄰域可能全是黑色計(jì)算出的均值很低導(dǎo)致中心區(qū)域被錯(cuò)誤地二值化為白色前景形成空洞。解決方案嘗試使用高斯法其加權(quán)特性可以緩解此問(wèn)題。適當(dāng)增大常數(shù)C提高閾值使中心區(qū)域不易被“翻轉(zhuǎn)”。在二值化后進(jìn)行形態(tài)學(xué)閉運(yùn)算先膨脹后腐蝕填充小的空洞。但這可能會(huì)改變目標(biāo)形狀。問(wèn)題2在純色大背景邊緣產(chǎn)生的“光暈”或“毛邊”在目標(biāo)與背景的交界處局部窗口會(huì)同時(shí)包含前景和背景像素計(jì)算出的閾值可能是一個(gè)中間值導(dǎo)致邊界像素二值化結(jié)果不穩(wěn)定產(chǎn)生鋸齒或毛邊。解決方案這是局部自適應(yīng)方法的固有缺陷難以完全消除??梢酝ㄟ^(guò)后處理的形態(tài)學(xué)操作如開(kāi)運(yùn)算來(lái)平滑邊緣。如果對(duì)邊緣精度要求極高可能需要考慮更先進(jìn)的基于梯度或能量最小化的分割方法而非簡(jiǎn)單的閾值法。踩坑記錄我曾在一個(gè)金屬表面劃痕檢測(cè)項(xiàng)目中使用局部自適應(yīng)二值化來(lái)突出劃痕。最初block_size設(shè)為31結(jié)果劃痕在圖像明亮區(qū)域幾乎消失在暗部區(qū)域則被過(guò)度放大。后來(lái)將block_size調(diào)整為15并配合一個(gè)較小的C值才成功地在不同光照區(qū)域穩(wěn)定地提取出了劃痕。核心在于窗口大小必須小于你關(guān)心的目標(biāo)特征尺寸這樣算法才能“感知”到局部變化。4. 更高級(jí)的二值化技術(shù)與實(shí)戰(zhàn)策略當(dāng)全局法和局部自適應(yīng)法都捉襟見(jiàn)肘時(shí)我們就需要祭出更高級(jí)的策略。這些方法通常結(jié)合了圖像預(yù)處理、多步驟處理或更復(fù)雜的模型。4.1 結(jié)合預(yù)處理光照歸一化很多二值化問(wèn)題根源在于光照不均。與其在二值化算法本身硬磕不如先嘗試“撫平”光照。方法一頂帽變換Top-hat頂帽變換定義為原圖減去其開(kāi)運(yùn)算結(jié)果頂帽 原圖 - 開(kāi)運(yùn)算(原圖)。 開(kāi)運(yùn)算能消除比結(jié)構(gòu)元小的亮細(xì)節(jié)因此原圖減去開(kāi)運(yùn)算圖就得到了這些被消除的亮細(xì)節(jié)如暗背景上的亮文字。kernel cv2.getStructuringElement(cv2.MORPH_RECT, (15, 15)) # 結(jié)構(gòu)元大小需大于文字筆畫(huà)寬度 tophat cv2.morphologyEx(gray_img, cv2.MORPH_TOPHAT, kernel) # 然后對(duì) tophat 圖像使用全局閾值如Otsu即可適用場(chǎng)景暗背景上有亮目標(biāo)如黑底白字。對(duì)于白底黑字應(yīng)使用底帽變換Black-hat。方法二自適應(yīng)直方圖均衡化CLAHE普通的直方圖均衡化是全局的會(huì)過(guò)度放大噪聲。CLAHE將圖像分成小塊對(duì)每個(gè)塊進(jìn)行直方圖均衡化并用雙線(xiàn)性插值消除塊之間的邊界從而在增強(qiáng)對(duì)比度的同時(shí)抑制噪聲。clahe cv2.createCLAHE(clipLimit2.0, tileGridSize(8,8)) gray_clahe clahe.apply(gray_img) # 然后再對(duì) gray_clahe 進(jìn)行二值化適用場(chǎng)景整體對(duì)比度低且光照不均。常用于醫(yī)學(xué)圖像如X光的預(yù)處理。4.2 Sauvola算法文本二值化的利器Sauvola算法是局部自適應(yīng)閾值的一個(gè)著名變種特別為文檔圖像二值化而設(shè)計(jì)。它改進(jìn)了閾值計(jì)算公式使其對(duì)文本的灰度和局部對(duì)比度變化更魯棒。閾值計(jì)算公式為T(mén)(x,y) mean * [1 k * (std / R - 1)]其中mean和std是局部窗口內(nèi)的均值和標(biāo)準(zhǔn)差。R是標(biāo)準(zhǔn)差的動(dòng)態(tài)范圍通常取128對(duì)于8位圖像。k是一個(gè)正參數(shù)通常取0.2~0.5。k值越大閾值越接近均值對(duì)高對(duì)比度區(qū)域越敏感。OpenCV沒(méi)有直接實(shí)現(xiàn)Sauvola但我們可以用NumPy輕松實(shí)現(xiàn)def sauvola_threshold(img, window_size15, k0.2, R128): mean cv2.boxFilter(img, cv2.CV_32F, (window_size, window_size)) mean_sq cv2.boxFilter(img**2, cv2.CV_32F, (window_size, window_size)) std np.sqrt(mean_sq - mean**2) threshold mean * (1 k * (std / R - 1)) binary (img threshold).astype(np.uint8) * 255 return binarySauvola的優(yōu)勢(shì)在光照不均、背景有輕微紋理或污漬的文檔圖像上其效果通常顯著優(yōu)于基本的均值/高斯自適應(yīng)法能更好地保持筆畫(huà)連貫性抑制背景噪聲。4.3 基于梯度或邊緣的二值化對(duì)于目標(biāo)與背景邊界清晰但內(nèi)部紋理復(fù)雜的情況可以轉(zhuǎn)而利用梯度信息。思路是先計(jì)算圖像的梯度幅值如Sobel算子梯度大的地方很可能是邊緣。然后對(duì)梯度圖進(jìn)行閾值處理或者將梯度信息與灰度信息結(jié)合。# 計(jì)算梯度幅值 grad_x cv2.Sobel(gray_img, cv2.CV_64F, 1, 0, ksize3) grad_y cv2.Sobel(gray_img, cv2.CV_64F, 0, 1, ksize3) grad_mag np.sqrt(grad_x**2 grad_y**2) grad_mag np.uint8(grad_mag / grad_mag.max() * 255) # 對(duì)梯度圖進(jìn)行閾值化得到邊緣 _, edge_binary cv2.threshold(grad_mag, 30, 255, cv2.THRESH_BINARY)這種方法得到的二值圖是目標(biāo)的“輪廓”而非實(shí)心區(qū)域。常用于邊緣檢測(cè)或作為更復(fù)雜分割如分水嶺算法的輸入。5. 實(shí)戰(zhàn)流程與參數(shù)調(diào)優(yōu)指南在實(shí)際項(xiàng)目中二值化很少是孤立一步。它通常嵌入在一個(gè)完整的圖像預(yù)處理流程中。下面是一個(gè)穩(wěn)健的通用流程。5.1 標(biāo)準(zhǔn)預(yù)處理與二值化流水線(xiàn)讀取圖像并灰度化cv2.imread(‘path’, cv2.IMREAD_GRAYSCALE)。降噪根據(jù)噪聲類(lèi)型選擇濾波器。高斯模糊(cv2.GaussianBlur)對(duì)付高斯噪聲輕微平滑有助于穩(wěn)定閾值。中值濾波(cv2.medianBlur)對(duì)付椒鹽噪聲保邊效果好。雙邊濾波保邊平滑的終極武器但計(jì)算慢。注意降噪要適度過(guò)度平滑會(huì)模糊邊緣讓二值化丟失細(xì)節(jié)。通常一個(gè)3x3或5x5的高斯/中值濾波足矣。光照補(bǔ)償可選但關(guān)鍵如果存在明顯光照不均使用頂帽/底帽變換或CLAHE。選擇二值化方法并實(shí)施第一步嘗試Otsu畫(huà)出直方圖看是否為雙峰。是則直接用簡(jiǎn)單高效。若Otsu失敗光照不均轉(zhuǎn)向局部自適應(yīng)閾值。從adaptiveThresholdADAPTIVE_THRESH_GAUSSIAN_C開(kāi)始。block_size初始設(shè)為15或25取決于圖像分辨率。C初始設(shè)為2或3。后處理二值化結(jié)果通常不完美需要后處理。去小噪聲形態(tài)學(xué)開(kāi)運(yùn)算 (cv2.morphologyExwithMORPH_OPEN) 或面積過(guò)濾 (cv2.connectedComponentsWithStats)。填充空洞形態(tài)學(xué)閉運(yùn)算 (MORPH_CLOSE)。連接斷裂形態(tài)學(xué)膨脹 (cv2.dilate) 或使用特定的斷線(xiàn)連接算法。5.2 參數(shù)調(diào)優(yōu)的“望聞問(wèn)切”調(diào)參不是瞎試要有章法。把二值化結(jié)果和原圖放在一起對(duì)比觀(guān)察如果前景大面積缺失太黑閾值太高了。全局閾值降低T值。局部自適應(yīng)減小C值甚至設(shè)為負(fù)數(shù)或略微減小block_size。如果背景大量誤判為前景太白噪聲多閾值太低了。全局閾值提高T值。局部自適應(yīng)增大C值或略微增大block_size。如果目標(biāo)內(nèi)部出現(xiàn)空洞局部自適應(yīng)可能是block_size太大嘗試減小?;蛘咴龃驝值??紤]使用閉運(yùn)算后處理。如果目標(biāo)邊緣出現(xiàn)嚴(yán)重鋸齒或毛刺局部自適應(yīng)嘗試使用高斯法替代均值法。嘗試略微增大block_size使閾值計(jì)算更穩(wěn)定。使用開(kāi)運(yùn)算進(jìn)行平滑。一個(gè)實(shí)用的調(diào)試技巧不要只盯著最終的二值圖。將計(jì)算出的閾值圖可視化出來(lái)對(duì)于自適應(yīng)閾值可以計(jì)算并顯示每個(gè)像素的閾值。這能幫你直觀(guān)理解算法在圖像不同區(qū)域是如何決策的從而精準(zhǔn)定位參數(shù)問(wèn)題。5.3 不同場(chǎng)景下的方案選型速查表場(chǎng)景特征推薦方法關(guān)鍵參數(shù)/技巧備注高對(duì)比度光照均勻全局Otsu無(wú)需調(diào)參首選嘗試先看直方圖是否為雙峰光照漸變背景簡(jiǎn)單局部自適應(yīng)高斯block_size15~35,C2~5通用性最強(qiáng)文檔圖像背景有紋理/污漬Sauvola算法window_size15~25,k0.2~0.4文本專(zhuān)用效果出色暗背景亮前景頂帽變換 Otsu結(jié)構(gòu)元大于目標(biāo)寬度如黑底白字亮背景暗前景底帽變換 Otsu結(jié)構(gòu)元大于目標(biāo)寬度如白底黑字低對(duì)比度整體偏暗/亮CLAHE 二值化clipLimit2.0,tileGridSize(8,8)強(qiáng)力對(duì)比度增強(qiáng)需要精確輪廓內(nèi)部紋理不重要基于梯度的閾值對(duì)梯度圖設(shè)定閾值得到的是輪廓線(xiàn)6. 常見(jiàn)問(wèn)題排查與性能優(yōu)化6.1 二值化結(jié)果不穩(wěn)定怎么辦現(xiàn)象同一場(chǎng)景不同時(shí)間拍攝的圖像二值化效果差異大。排查檢查光照這是首要懷疑對(duì)象。確保拍攝環(huán)境光源穩(wěn)定或使用環(huán)形光源等均勻照明設(shè)備。工業(yè)場(chǎng)景中這是根治許多圖像問(wèn)題的前提。檢查相機(jī)參數(shù)自動(dòng)曝光、自動(dòng)白平衡是否關(guān)閉這些自動(dòng)功能會(huì)導(dǎo)致圖像整體亮度波動(dòng)。務(wù)必使用固定曝光、固定增益。引入圖像標(biāo)準(zhǔn)化在二值化前對(duì)圖像進(jìn)行對(duì)比度拉伸或Gamma校正使其灰度分布更穩(wěn)定。# 對(duì)比度拉伸將最小最大灰度值映射到0和255 min_val, max_val np.percentile(gray_img, [2, 98]) # 忽略極端值 stretched np.uint8(np.clip((gray_img - min_val) * 255.0 / (max_val - min_val), 0, 255))6.2 處理速度太慢如何優(yōu)化局部自適應(yīng)閾值需要對(duì)每個(gè)像素計(jì)算其鄰域統(tǒng)計(jì)量計(jì)算量大。優(yōu)化策略降分辨率如果目標(biāo)尺寸允許先將圖像縮小cv2.resize二值化后再放大回原尺寸。這是最有效的提速方法。優(yōu)化窗口大小block_size是性能關(guān)鍵。在滿(mǎn)足效果的前提下盡量使用較小的奇數(shù)。使用積分圖OpenCV的adaptiveThreshold函數(shù)內(nèi)部可能已經(jīng)優(yōu)化。但如果你自己實(shí)現(xiàn)如Sauvola使用積分圖可以快速計(jì)算任意矩形區(qū)域的和與平方和將均值、方差的計(jì)算從O(N)降到O(1)。并行化如果處理大量圖片使用多線(xiàn)程Python的concurrent.futures或GPU加速如CUDA。6.3 二值化后目標(biāo)粘連或斷裂粘連多個(gè)獨(dú)立目標(biāo)在二值化后連成了一片。原因閾值過(guò)低或原始圖像中目標(biāo)本就靠得太近。解決嘗試提高閾值。如果不行考慮在二值化前使用形態(tài)學(xué)腐蝕稍微縮小目標(biāo)分割后再膨脹恢復(fù)。或者使用分水嶺算法進(jìn)行分割。斷裂一個(gè)完整的目標(biāo)如字符斷成了幾截。原因閾值過(guò)高或目標(biāo)本身對(duì)比度不均如筆畫(huà)顏色深淺不一。解決嘗試降低閾值。使用形態(tài)學(xué)閉運(yùn)算先膨脹后腐蝕連接斷點(diǎn)。對(duì)于文本Sauvola算法通常比普通自適應(yīng)法更能保持筆畫(huà)連貫。6.4 終極策略融合與深度學(xué)習(xí)當(dāng)傳統(tǒng)方法在極端復(fù)雜場(chǎng)景下如自然場(chǎng)景文本、嚴(yán)重陰影、反光力不從心時(shí)可以考慮多閾值融合使用不同參數(shù)或方法得到多個(gè)二值化結(jié)果再通過(guò)邏輯運(yùn)算與、或融合。例如一個(gè)結(jié)果保證召回率不丟失目標(biāo)另一個(gè)結(jié)果保證精確率減少噪聲兩者取交集?;谏疃葘W(xué)習(xí)的二值化這是當(dāng)前的研究前沿。使用U-Net等分割網(wǎng)絡(luò)直接學(xué)習(xí)從灰度圖到二值圖的端到端映射。網(wǎng)絡(luò)能隱式地學(xué)習(xí)光照、陰影、紋理等復(fù)雜因素的建模在公開(kāi)基準(zhǔn)測(cè)試如DIBCO上遠(yuǎn)超傳統(tǒng)方法。當(dāng)然這需要大量的標(biāo)注數(shù)據(jù)和GPU資源進(jìn)行訓(xùn)練。從我多年的項(xiàng)目經(jīng)驗(yàn)來(lái)看圖像二值化遠(yuǎn)非一個(gè)threshold()函數(shù)調(diào)用那么簡(jiǎn)單。它是一項(xiàng)需要結(jié)合圖像特性、物理場(chǎng)景和業(yè)務(wù)目標(biāo)進(jìn)行精心設(shè)計(jì)和調(diào)試的技術(shù)。核心在于理解每種方法的適用場(chǎng)景和參數(shù)含義養(yǎng)成先分析看直方圖、看光照、再實(shí)驗(yàn)建立調(diào)參流水線(xiàn)、后處理形態(tài)學(xué)優(yōu)化的工作習(xí)慣。記住沒(méi)有“銀彈”參數(shù)最好的參數(shù)永遠(yuǎn)是針對(duì)你當(dāng)前那批圖像數(shù)據(jù)調(diào)試出來(lái)的。多觀(guān)察、多思考、多動(dòng)手試你就能讓計(jì)算機(jī)在這“非黑即白”的世界里準(zhǔn)確地找到你想要的東西。