动机
在现代世界中,有成千上万的工具,可以轻松地对图像进行编辑、调整大小、改变、添加不同的效果等操作。但我们很少关心它在后台是如何工作的。本文将讨论一种重要的图像处理技术,称为混合和粘贴图像。这种知识对图像处理和计算机视觉都至关重要。尽管这些技术很简单,但它们是计算机视觉的核心基础之一。
如果你是图像处理和计算机视觉的初学者,本文可能对你有所帮助。
目录
什么是图像混合?
何时需要混合?
使用OpenCv进行逐步实现
什么是图像混合和粘贴?
根据牛津词典的定义,“混合”意味着“不同物质或其他东西的混合”。这个词在图像处理和计算机视觉中也用于类似的含义。这是一种将两个或多个图像组合在一起以创建新图像的技术。输出图像包含输入图像的元素。
混合是在图像尺寸相同或不同的情况下都可能的。这两种方法都将在实现部分进行讨论。
粘贴图像意味着将一幅图像的像素复制到另一幅图像上。
何时需要混合?
我们经常需要将两个或多个图像合并的过程。通常情况下,我们可以使用图像编辑软件来完成。在计算机视觉中,我们需要开发自动化的图像混合过程。在这种情况下,手动编辑是不可能的。因此,在这种情况下需要实际操作的知识。
使用OpenCV逐步实现
我们可以在以下情况下混合图像:
混合后的图像尺寸相同
图像尺寸不同
让我们导入必要的库。
import cv2
import matplotlib.pyplot as plt
import numpy as np
现在是用OpenCV读取图像的时候了。cv2.imread()函数帮助我们读取图像。
# Two images
image_1 = cv2.imread('Kaptai_lake.jpg')
image_2 = cv2.imread('copyright.png')
可视化第一幅图像。
img1=cv2.cvtColor(image_1,cv2.COLOR_BGR2RGB)
plt.imshow(img1)
在可视化之前,我将颜色通道从BGR转换为RGB,因为OpenCV以BGR格式读取图像,而matplotlib以RGB格式工作。因此,我已经使用了c2.COLOR_BGR2RGB来转换颜色通道。
现在,可视化第二幅图像。
img2=cv2.cvtColor(image_2,cv2.COLOR_BGR2RGB)
plt.imshow(img2)
我们将合并这两幅图像,以在第一幅图像上创建水印。
对于相同尺寸的图像
在相同尺寸的图像混合的情况下,图像的形状必须相等。让我们找到我们图像的形状。
print(image_1.shape)
print(image_2.shape)
(3468, 4624, 3)
(468, 802, 3)
这两幅图像的形状不同。现在,我们需要重新塑造这些图像。
image_1 =cv2.resize(image_1 ,(500,500))
image_2 =cv2.resize(image_2,(500,500))
print(image_1.shape)
print(image_2.shape)
(500, 500, 3)
(500, 500, 3)
我们已成功将这两幅图像变换成相同的尺寸。
我们已经到了混合图像的最后一步。
在图像混合中,我们使用数学公式来组合两个或多个图像的像素值,以创建一个新图像。用于混合的公式如下:
在这里,image_1和image_2是我们要混合的两幅图像。Alpha和beta是混合权重,用于确定每个图像对最终输出的贡献。Gamma是一个标量值,用于在输出图像中创建噪音。
可以调整alpha、beta和gamma的值来控制输出图像的外观。例如,增加alpha值将增加image_1对输出的贡献,导致最终图像更类似于image_1。类似地,增加beta值将增加image_2对输出的贡献,导致最终图像更类似于image_2。
以下的代码片段可以完成这个任务。
blended = cv2.addWeighted(src1=image_1,alpha=0.4,src2=image_2,beta=0.6,gamma=0)
blend_BGR=cv2.cvtColor(blended,cv2.COLOR_BGR2RGB)
plt.imshow(blend_BGR)
我们使用cv2.addWeighted()函数来使用混合公式混合图像。我们设置alpha值为0.4,beta值为0.6,这意味着第二幅图像对最终输出的贡献大于第一幅图像。我们将gamma的值设为0,这意味着没有标量值被添加到结果中。
最后,我们使用plt.imshow()函数显示输出图像。我们发现第二幅图像比第一幅图像更明显。正如我们所使用的,beta值大于alpha值。
我们已成功混合了尺寸相同的图像。
然而,通常情况下,我们需要混合不同尺寸的图像。这并没有直接的方法来完成。我们需要遵循一些技巧和流程来实现。在下一节中,我将展示具体的实现。
使用不同尺寸的图像进行图像混合
在导入库和图像之后,我们将调整两幅图像的大小,以简化实现。
image_1_re =cv2.resize(image_1,(2400,2000))
image_2_re =cv2.resize(image_2,(1400,1400))
print(image_1_re.shape)
print(image_2_re.shape)
(2000, 2400, 3)
(1400, 1400, 3)
创建感兴趣区域(ROI)
感兴趣区域(ROI)是图像中您想要从其余部分单独选择和处理的部分。ROI可以使用坐标或形状(如矩形或多边形)来定义。例如,在图像中进行面部检测时,可以选择ROI,围绕预期的面部位置,以提高算法的准确性和效率。下面的图形表示了它的工作原理。
在上图中,我们希望从大图像(400,700)中剪切一个宽度和高度(100,300)的小白色部分。我们已经为我们的任务做了同样的事情。
我们首先选择了大图像的部分,该部分与小图像的形状相等,位于右下角。
x_off=2400-1400 #offset value of x
y_off=2000-1400 # offset value of y
这些代码行将x_off和y_off定义为从图像中创建ROI的水平和垂直偏移量。第一幅图像的宽度为2400像素,高度为2000像素;第二幅图像的宽度和高度都为1400像素。我们想要在第一幅图像的右下角创建ROI,因为我们想要将第二幅图像粘贴到第一幅图像的右下角。
rows,cols,channels = image_2_re.shape
roi_image = image_1_re[y_off:2000,x_off:2400] # BOTTOM RIGHT CORNER
plt.imshow(roi_image)
上面的图像是我们将粘贴第二幅图像的提取区域。现在,是时候将第二幅图像(版权标识)粘贴到提取区域上了。
创建遮罩图像以放置水印
图像遮罩是选择图像的重要部分并隐藏其余部分的技术。对于我们的情况,我们只想提取以下版权图像的字母部分。
这是一幅具有三个颜色通道的图像。让我们将其转换为灰度图像;否则,我们将很难进行后续操作。
imgTogray = cv2.cvtColor(image_2_re,cv2.COLOR_BGR2GRAY)
plt.imshow(imgTogray,cmap='gray')
在这里,我们看到文本“Capture By Zubair”,是黑色的。我们需要保持这部分不变,而改变其他部分。
我们需要创建一个遮罩,以分离图像的前景和背景。在混合图像时,我们需要创建一个表示前景对象形状的遮罩,以便我们可以将其与背景图像隔离并混合。
让我们反转图像像素,将白色转换为黑色,黑色转换为白色。
inv_mask = cv2.bitwise_not(imgTogray)
plt.imshow(inv_mask,cmap='gray')
现在,我们将在反转的遮罩图像上执行按位或操作,以提取遮罩区域的主要颜色。
[N.B. 如果你想了解更多关于OpenCV按位或操作的信息,请阅读文章。]
https://dontrepeatyourself.org/post/bitwise-operations-and-image-masking-opencv/
https://dontrepeatyourself.org/post/bitwise-operations-and-image-masking-opencv/
fore_g = cv2.bitwise_or(image_2_re, image_2_re, mask= inv_mask)
plt.imshow(fore_g)
我们已成功将版权图像的颜色提取到遮罩区域。再次运行按位或操作,将提取的ROI图像与完整的背景图像合并。
final_roi_val = cv2.bitwise_or(roi_image,fore_g)
plt.imshow(final_roi_val )
让我们将完整的背景图像连接到上面的图像。
l_image = image_1_re
s_image = final_roi_val
l_image[y_off:y_off+s_image.shape[0], x_off:x_off+s_image.shape[1]] = s_image
final_rgb=cv2.cvtColor(l_image,cv2.COLOR_BGR2RGB)
plt.imshow(final_rgb)
我们刚刚用遮罩的ROI图像替换了背景图像像素。最后,我们制作了带有水印的最终图像。
结论
本文尽力以最简单的方式表示混合过程。这种知识是计算机视觉的基础之一。