目標是去除大的不規則區域并僅保留影像中的字符。
例如,給定以下

和預期的masked output

我的印象可以如下實作
import cv2
import numpy as np
from matplotlib import pyplot as plt
dpath='remove_bg1.jpg'
img = cv2.imread(dpath)
img_fh=img.copy()
cv2.bitwise_not(img_fh,img_fh)
ksize=10
kernel = np.ones((ksize,ksize),np.uint8)
erosion = cv2.erode(img_fh,kernel,iterations = 3)
invertx = cv2.bitwise_not(erosion)
masked = cv2.bitwise_not(cv2.bitwise_and(img_fh,invertx))
all_image=[img,invertx,masked]
ncol=len(all_image)
for idx, i in enumerate(all_image):
plt.subplot(int(f'1{ncol}{idx 1}')),plt.imshow(i)
plt.show()
產生

顯然,上面的代碼沒有產生預期的結果。
我可以知道如何正確解決這個問題嗎?
uj5u.com熱心網友回復:
要洗掉不需要的 blob,我們必須創建一個遮罩,使其完全包圍它。
流動:
- 對影像進行反向二值化(這樣您就可以在深色背景下使用白色前景)
- 放大影像(由于 blob 與字母“A”接觸,因此必須將其隔離)
- 找到面積最大的輪廓
- 在另一個 1 通道影像上繪制輪廓并將其加厚(膨脹)
- 像素分配:包含膨脹斑點的像素在原始影像上變為白色
代碼:
im = cv2.imread('stained_text.jpg')
im2 = im.copy()
gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
# inverse binaraization
th = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV cv2.THRESH_OTSU)[1]

注意與字母“A”接觸的斑點區域。因此,為了隔離它,我們使用橢圓內核執行侵蝕
# erosion
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5))
erode = cv2.erode(th, kernel, iterations=2)

# find contours
contours, hierarchy = cv2.findContours(erode, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
# Contour of maximum area
c = max(contours, key = cv2.contourArea)
# create 1-channel image in black
black = np.zeros((im.shape[0], im.shape[1]), np.uint8)
# draw the contour on it
black = cv2.drawContours(black, [c], 0, 255, -1)
# perform dilation to have clean border
# we are using the same kernel
dilate = cv2.dilate(black, kernel, iterations = 3)

# assign the dilated area in white over the original image
im2[dilate == 255] = (255,255,255)

這只是如何進行的眾多可能方式之一。需要注意的關鍵是如何隔離 blob。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/483313.html
上一篇:PillowImage.pastevsCompositevsalpha_compositevsblend,有什么區別?
