简体   繁体   English

如何从 OPENCV python 中的图像中删除背景灰色图纸

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

I need to remove the gray drawing from the image background and only need symbols drawn over it.我需要从图像背景中删除灰色绘图,只需要在其上绘制符号。

Here is my code to do that using morphologyEx but it did not remove the entire gray drawing that is in background.这是我使用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()

I tried this also and got expected results in grayscale but unable to convert it to BGR.我也试过了,得到了预期的灰度结果,但无法将其转换为 BGR。

Here is my code这是我的代码

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);

Also i used contours to identify symbols and draw them to white image but problem is that it also identify background drawing that i don't want.我也使用轮廓来识别符号并将它们绘制成白色图像,但问题是它也识别出我不想要的背景图。

Input image输入图像

在此处输入图像描述

Expected output image预期 output 图像

在此处输入图像描述

Also the drawing will be always in gray color as in image.此外,绘图将始终为灰色,如图像所示。

Please help me out to get better result.请帮助我获得更好的结果。

Here is one way to do that in Python/OpenCV.这是在 Python/OpenCV 中执行此操作的一种方法。

  • Read the input读取输入
  • Convert to HSV and separate channels转换为 HSV 和分离通道
  • Threshold the saturation channel阈值饱和通道
  • Threshold the value channel and invert阈值通道和反转
  • Combine the two threshold images as a mask将两个阈值图像组合为掩码
  • Apply the mask to the input to write white where the mask is black将掩码应用于输入以在掩码为黑色的地方写入白色
  • Save the result保存结果

Input:输入:

在此处输入图像描述

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)


Saturation channel thresholded:饱和通道阈值:

在此处输入图像描述

Value channel thresholded and inverted:值通道阈值和反转:

在此处输入图像描述

Mask:面具:

在此处输入图像描述

Result:结果:

在此处输入图像描述

You are almost there...你快到了……

Instead of using cv2.inRange to "catch" the non-gray pixel I suggest using cv2.inRange for catching all the pixels you want to change to white color:我建议不要使用cv2.inRange来“捕捉”非灰色像素,而是使用cv2.inRange来捕捉您想要更改为白色的所有像素:

mask = cv2.inRange(hsv, (0, 0, 100), (255, 5, 255))
  • The hue range is irrelevant.色调范围无关紧要。
  • The saturation is close to zero (shades of gray).饱和度接近于零(灰色阴影)。
  • The brightness excludes the black pixels (you like to keep).亮度不包括黑色像素(您喜欢保留)。

In order to get a nicer solution, I also used the following additional stages:为了获得更好的解决方案,我还使用了以下附加阶段:

  • Build a mask of non-black pixels:构建非黑色像素的蒙版:

     nzmask = cv2.inRange(hsv, (0, 0, 5), (255, 255, 255))
  • Erode the above mask:腐蚀上面的面具:

     nzmask = cv2.erode(nzmask, np.ones((3,3)))
  • Apply and operation between mask and nzmask : masknzmask之间的应用and操作:

     mask = mask & nzmask

The above stages keeps the gray pixels around the black text.上述阶段保持黑色文本周围的灰色像素。
Without the above stages, the black text gets thinner.如果没有上述阶段,黑色文本会变薄。

  • The last stage is replacing mask pixels with white:最后一个阶段是用白色替换mask像素:

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

Here is the code:这是代码:

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()

Result:结果:
在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM