cv2-不规则裁剪粘贴

发布时间 2023-11-10 14:16:07作者: 贝壳里的星海

opencv不规则裁剪粘贴

矩形图像粘贴

import cv2

img1=cv2.imread("./assets/images/1.jpg")      # 背景图像
img2=cv2.imread("./assets/images/logo.jpg")   # 对象图像


img1 = cv2.resize(img1, (720, 720))
img2 = cv2.resize(img2, (200, 200))

def img1img2_tores(img1,img2,x1,y1):
    
    # 首先获取原始图像roi
    height, width, channels = img2.shape
    img1[y1:y1+height, x1:x1+width] =  img2
    
    cv2.imshow("res",img1)
    cv2.waitKey(0)
    
    return     
    

img1img2_tores(img1,img2,100,200)
img

mask不规则图像

图像裁剪

import cv2
import numpy as np


img=cv2.imread("./assets/images/1.jpg")    

# 坐标点points
pts = np.array([[(10, 23), (260, 34), (456, 299), (200, 399),(10,23)]], dtype=np.int32)

mask_backblack = np.zeros(img.shape[:2], np.uint8)  # 全0

# 在mask上将多边形区域填充为白色
cv2.fillPoly(mask_backblack, pts, (255))  # 填充,用 255 填充

mask_backwhite = cv2.bitwise_not(mask_backblack)  # 使用非运算反转

# 背景为黑色
dst_inmark = cv2.bitwise_and(img, img, mask=mask_backblack)   # 提取mark位置
dst_outmark = cv2.bitwise_and(img, img, mask=mask_backwhite)  # 提取非mark位置
cv2.imshow("dst_inmark",dst_inmark)
cv2.imshow("dst_outmark",dst_outmark)
cv2.waitKey(0)

# 配置其他颜色
other = np.ones_like(img)    # 整块其他背景颜色
other[:, :, 0] *= 255
other[:, :, 1] *= 255

mask2 = np.ones(img.shape, np.uint8) * 255
mask2 = cv2.fillPoly(mask2, [pts], (0, 0, 0,))
other = cv2.bitwise_and(other, mask2)
other_color = dst_inmark + other
cv2.imshow("mask2.jpg", other_color)
cv2.waitKey(0)

img

图像粘贴

详细每个步骤

import cv2

img1=cv2.imread("./assets/images/1.jpg")      # 背景图像
img2=cv2.imread("./assets/images/logo.jpg")   # 对象图像


img1 = cv2.resize(img1, (720, 720))
img2 = cv2.resize(img2, (200, 200))
 
# 首先获取原始图像roi
rows, cols, channels = img2.shape
roi = img1[0:rows, 0:cols]                    # 需要合并替换的区域
 
# 对象图像提取mask
img2gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
 
cv2.imshow('img2gray', img2gray)      # 灰度
cv2.waitKey(0)
'''
将一个灰色的图片,变成要么是白色要么就是黑色。
大于规定thresh值就是设置的最大值 常为255 也就是白色
'''
# 将灰度值二值化,得到ROI区域掩模
# cv2.threshold (源图片, 阈值=ret, 填充色, 阈值类型)
ret, mask = cv2.threshold(img2gray, 200, 255, cv2.THRESH_BINARY)
  
cv2.imshow('mask', mask)            # 二值化 
cv2.waitKey(0)
 
# ROI掩模区域反向掩模
mask_inv = cv2.bitwise_not(mask)    # 取反,黑色背景
 
cv2.imshow('mask_inv', mask_inv)
cv2.waitKey(0)
 

img
# 掩模显示前景
img2_fg = cv2.bitwise_and(img2, img2, mask=mask_inv)     # 对象前景显示
cv2.imshow('img2_fg', img2_fg)
cv2.waitKey(0)
 
# 掩模显示背景
img1_bg = cv2.bitwise_and(roi, roi, mask=mask)         #  背景图像,区域抠图
 
cv2.imshow('img1_bg', img1_bg)
cv2.waitKey(0)
 

# 前背景图像叠加
dst = cv2.add(img1_bg, img2_fg)
cv2.imshow('dst', dst)
cv2.waitKey(0)
  
img1[0:rows, 0:cols] = dst
 
cv2.imshow('res', img1)
cv2.waitKey(0)
cv2.destroyAllWindows()
img img

函数封装

import cv2

img1=cv2.imread("./assets/images/1.jpg")      # 背景图像
img2=cv2.imread("./assets/images/logo.jpg")   # 对象图像


img1 = cv2.resize(img1, (720, 720))
img2 = cv2.resize(img2, (200, 200))


def get_mask(img):
    # 对象图像提取mask
    imggray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    cv2.imshow('img2gray', imggray)      # 灰度
    cv2.waitKey(0)
    '''
    将一个灰色的图片,变成要么是白色要么就是黑色。
    大于规定thresh值就是设置的最大值 常为255 也就是白色
    '''
    # 将灰度值二值化,得到ROI区域掩模
    # cv2.threshold (源图片, 阈值=ret, 填充色, 阈值类型)
    _, mask_white = cv2.threshold(imggray, 200, 255, cv2.THRESH_BINARY)
    
    cv2.imshow('mask_white', mask_white)            # 二值化,白色北京
    cv2.waitKey(0)
    
    return mask_white

def img1img2mask_to_res(img1,img2,mask_white):
    #  不支持 定义 位置
    
    # 首先获取原始图像roi
    rows, cols, channels = img2.shape
    roi = img1[0:rows, 0:cols]                                  # 需要合并替换的区域,默认是从左上角开始的
    
    mask_black=cv2.bitwise_not(mask_white)                    
    
    # 掩模显示前景
    img2_fg = cv2.bitwise_and(img2, img2, mask=mask_black)        # 对象前景显示
    cv2.imshow('img2_fg', img2_fg)
    cv2.waitKey(0)
    
    # 掩模显示背景
    img1_bg = cv2.bitwise_and(roi, roi, mask=mask_white)          # 背景图像,区域抠图
    
    cv2.imshow('img1_bg', img1_bg)
    cv2.waitKey(0)
    

    # 前背景图像叠加
    dst = cv2.add(img1_bg, img2_fg)
    cv2.imshow('dst', dst)
    cv2.waitKey(0)
    
    img1[0:rows, 0:cols] = dst
    
    cv2.imshow('res', img1)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
  


def img1img2mask_to_res2(img1,img2,mask_white,x1,y1):
    """
    x1,y2 为叠加的起始坐标 支持定义位置信息
    """
    
    # 首先获取原始图像roi
    height, width, channels = img2.shape
    roi = img1[y1:y1+height, x1:x1+width]                                  # 需要合并替换的区域,默认是从左上角开始的
    
    mask_black=cv2.bitwise_not(mask_white)                    
    
    # 掩模显示前景
    img2_fg = cv2.bitwise_and(img2, img2, mask=mask_black)        # 对象前景显示
    cv2.imshow('img2_fg', img2_fg)
    cv2.waitKey(0)
    
    # 掩模显示背景
    img1_bg = cv2.bitwise_and(roi, roi, mask=mask_white)          # 背景图像,区域抠图
    
    cv2.imshow('img1_bg', img1_bg)
    cv2.waitKey(0)
    

    # 前背景图像叠加
    dst = cv2.add(img1_bg, img2_fg)
    cv2.imshow('dst', dst)
    cv2.waitKey(0)
    
    img1[y1:y1+height, x1:x1+width] = dst
    
    cv2.imshow('res', img1)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
      

mask_white=get_mask(img2)
img1img2mask_to_res2(img1,img2,mask_white,100,200)

参考资料

参考1_mask粘贴