作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个无法控制的背景颜色的对象(样本)的图像。此问题已通过 post 的建议得到解决.如果图像是从垂直角度拍摄的,则该代码可以很好地工作。
但是,我还有另一个问题。一些图像是从无法控制的角度拍摄的。我上面提到的帖子中的现有代码返回了意外的结果。例如,给定原始图像
结果是 .
我修改该代码的想法是从外部轮廓制作一个蒙版,然后在原始和蒙版之间按位应用。但我不知道如何从外轮廓制作面具。我可以有你的建议吗?
最佳答案
您可以使用以下解决方案(尽管它不能很好地分离样本):
cv2.floodFill
用黑色背景替换彩色背景。 floodFill
之后留下的一些不需要的伪影。 . import numpy as np
import cv2
from scipy.interpolate import splprep, splev
orig_im = cv2.imread("specimen1.jpg")
im = orig_im.copy()
h, w = im.shape[0], im.shape[1]
# Seed points for floodFill (use two points at each corner for improving robustness)
seedPoints = ((0, 0), (10, 10), (w-1, 0), (w-1, 10), (0, h-1), (10, h-1), (w-1, h-1), (w-10, h-10))
# Fill background with black color
for seed in seedPoints:
cv2.floodFill(im, None, seedPoint=seed, newVal=(0, 0, 0), loDiff=(5, 5, 5), upDiff=(5, 5, 5))
# Use "close" morphological operation
im = cv2.morphologyEx(im, cv2.MORPH_OPEN, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (10,10)));
#Convert to Grayscale, and then to binary image.
gray = cv2.cvtColor(im, cv2.COLOR_RGB2GRAY)
ret, thresh_gray = cv2.threshold(gray, 5, 255, cv2.THRESH_BINARY)
#Find contours
_, contours, _ = cv2.findContours(thresh_gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
c = max(contours, key=cv2.contourArea) # Get the largest contour
# Smooth contour
# https://agniva.me/scipy/2016/10/25/contour-smoothing.html
x,y = c.T
x = x.tolist()[0]
y = y.tolist()[0]
tck, u = splprep([x,y], u=None, s=1.0, per=1)
u_new = np.linspace(u.min(), u.max(), 20)
x_new, y_new = splev(u_new, tck, der=0)
res_array = [[[int(i[0]), int(i[1])]] for i in zip(x_new,y_new)]
smoothened = np.asarray(res_array, dtype=np.int32)
# For testing
test_im = orig_im.copy()
cv2.drawContours(test_im, [smoothened], 0, (0, 255, 0), 1)
# Build a mask
mask = np.zeros_like(thresh_gray)
cv2.drawContours(mask, [smoothened], -1, 255, -1)
# Apply mask
res = np.zeros_like(orig_im)
res[(mask > 0)] = orig_im[(mask > 0)]
# Show images for testing
cv2.imshow('test_im', test_im)
cv2.imshow('res', res)
cv2.imshow('mask', mask)
cv2.waitKey(0)
cv2.destroyAllWindows()
loDiff
和
hiDiff
参数以匹配给定图像的最佳参数)。
关于opencv - 从外部轮廓创建蒙版以移除图像背景,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60319634/
我是一名优秀的程序员,十分优秀!