簡體   English   中英

如何從 OPENCV python 中的圖像中刪除背景灰色圖紙

[英]How to remove background gray drawings from image in OPENCV python

我需要從圖像背景中刪除灰色繪圖,只需要在其上繪制符號。

這是我使用morphologyEx 執行此操作的代碼,但它沒有刪除背景中的整個灰色繪圖。

img_path = "images/new_drawing.png"
img = cv2.imread(img_path)

kernel = np.ones((2,2), dtype=np.uint8)
result = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel, iterations=1)
cv2.imshow('Without background',result);

cv2.waitKey(0)
cv2.destroyAllWindows()

我也試過了,得到了預期的灰度結果,但無法將其轉換為 BGR。

這是我的代碼

img = cv2.imread('images/new_drawing.png')
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
med_blur = cv2.medianBlur(gray_img, ksize=3)

_, thresh = cv2.threshold(med_blur, 190, 255, cv2.THRESH_BINARY)
blending = cv2.addWeighted(gray_img, 0.5, thresh, 0.9, gamma=0)
cv2.imshow("blending", blending);

我也使用輪廓來識別符號並將它們繪制成白色圖像,但問題是它也識別出我不想要的背景圖。

輸入圖像

在此處輸入圖像描述

預期 output 圖像

在此處輸入圖像描述

此外,繪圖將始終為灰色,如圖像所示。

請幫助我獲得更好的結果。

這是在 Python/OpenCV 中執行此操作的一種方法。

  • 讀取輸入
  • 轉換為 HSV 和分離通道
  • 閾值飽和通道
  • 閾值通道和反轉
  • 將兩個閾值圖像組合為掩碼
  • 將掩碼應用於輸入以在掩碼為黑色的地方寫入白色
  • 保存結果

輸入:

在此處輸入圖像描述

import cv2
import numpy as np

# read image
img = cv2.imread('symbols.png')

# convert image to hsv colorspace
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
h, s, v = cv2.split(hsv)

# threshold saturation image
thresh1 = cv2.threshold(s, 92, 255, cv2.THRESH_BINARY)[1]

# threshold value image and invert
thresh2 = cv2.threshold(v, 128, 255, cv2.THRESH_BINARY)[1]
thresh2 = 255 - thresh2

# combine the two threshold images as a mask
mask = cv2.add(thresh1,thresh2)

# use mask to remove lines in background of input
result = img.copy()
result[mask==0] = (255,255,255)

# display IN and OUT images
cv2.imshow('IMAGE', img)
cv2.imshow('SAT', s)
cv2.imshow('VAL', v)
cv2.imshow('THRESH1', thresh1)
cv2.imshow('THRESH2', thresh2)
cv2.imshow('MASK', mask)
cv2.imshow('RESULT', result)
cv2.waitKey(0)
cv2.destroyAllWindows()

# save output image
cv2.imwrite('symbols_thresh1.png', thresh1)
cv2.imwrite('symbols_thresh2.png', thresh2)
cv2.imwrite('symbols_mask.png', mask)
cv2.imwrite('symbols_cleaned.png', result)


飽和通道閾值:

在此處輸入圖像描述

值通道閾值和反轉:

在此處輸入圖像描述

面具:

在此處輸入圖像描述

結果:

在此處輸入圖像描述

你快到了……

我建議不要使用cv2.inRange來“捕捉”非灰色像素,而是使用cv2.inRange來捕捉您想要更改為白色的所有像素:

mask = cv2.inRange(hsv, (0, 0, 100), (255, 5, 255))
  • 色調范圍無關緊要。
  • 飽和度接近於零(灰色陰影)。
  • 亮度不包括黑色像素(您喜歡保留)。

為了獲得更好的解決方案,我還使用了以下附加階段:

  • 構建非黑色像素的蒙版:

     nzmask = cv2.inRange(hsv, (0, 0, 5), (255, 255, 255))
  • 腐蝕上面的面具:

     nzmask = cv2.erode(nzmask, np.ones((3,3)))
  • masknzmask之間的應用and操作:

     mask = mask & nzmask

上述階段保持黑色文本周圍的灰色像素。
如果沒有上述階段,黑色文本會變薄。

  • 最后一個階段是用白色替換mask像素:

     new_img = img.copy() new_img[np.where(mask)] = 255

這是代碼:

import numpy as np
import cv2

img_path = "new_drawing.png"
img = cv2.imread(img_path)

hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

mask = cv2.inRange(hsv, (0, 0, 100), (255, 5, 255))
cv2.imshow('mask before and with nzmask', mask);

# Build mask of non black pixels.
nzmask = cv2.inRange(hsv, (0, 0, 5), (255, 255, 255))

# Erode the mask - all pixels around a black pixels should not be masked.
nzmask = cv2.erode(nzmask, np.ones((3,3)))
cv2.imshow('nzmask', nzmask);

mask = mask & nzmask

new_img = img.copy()
new_img[np.where(mask)] = 255

cv2.imshow('mask', mask);
cv2.imshow('new_img', new_img);
cv2.waitKey(0)
cv2.destroyAllWindows()

結果:
在此處輸入圖像描述

暫無
暫無

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

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