1 回答

TA貢獻1842條經驗 獲得超13個贊
這是在 OpenCV 中使用閾值 + 輪廓過濾的潛在方法:
將圖像轉換為灰度和自適應閾值
使用定義的閾值查找輪廓并過濾以刪除所有非文本輪廓
將非文本輪廓繪制到掩碼上并按位異或以僅獲取文本
計算文本像素的百分比
由于您沒有提供輸入圖像,我將使用教科書中的示例圖像。注意一些文本是彩色的,并且有一張圖片來模擬帶有文本的普通圖像。
我們首先將圖像轉換為灰度和自適應閾值cv2.adaptiveThreshold()以獲得二值圖像。
image = cv2.imread('1.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV,11,3)
接下來,我們使用 找到輪廓cv2.findContours()并使用輪廓區域進行過濾cv2.contourArea()。我們定義一個picture_threshold值來定義非文本輪廓的閾值。從本質上講,這個值決定了如果輪廓太大,它一定是一張圖片,所以我們要從我們的圖像中過濾掉這些輪廓。在這種情況下,我們將非文本輪廓定義為任何大于5%圖像大小的輪廓。這是一個不錯的假設,因為單個單詞不會大于1%整個圖像區域的大?。ǔ撬腔諛耍覀兗僭O只是普通文本)。
閾值二值圖像(左)和蒙版上過濾的非文本輪廓(右)
mask = thresh.copy()
mask = cv2.merge([mask,mask,mask])
picture_threshold = image.shape[0] * image.shape[1] * .05
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
area = cv2.contourArea(c)
if area < picture_threshold:
cv2.drawContours(mask, [c], -1, (0,0,0), -1)
為了去除不需要的輪廓,我們執行按位異或操作來獲得只有文本的過濾圖像。這是我們將計算文本像素百分比的圖像。
mask = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)
result = cv2.bitwise_xor(thresh, mask)
由于我們僅隔離了圖像上的文本輪廓,因此我們只需使用 計算圖像上的白色像素數cv2.countNonZero()。我們可以通過除以圖像的面積來獲得文本像素的百分比。結果如下:
百分比:13.15%
text_pixels = cv2.countNonZero(result)
percentage = (text_pixels / (image.shape[0] * image.shape[1])) * 100
print('Percentage: {:.2f}%'.format(percentage))
完整代碼
import cv2
import numpy as np
image = cv2.imread('1.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV,11,3)
mask = thresh.copy()
mask = cv2.merge([mask,mask,mask])
picture_threshold = image.shape[0] * image.shape[1] * .05
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
area = cv2.contourArea(c)
if area < picture_threshold:
cv2.drawContours(mask, [c], -1, (0,0,0), -1)
mask = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)
result = cv2.bitwise_xor(thresh, mask)
text_pixels = cv2.countNonZero(result)
percentage = (text_pixels / (image.shape[0] * image.shape[1])) * 100
print('Percentage: {:.2f}%'.format(percentage))
cv2.imshow('thresh', thresh)
cv2.imshow('result', result)
cv2.imshow('mask', mask)
cv2.waitKey()
添加回答
舉報