使用OpenCV将一个纯绿色区域替换为另一幅图像

2024-05-16 19:41:02 发布

您现在位置:Python中文网/ 问答频道 /正文

下面的图像有一个绿色区域,我正在寻找任何其他图像替换。它的视角没有必要匹配。你知道吗

enter image description here

我已经可以制作一个面具了。但在调整另一幅图像的大小并将其与绿色区域对齐方面还没有取得成功。我在网上找到的大多数资源都提到了这两幅图像需要相同的大小,但我只想调整新图像的大小,使其适合绿色矩形,而不是让两幅正方形图像重叠,其中一幅图像带有剪切。你知道吗

enter image description here

什么是好方法?你知道吗


Tags: 方法图像区域资源矩形绿色正方形视角
2条回答

下面是一个使用Python OpenCV的解决方案。你知道吗

Read both images.

Measure and enter 4 corresponding sets of x,y control points.

Compute homography (perspective coefficients)

Warp the source image using the homography   the background will be black

Create a binary mask from the dst image using the green color range.

Invert the mask.

Apply the inverted mask to the dst image to blacken the inside of the region of interest (where the src will go)

Add the warped src to the masked dst to form the result


src公司:

enter image description here

夏令时:

enter image description here

#!/python3.7

import cv2
import numpy as np


# Read source image.
src = cv2.imread('original.jpg')

# Four corners of source image
# Coordinates are in x,y system with x horizontal to the right and y vertical downward
# listed clockwise from top left
pts_src = np.float32([[0, 0], [325, 0], [325, 472], [0, 472]])


# Read destination image.
dst = cv2.imread('green_rect.png')

# Four corners of destination image.
pts_dst = np.float32([[111, 59], [206, 60], [216, 215], [121, 225]])

# Calculate Homography if more than 4 points
# h = forward transformation matrix
#h, status = cv2.findHomography(pts_src, pts_dst)

# Alternate if only 4 points
h = cv2.getPerspectiveTransform(pts_src,pts_dst)


# Warp source image to destination based on homography
# size argument is width x height, so have to reverse shape values
src_warped = cv2.warpPerspective(src, h, (dst.shape[1],dst.shape[0]))


# Set BGR color ranges
lowerBound = np.array([0, 255, 0]);
upperBound = np.array([0, 255, 0]);

# Compute mask (roi) from ranges in dst
mask = cv2.inRange(dst, lowerBound, upperBound);

# Dilate mask, if needed, when green border shows
kernel = np.ones((3,3),np.uint8)
mask = cv2.dilate(mask,kernel,iterations = 1)

# Invert mask
inv_mask = cv2.bitwise_not(mask)

# Mask dst with inverted mask
dst_masked = cv2.bitwise_and(dst, dst, mask=inv_mask)

# Put src_warped over dst
result = cv2.add(dst_masked, src_warped)

# Save outputs
cv2.imwrite('warped_src.jpg', src_warped)
cv2.imwrite('inverted_mask.jpg', inv_mask)
cv2.imwrite('masked_dst.jpg', dst_masked)
cv2.imwrite('perspective_composite.jpg', result)


翘曲钢筋:

enter image description here

倒置的遮罩:

enter image description here

蒙面测试:

enter image description here

结果:

enter image description here

我将留给读者过滤多余的绿色边框或编辑dst图像中的控制点,以使感兴趣的区域更大。你知道吗

注意:如果src的长宽比与绿色矩形的长宽比不匹配,那么使用这种方法src会失真。你知道吗

根据我前面的答案的评论,这里有一个简单的缩放和平移仿射扭曲的方法。你知道吗

Read both images

Measure the height of the green region and get the height of the src image

Measure the center (x,y) of the green region and get the center of the src image

Compute the affine matrix coefficients for scale and translation only (no rotation or skew)

Warp the source image using the affine matrix   the background will be black

Create a binary mask from the warped src image making everything not black into white

Invert the mask

Apply the inverted mask to the dst image

Add the warped src over the masked dst to form the result


src公司:

enter image description here

夏令时:

enter image description here

#!/python3.7

import cv2
import numpy as np


# Read source image.
src = cv2.imread('original.jpg')
h_src, w_src = src.shape[:2]

# Read destination image.
dst = cv2.imread('green_rect.png')
h_dst, w_dst = dst.shape[:2]

# compute scale from height of src and height of green region
h_green=170
scale = h_green/h_src

# compute offsets from center of scaled src and center of green
x_src = (scale)*w_src/2
y_src = (scale)*h_src/2
x_green = 165
y_green = 140
xoff = (x_green - x_src)
yoff = (y_green - y_src)

# build affine matrix for scale and translate only
affine_matrix = np.float32([ [scale,0,xoff], [0,scale,yoff] ])

# do affine warp
# add 1 to src to ensure no pure black
src_warped = cv2.warpAffine(src+1, affine_matrix, (w_dst, h_dst), cv2.INTER_AREA)

# Compute mask (roi) in warped src
_, mask = cv2.threshold(src_warped,1,255,cv2.THRESH_BINARY)

# Invert single channel of mask
inv_mask = cv2.bitwise_not(mask[:,:,0])

# Mask dst with inverted mask
dst_masked = cv2.bitwise_and(dst, dst, mask=inv_mask)

# Put warped src over masked dst
result = cv2.add(dst_masked,src_warped)

# Save outputs
cv2.imwrite('warped_src.jpg', src_warped)
cv2.imwrite('masked_src.jpg', mask)
cv2.imwrite('affine_composite.jpg', result)


翘曲钢筋:

enter image description here

反转遮罩:

enter image description here

屏蔽dst

enter image description here

结果:

enter image description here

相关问题 更多 >