使用opencvpython移除图像的背景

我有两个图像,一个只有背景,另一个有背景+可探测物体(在我的例子中是一辆汽车)

我正试图去掉背景,这样我的车就只能停在车里了生成的图像。下面是我试图获取

期望的结果

import numpy as np

import cv2

original_image = cv2.imread('IMG1.jpg', cv2.IMREAD_COLOR)

gray_original = cv2.cvtColor(original_image, cv2.COLOR_BGR2GRAY)

background_image = cv2.imread('IMG2.jpg', cv2.IMREAD_COLOR)

gray_background = cv2.cvtColor(background_image, cv2.COLOR_BGR2GRAY)

foreground = np.absolute(gray_original - gray_background)

foreground[foreground > 0] = 255

cv2.imshow('Original Image', foreground)

cv2.waitKey(0)

将两个图像相减得到的图像为

问题来了。预期的结果图像应该只是一辆汽车。也,如果你仔细看看这两张照片,你会发现它们不是

完全相同的是,相机移动了一点,所以背景被改变了有点不安。我的问题是,有了这两张照片,我怎么能

减去背景。我不想使用grabCut或背景减法ORMOG算法因为我现在不知道这些算法里面发生了什么。

另外,如果可能的话,请指导我这样做的一般方法不仅在这个具体的例子就是,我在一张图片中有一个背景背景+第二个图像中的对象。最好的解决办法是什么这样做。抱歉问了这么长时间。

回答:

我用OpenCV解决了你的问题

[分水岭](http://docs.opencv.org/3.1.0/d7/d1b/group\uu imgproc\uu misc.html\ga3267243e4d3f95165d55a618c65ac6e1

“分水岭”算法。你可以找到分水岭的理论和例子

这里.

首先,我选择了几个点(标记)来指示对象I的位置

想保留,背景在哪里。此步骤是手动的,可以改变

从一张图片到另一张图片。而且,它需要一些重复,直到你得到正确的答案

期望的结果。我建议使用一个工具来获得像素坐标。然后我

创建了一个零的空整数数组,大小与汽车图像相同。以及

然后我将一些值(1:background,[255192128,64]:car\u parts)赋给

标记位置的像素。

当我下载你的图片时,我不得不裁剪它以得到一个

那辆车。裁剪后,图像的大小为400x601。这可能不是什么

你拥有的图像的大小,所以标记将被关闭。

之后我使用了分水岭算法。第一个输入是图像,第二个输入是

输入是标记图像(除标记位置外,所有位置均为零)。这个

结果如下图所示。

我将值大于1的所有像素设置为255(汽车),其余的设置为255

(背景)归零。然后我用一个3x3的内核将得到的图像放大到

避免丢失有关汽车轮廓的信息。最后,我用了

放大图像作为原始图像的遮罩,使用cv2.bitwise和()函数,

这是我的密码:

import cv2

import numpy as np

import matplotlib.pyplot as plt

# Load the image

img = cv2.imread("/path/to/image.png", 3)

# Create a blank image of zeros (same dimension as img)

# It should be grayscale (1 color channel)

marker = np.zeros_like(img[:,:,0]).astype(np.int32)

# This step is manual. The goal is to find the points

# which create the result we want. I suggest using a

# tool to get the pixel coordinates.

# Dictate the background and set the markers to 1

marker[204][95] = 1

marker[240][137] = 1

marker[245][444] = 1

marker[260][427] = 1

marker[257][378] = 1

marker[217][466] = 1

# Dictate the area of interest

# I used different values for each part of the car (for visibility)

marker[235][370] = 255 # car body

marker[135][294] = 64 # rooftop

marker[190][454] = 64 # rear light

marker[167][458] = 64 # rear wing

marker[205][103] = 128 # front bumper

# rear bumper

marker[225][456] = 128

marker[224][461] = 128

marker[216][461] = 128

# front wheel

marker[225][189] = 192

marker[240][147] = 192

# rear wheel

marker[258][409] = 192

marker[257][391] = 192

marker[254][421] = 192

# Now we have set the markers, we use the watershed

# algorithm to generate a marked image

marked = cv2.watershed(img, marker)

# Plot this one. If it does what we want, proceed;

# otherwise edit your markers and repeat

plt.imshow(marked, cmap='gray')

plt.show()

# Make the background black, and what we want to keep white

marked[marked == 1] = 0

marked[marked > 1] = 255

# Use a kernel to dilate the image, to not lose any detail on the outline

# I used a kernel of 3x3 pixels

kernel = np.ones((3,3),np.uint8)

dilation = cv2.dilate(marked.astype(np.float32), kernel, iterations = 1)

# Plot again to check whether the dilation is according to our needs

# If not, repeat by using a smaller/bigger kernel, or more/less iterations

plt.imshow(dilation, cmap='gray')

plt.show()

# Now apply the mask we created on the initial image

final_img = cv2.bitwise_and(img, img, mask=dilation.astype(np.uint8))

# cv2.imread reads the image as BGR, but matplotlib uses RGB

# BGR to RGB so we can plot the image with accurate colors

b, g, r = cv2.split(final_img)

final_img = cv2.merge([r, g, b])

# Plot the final result

plt.imshow(final_img)

plt.show()

如果你有很多图像,你可能需要创建一个工具来

以图形方式注释标记,甚至是一种查找标记的算法

自动地。

以上是 使用opencvpython移除图像的背景 的全部内容, 来源链接: utcz.com/qa/433097.html

回到顶部