一、图像颜色替换
1.定义
在上一节实验《对图像识别颜色》的基础上,如果我们想修改当前颜色,其原理就是在得到原图的掩膜之后,对掩膜中的白色区域所对应的原图中的区域进行一个像素值的修改即可。
大概得步骤就是:
(1)读图
(2)转换颜色空间
(3)制作掩膜
(4)修改像素值
(5)得到新图
2.制作掩膜
掩膜就是只显示你想显示的地方,这里说的显示是用白色区域表示你想显示的地方。
它用于选择性地遮挡图像的某些部分,以实现特定任务的目标。掩膜通常是一个二值化图像,并且与原图像的大小相同,其中目标区域被设置为1(或白色),而其他区域被设置为0(或黑色)。
3.颜色替换
由于掩膜与原图的大小相同,并且像素位置一一对应,那么我们就可以得到掩膜中白色(也就是像素值为255)区域的坐标,并将其带入到原图像中,即可得到原图中的你想显示颜色区域的坐标,然后就可以修改像素值了,这样就完成了颜色的替换。
4.代码实现
步骤:
(1)读图 cv2.imread(path)
(2)转换颜色空间 cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
(3)制作掩膜 cv2.inRange(img_hsv,lower,upper)
(4)修改像素值 img[img_mask == 255] = (0, 255, 0) ---布尔索引
(5)得到新图 cv2.imshow('image_np',image_np)
import cv2
import numpy as np
img = cv2.imread('./photo/8.jpg')
img_hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
#查找红色区域
lower = np.array([156,43,46])
upper = np.array([180,255,255])
#掩膜
img_mask = cv2.inRange(img_hsv,lower,upper)
#替换颜色,变为蓝色
#掩膜为白色的地方用布尔索引,将图像赋成蓝色
img[img_mask == 255] = [255,0,0]
cv2.imshow('img',img)
cv2.imshow('img_mask',img_mask)
cv2.waitKey(0)
这里只找了一部分红色,因为红色的值有两个。
结果:
二、图像添加水印
1.定义
添加水印的概念其实可以理解为将一张图片中的某个物体或者图案提取出来,然后叠加到另一张图片上。
具体的操作思想是通过
(1)将原始图片转换成灰度图,并进行二值化处理;
(2)去除背景部分,得到一个类似掩膜的图像;
(3)将这个二值化图像与另一张图片中要添加水印的区域进行“与”运算,使得目标物体的形状出现在要添加水印的区域;
(4)将得到的目标物体图像与要添加水印的区域进行相加,就完成了添加水印的操作。
这样可以实现将一个图像中的某个物体或图案叠加到另一个图像上,从而实现添加水印的效果。
2.模版输入---带水印图案的掩膜
使用模板输入所输入的图片其实是作为要添加的水印,有了水印的彩色图之后,我们需要用它来制作一个掩模,这就用到了灰度化和二值化,即先灰度化后二值化,这就得到了带有水印图案的掩模。
3.与运输---掩膜与ROI区域
根据掩膜的大小切割出一个ROI区域,也就是我们要添加水印的区域,之后让其与模板的掩膜进行与运算,我们知道,与运算的过程中,只要有黑色像素,那么得到的结果图中的对应位置也会是黑色像素。
4.图像融合--相加(掩膜,与运算时的图)
颜色加法:cv2.add(img1,img2)
5.代码实现
1.引入两张图,一张图为需要添加水印的图,另一张为logo图;cv2.imread(path)
2.切割ROI;roi = img1[: r2 , : r2]
3.灰度化logo图;cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)
4.二值化;cv2.threshold(gray,170, 255, cv2.THRESH_BINARY)
5.与运输(ROI和黑色掩膜);cv2.bitwise_and(roi,roi,mask=ma1)
6.二值化; cv2.threshold(gray, 170, 255, cv2.THRESH_BINARY_INV)
7.与运输(logo图和白色掩膜);cv2.bitwise_and(img2,img2,mask = ma2)
8.颜色加法。cv2.add(fg1, fg2)
import cv2
import numpy as np
img1 = cv2.imread('./photo/87.png')
img2 = cv2.imread('./photo/logo.jpg')
h1,w1,c1 = img1.shape
h2,w2,c2 = img2.shape
#切割
roi = img1[: h2,: w2] #取出img1中跟img2同样大小的区域
#将logo灰度化
gray = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)
#二值化,得到黑色掩膜
ret,mask1 = cv2.threshold(gray,170,255,cv2.THRESH_BINARY)
#阈值法:小于等于阈值的像素就被设置为0(黑)
# 大于阈值的像素就被设置为maxval。
#与运算
fg1 = cv2.bitwise_and(roi,roi,mask=mask1)
# cv2.imshow('mask1',mask1)
cv2.imshow('fg1',fg1)
#二值化,得到白色掩膜
ret,mask2 = cv2.threshold(gray,170,255,cv2.THRESH_BINARY_INV)
fg2 = cv2.bitwise_and(img2,img2,mask=mask2)
# cv2.imshow('mask2',mask2)
cv2.imshow('fg2',fg2)
#图像加法
roi[:] = cv2.add(fg1, fg2)
cv2.imshow('img1',img1)#修改roi的数据相当于修改原图:看下面案例
cv2.waitKey(0)
cv2.destroyAllWindows()
结果: