python - 如何在背景 OpenCV 和 Python 上调整和转换蒙版图像的大小

标签 python image numpy opencv matplotlib

通过我自己的谷歌搜索并关注 this教程 我在下面创建了 python 脚本。它在图像中找到最主要(常见)的颜色并将其替换为另一个“背景”图像。它基本上创建了一个蒙版并将其放置在背景图像的顶部。我的问题是如何调整面具的大小并翻译它。我是使用 Python 的 OpenCV 的完整初学者,因此一些带有解释的代码示例将大有帮助:)。

这是脚本:

import os
#from colorthief import ColorThief
from PIL import Image
import cv2
import matplotlib.pyplot as plt
import numpy as np

imgDirec = "/Users/.../images"

def find_dominant_color(filename):
        #Resizing parameters
        width, height = 150,150
        image = Image.open(filename)
        image = image.resize((width, height),resample = 0)
        #Get colors from image object
        pixels = image.getcolors(width * height)
        #Sort them by count number(first element of tuple)
        sorted_pixels = sorted(pixels, key=lambda t: t[0])
        #Get the most frequent color
        dominant_color = sorted_pixels[-1][1]
        return dominant_color



filepath = "/Users/.../image.jpg" #Foreground Image
dominant_color = find_dominant_color(filepath)
#dominant_color = color_thief.get_color(quality=1)
print(dominant_color)
image = cv2.imread(filepath)
image_copy = np.copy(image)
image_copy = cv2.cvtColor(image_copy, cv2.COLOR_BGR2RGB)
lower_blue = np.array([dominant_color[0]-20, dominant_color[1]-20, dominant_color[2]-20])     ##[R value, G value, B value]
upper_blue = np.array([dominant_color[0]+20, dominant_color[1]+20, dominant_color[2]+20])
#plt.imshow(image_copy)


mask = cv2.inRange(image_copy, lower_blue, upper_blue)
#plt.imshow(mask, cmap='gray')

masked_image = np.copy(image_copy)
masked_image[mask != 0] = [0, 0, 0]
#plt.imshow(masked_image)
background_image = cv2.imread('/Users/.../background1.jpg')
background_image = cv2.cvtColor(background_image, cv2.COLOR_BGR2RGB)

crop_background = background_image[0:image_copy.shape[0], 0:image_copy.shape[1]]

crop_background[mask == 0] = [0, 0, 0]

#plt.imshow(crop_background)

#These Transformations do not work as intended.
newImg = cv2.resize(crop_background, (0,0), fx=2, fy=2)

height, width = masked_image.shape[:2]
quarter_height, quarter_width = height / 4, width / 4
T = np.float32([[1, 0, quarter_width], [0, 1, quarter_height]])
img_translation = cv2.warpAffine(masked_image, T, (width, height)) 


final_image = crop_background + masked_image
plt.imshow(final_image)
plt.show()

这是图片.jpg

Person against white background

这是背景1.jpg

enter image description here

并且正确运行脚本知道我得到:

enter image description here

我希望能够使人变小并在背景中翻译他。我该怎么做?另外,有什么方法可以保持背景图像的原始大小,同时将人的较小图片放在上面?同样,我是初学者(主要是 iOS 开发人员),所以可能有一个非常明显的解决方案。请赐教!

提前致谢!

最佳答案

要回答这个问题,您必须在代码中找到两件事。第一个是,背景裁剪在哪一行?这个过程将在下面一行

crop_background = background_image[0:image_copy.shape[0], 0:image_copy.shape[1]]

所以对于翻译Person在背景中,您必须定义两个在背景中转换图像的偏移量。我会这样做:
x_offset=100 # translate in x-axis
y_offset=200  # translate in y-axis
crop_background = background_image[y_offset:image_copy.shape[0]+y_offset, x_offset:image_copy.shape[1]+x_offset]

到目前为止,我们添加了翻译功能,但是我们如何才能看到整个背景而不是裁剪背景呢?要添加此功能,您应该覆盖 final_image到我们裁剪图像的确切位置。
background_image[y_offset:image_copy.shape[0]+y_offset, x_offset:image_copy.shape[1]+x_offset]=final_image

通过添加这一行,新图片将如下所示:

enter image description here

那么调整图像大小呢? OpenCV中有一个函数,它的名字是cv2.resize通过您可以将图像调整为任何大小,我在下面的行中将您的图像 reshape 为 (100,200) 并重新运行代码:
image = cv2.resize(image,(100,200))

结果将是:

enter image description here

整个代码将如下所示:
import os
#from colorthief import ColorThief
from PIL import Image
import cv2
import matplotlib.pyplot as plt
import numpy as np

imgDirec = "/home/isv/Desktop/"

def find_dominant_color(filename):
        #Resizing parameters
        width, height = 150,150
        image = Image.open(filename)
        image = image.resize((width, height),resample = 0)
        #Get colors from image object
        pixels = image.getcolors(width * height)
        #Sort them by count number(first element of tuple)
        sorted_pixels = sorted(pixels, key=lambda t: t[0])
        #Get the most frequent color
        dominant_color = sorted_pixels[-1][1]
        return dominant_color





filepath = "/home/isv/Desktop/image.jpg" #Foreground Image
dominant_color = find_dominant_color(filepath)
#dominant_color = color_thief.get_color(quality=1)
print(dominant_color)
image = cv2.imread(filepath)
image = cv2.resize(image,(100,200))    #added line
image_copy = np.copy(image)
image_copy = cv2.cvtColor(image_copy, cv2.COLOR_BGR2RGB)
lower_blue = np.array([dominant_color[0]-20, dominant_color[1]-20, dominant_color[2]-20])     ##[R value, G value, B value]
upper_blue = np.array([dominant_color[0]+20, dominant_color[1]+20, dominant_color[2]+20])
#plt.imshow(image_copy)


mask = cv2.inRange(image_copy, lower_blue, upper_blue)
#plt.imshow(mask, cmap='gray')

masked_image = np.copy(image_copy)
masked_image[mask != 0] = [0, 0, 0]
#plt.imshow(masked_image)
background_image = cv2.imread('/home/isv/Desktop/background1.jpg')
background_image = cv2.cvtColor(background_image, cv2.COLOR_BGR2RGB)

x_offset=100    #added line
y_offset=200    #added line
crop_background = background_image[y_offset:image_copy.shape[0]+y_offset, x_offset:image_copy.shape[1]+x_offset]   #change line

crop_background[mask == 0] = [0, 0, 0]

#plt.imshow(crop_background)

#These Transformations do not work as intended.
newImg = cv2.resize(crop_background, (0,0), fx=2, fy=2)

height, width = masked_image.shape[:2]
quarter_height, quarter_width = height / 4, width / 4
T = np.float32([[1, 0, quarter_width], [0, 1, quarter_height]])
img_translation = cv2.warpAffine(masked_image, T, (width, height)) 


final_image = crop_background + masked_image
background_image[y_offset:image_copy.shape[0]+y_offset, x_offset:image_copy.shape[1]+x_offset]=final_image   #added line
plt.imshow(final_image)
plt.show()

plt.figure()                        # added line
plt.imshow(background_image)        # added line
plt.show()                          # added line

我希望这段代码对你有帮助。

关于python - 如何在背景 OpenCV 和 Python 上调整和转换蒙版图像的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59545637/

相关文章:

javascript - Flask Jinja2 语句与 JavaScript 用例

python opencv在使用第三方摄像头时无法显示视频

python - 查找图像上的特定点

python - Numpy 数组填充随机数,这样您只需沿 x/y 轴将值更改 1

python - 简单的Python Q : idk what produces None when this code's executed

python - 如何修复机器学习中恒定的验证准确性?

python - 从列创建 numpy 结构化数组

python - 如何在python中添加到numpy数组的第k+1个元素?

image - 图像中的线检测

html - 背景图像上的 float 图像在高分辨率下向屏幕左侧 float