簡體   English   中英

在黑色背景上獲取白色文本

[英]Get white text on black background

我想識別一組圖像中的文本。 有一些圖像帶有白色和黑色文本。

在此處輸入圖像描述

我使用 otsu 閾值對圖像進行二值化

在此處輸入圖像描述

在輪廓識別和去除非文本區域后,我確定了所需的文本區域。

在此處輸入圖像描述

我需要白色的所有文本。 但我不知道該怎么做。 我想過使用按位運算符,但找不到方法。 有人可以幫我弄這個嗎?

預期輸出:

在此處輸入圖像描述

import cv2
import numpy as np


def process(img):
 # read image
 img_no = str(img)
 rgb = cv2.imread(img_no + '.jpg')
 # cv2.imshow('original', rgb)

 # convert image to grayscale
 gray = cv2.cvtColor(rgb, cv2.COLOR_BGR2GRAY)

 _, bw_copy = cv2.threshold(gray, 0.0, 255.0, cv2.THRESH_BINARY | cv2.THRESH_OTSU)

 # bilateral filter
 blur = cv2.bilateralFilter(gray, 5, 75, 75)
 # cv2.imshow('blur', blur)

 # morphological gradient calculation
 kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
 grad = cv2.morphologyEx(blur, cv2.MORPH_GRADIENT, kernel)
 # cv2.imshow('gradient', grad)

 # binarization
 _, bw = cv2.threshold(grad, 0.0, 255.0, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
 # cv2.imshow('otsu', bw)

 # closing
 kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 1))
 closed = cv2.morphologyEx(bw, cv2.MORPH_CLOSE, kernel)
 # cv2.imshow('closed', closed)

 # finding contours
 contours, hierarchy = cv2.findContours(closed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

 mask = np.zeros(closed.shape, dtype=np.uint8)
 mask1 = np.zeros(bw_copy.shape, dtype=np.uint8)

 for idx in range(len(contours)):
    x, y, w, h = cv2.boundingRect(contours[idx])
    mask[y:y + h, x:x + w] = 0
    area = cv2.contourArea(contours[idx])
    aspect_ratio = float(w) / h
    cv2.drawContours(mask, contours, idx, (255, 255, 255), -1)
    r = float(cv2.countNonZero(mask[y:y + h, x:x + w])) / (w * h)

    # identify region of interest
    if r > 0.34 and 0.52 < aspect_ratio < 13 and area > 145.0:
        cv2.drawContours(mask1, [contours[idx]], -1, (255, 255, 255), -1)

 result = cv2.bitwise_and(bw_copy, mask1)
 cv2.imshow('result', result)

 print(img_no + " Done")
 cv2.waitKey()

新圖片

接受的答案不適用於這張照片。

在此處輸入圖像描述

乍一看,這似乎是一個簡單的問題,但解決起來卻相當棘手。 但是,您已經擁有解決問題所需的所有要素,並且只需要對您的算法稍作調整。

以下是要點:

您需要的是閾值圖像(bw_copy)的倒置圖像(wb_copy)。

在此處輸入圖像描述

在此處輸入圖像描述

你在制作面具方面做得很好

在此處輸入圖像描述

使用上面的掩碼對 bw_copy 和 wb_copy 運行 bitwise_and 操作。 您應該得到如下所示的結果。

在此處輸入圖像描述

在此處輸入圖像描述

如您所見,您的答案來自兩張圖片。 您需要做的就是對每個字體 blob,計算兩個圖像中的非零像素並選擇具有較高計數的那個。 這樣做將提供您想要的結果。

在此處輸入圖像描述

這是我對代碼所做的修改

  # finding contours
    _,contours,_ = cv2.findContours(closed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

    mask = np.zeros(closed.shape, dtype=np.uint8)
    mask1 = np.zeros(bw_copy.shape, dtype=np.uint8)
    wb_copy = cv2.bitwise_not(bw_copy)
    new_bw = np.zeros(bw_copy.shape, dtype=np.uint8)

    for idx in range(len(contours)):
        x, y, w, h = cv2.boundingRect(contours[idx])
        mask[y:y + h, x:x + w] = 0
        area = cv2.contourArea(contours[idx])
        aspect_ratio = float(w) / h
        cv2.drawContours(mask, contours, idx, (255, 255, 255), -1)
        r = float(cv2.countNonZero(mask[y:y + h, x:x + w])) / (w * h)


        # identify region of interest
        if r > 0.34 and 0.52 < aspect_ratio < 13 and area > 145.0:

            cv2.drawContours(mask1, [contours[idx]], -1, (255, 255, 255), -1)

            bw_temp = cv2.bitwise_and(mask1[y:y + h, x:x + w],bw_copy[y:y + h, x:x + w])
            wb_temp = cv2.bitwise_and(mask1[y:y + h, x:x + w],wb_copy[y:y + h, x:x + w])

            bw_count = cv2.countNonZero(bw_temp)
            wb_count = cv2.countNonZero(wb_temp)

            if bw_count > wb_count:
                new_bw[y:y + h, x:x + w]=np.copy(bw_copy[y:y + h, x:x + w])
            else:
                new_bw[y:y + h, x:x + w]=np.copy(wb_copy[y:y + h, x:x + w])

    cv2.imshow('new_bw', new_bw)

輸入圖像:

輸入圖像

我做了以下事情:

import cv2 as cv
import numpy as np
img_path = '10002.png'
img = cv.imread(img_path)
img = cv.resize(img, (None, None), None, 0.4, 0.4)
img = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
img = np.array(img, dtype='float32')
result = np.where(img == 0., 255, 0)
result = np.array(result, dtype='uint8')
result = cv.erode(result, kernel=np.ones(shape=(3, 3)), iterations=1)
cv.imshow('Image', img)
cv.imshow('Result', result)
cv.waitKey(0)
cv.destroyAllWindows()

輸出圖像:

輸出圖像

您甚至可以使用按位不反轉圖像並在白色背景上獲得黑色文本。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM