一.ROI切割
类似裁剪图片,但是原理是基于Numpy数组的切片操作(ROI数组切片是会修改原图数据的),也就是说这个“裁剪”不是为了保存“裁剪”部分,而是为了方便修改等处理。
1 2 3 4 5 6 7 8 9 10 11 12
| import cv2 as cv import numpy as np img = cv.imread('../images/demo.png')
roi = img[70:380, 81:450] cv.imshow('Original', img) cv.imshow('ROI', roi) cv.waitKey(0) cv.destroyAllWindows()
|
结果:

二.图像添加水印
也将一张图片中的某个物体或者图案提取出来,然后叠加到另一张图片上。通过将原始图片转换成灰度图,并进行二值化处理,得到一个类似掩膜的图像。
简要来讲,就是得到一个目标区域大小的黑背景白logo掩膜(获取logo颜色),和一个白背景黑logo掩膜(获取背景颜色),然后两个分别对logo原图和目标区域进行与运算,然后处理后的两个图做饱和运算,就可以得到有颜色有背景的图了。
2.1 模板输入
就是包含水印的图片,先灰度化后二值化(分别用阈值法和反向阈值法),这就得到了白色logo黑背景的掩膜和黑logo白色背景的掩膜。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import cv2 as cv import numpy as np img = cv.imread('../images/ymb3.jpg')
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
_, binary = cv.threshold(gray, 250, 255, cv.THRESH_BINARY)
_, binary_inv = cv.threshold(gray, 250, 255, cv.THRESH_BINARY_INV)
cv.imshow('binary', binary) cv.imshow('binary_inv', binary_inv) cv.waitKey(0) cv.destroyAllWindows()
|
结果:

2.2 与运算
根据掩膜的大小切割出一个ROI区域,也就是我们要添加水印的区域,之后让其与模板的两个掩膜进行与运算,就可以得到有logo黑背景和黑logo有目标区域背景的掩膜。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| import cv2 as cv import numpy as np logo = cv.imread('../images/ymb3.jpg') sy = cv.resize(logo, (150, 150)) img = cv.imread('../images/lvbo.png')
gray = cv.cvtColor(sy, cv.COLOR_BGR2GRAY)
_, binary = cv.threshold(gray, 250, 255, cv.THRESH_BINARY)
_, binary_inv = cv.threshold(gray, 250, 255, cv.THRESH_BINARY_INV)
print(binary.shape) print(img.shape)
roi = img[100:250, 100:250]
bg = cv.bitwise_and(roi, roi, mask=binary)
wm = cv.bitwise_and(sy, sy, mask=binary_inv)
cv.imshow('b', binary) cv.imshow('bi', binary_inv) cv.imshow('sy', sy) cv.imshow('bg', bg) cv.imshow('wm', wm) cv.waitKey(0) cv.destroyAllWindows()
|
结果:

1 2
| (150, 150) (626, 1075, 3)
|
2.3 图像融合
目的就是将图像对应的数组中的对应元素进行相加:
就是opencv两张图相加,饱和运算就是加数值,黑色的区域是0,加5就是5,所以就可以替换黑色变成有颜色的部分。
或者使用 OpenCV 的 cv.addWeighted() 方法可以将两张图片按权重进行混合。通过调整权重参数,可以控制水印的透明度。
1 2 3 4 5 6 7 8 9
| dst = cv.add(bg, wm)
img[100:250, 100:250] = dst cv.imshow('re', dst) cv.imshow('result', img) cv.waitKey(0) cv.destroyAllWindows()
|
结果:

我这里是因为图片里面很多颜色像白色,所以效果没有特别好。