【问题标题】:How to resize and translate a masked image over a background OpenCV and Python如何在背景 OpenCV 和 Python 上调整和转换蒙版图像的大小
【发布时间】:2020-04-20 01:45:57
【问题描述】:

通过我自己的谷歌搜索并遵循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

这是 background1.jpg

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

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

提前致谢!

【问题讨论】:

    标签: python image numpy opencv matplotlib


    【解决方案1】:

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

    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
    

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

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

    image = cv2.resize(image,(100,200))
    

    结果将是:

    整个代码如下:

    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
    

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

    【讨论】:

      猜你喜欢
      • 2019-07-15
      • 1970-01-01
      • 2017-12-13
      • 2020-09-23
      • 2021-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-16
      相关资源
      最近更新 更多