图像修复python_⽤python进⾏图像修复与去除⽔印
有时候我们在看知乎的时候,会突然发现⼀张很好看的图⽚,想据为⼰有,猥猥琐琐的准备长按图⽚保存,发现图⽚上居然带了⽔印,这个时候该怎么办呢?哈哈哈,直接裁剪掉不就好了吗~~~
但是,作为⼀个新时代的程序猿,我们不能够就这么简单处理对不对。对
于是翻起了课本,发现有⼀种算法叫做矩阵补全(matrix compltion)可以⽤来做图像修复,可以把模糊成这样的新垣结⾐修复新垣结⾐原图
加了两次⾼斯噪声的新垣结⾐修复后的新垣结⾐
虽然⽐原图模糊了⼀点,但新垣结⾐还是美丽好看的(甚⾄别有⼀番韵味)。那么其实我们可以想⼀想噪声其实就是相当于数据缺失,那么⽔印也是相当于数据缺失,那么矩阵补全可以把图像修复,是不是也可以把⽔印去掉呢?投影机屏幕
⾸先,我们来了解⼀下什么是矩阵补全
矩阵补全(matrix completion)
根据字⾯意思就是有⼀个矩阵,⾥⾯有⼀些元素是缺失的,我们要想办法把缺失的元素补全,这就是矩阵补全了。
矩阵补全⼀开始是从Netflix 的⼀个⽐赛中流⾏开来的,悬赏100万美⾦给能够提⾼公司现⾏的matrix completion 算法10%以上的优胜队伍。
以⾖瓣为例,就是根据电影的评分系统做推断。但是我们知道,⾖瓣的⽤户千千万,电影的数量千千万,但是每个⽤户对只会对极少的电影进⾏评分,那么这个矩阵中⼤部分的数据是缺失的,我们要根据这个⾮常稀疏的矩阵,来推断整个⽤户对不同电影的评分,这就是矩阵补
全的实际应⽤。Netflix⽐赛
我们这⾥图像也可以看做是⼀个矩阵(彩⾊图像可以看成是三个图像),残缺的图像就相当于缺失的数据,那么通过算法把缺失的数据补上也就是修复图像了。
⽔印去除
我的思路就是,在有⽔印的地⽅,加⼀块⿊⾊遮罩,模拟数据缺失,然后运⽤矩阵补全的⽅式复原,同样⽤新垣结⾐来试验,先⽤⿊⾊ 颜⾊块遮罩,然后就会惊⼈的发现加了⾊块就好了,因为背景就是⿊⾊。。。。
加了⿊⾊⾊块就好了。。。。根本不⽤修复,但是我还是不死⼼的进⾏了⼀番操作修复后的新垣结⾐2
发现修复后的图⽚还不如原来的,因为这次矩阵补全把⿊⾊块附近的裙⼦给学习过去了。看来有点风险,还是先不⽤新垣结⾐的照⽚,先⽤别的测试测试
好吧,我们换⼀张风景图⽚,有⼀块⼩⽔印有⽔印的图加了遮罩的图复原图
可以看出,复原图虽然有⼀点瑕疵,但是已经算是⽐较成功的把⽔印去掉了,那么说明这个算法还是⽐较靠谱的,那么我们还是换上新垣结⾐的照⽚,了⼀张好看的,但是没有⽔印,但是不影响我们的实验,我们假设她有⽔印,然后我们加上⿊⾊遮罩原图打了码的新垣结⾐修
复后的新垣结⾐
要女朋友有什么用不得不说,修复效果很⼀般,新垣结⾐都毁容了
很愤怒,于是乱画⼀通发泄乱画之后的新垣结⾐
⼀时⽓愤不由得把新垣结⾐乱涂乱画起来,现在后悔不已,那么能不能够复原呢?我们来看⼀看再次修复的新垣结⾐
结论
综上来看,⽤矩阵分解的办法来进⾏图像修复效果还是很不错的,不论是⾼噪声照⽚还是被乱涂乱画之后的照⽚, 可以⽤于家⾥照⽚被熊孩⼦乱涂乱画之后的修复。
但是对于⽔印去除呢,部分图⽚还是可以的,但是部分图⽚效果还是差强⼈意。灵蛇髻
其实内在含义就是,当数据连续缺失区域不⼤时,如上图风景照⽚或者细⼩的涂鸦笔记,矩阵补全的效果就⽐较好,但是当数据连续缺失区域较⼤时,矩阵补全的效果可能就没有那么好,特使是⽤在如此美丽动⼈的新垣结⾐⾝上,⼩⼩瑕疵就会被放⼤得更厉害。
下⾯是具体实现源码:
主要⽤的算法是LRMC
import numpy as np
def svt(mat, tau):
u, s, v = np.linalg.svd(mat, full_matrices = 0)
网上订票取票
vec = s - tau个性qq英文网名
vec[vec < 0] = 0
return np.matmul(np.matmul(u, np.diag(vec)), v)
def LRMC(sparse_mat, dense_mat, rho, maxiter):
pos_train = np.where(sparse_mat != 0)
pos_test = np.where((sparse_mat == 0) & (dense_mat != 0))
binary_mat = py()
binary_mat[pos_train] = 1
X = py()
Z = py()
T = py()
rse = np.zeros(maxiter)
for it in range(maxiter):
Z = svt(X + T / rho, 1 / rho)
X = Z - T / rho
X[pos_train] = sparse_mat[pos_train]
T = T - rho * (Z - X)
rse[it] = ((X[pos_test] - dense_mat[pos_test], 2)
/ (dense_mat[pos_test], 2))
return X, rse
准备两张图
import imageio
import matplotlib.pyplot as plt
lena = imageio.imread('z6.bmp')/255.0
sparse_lena=imageio.imread('z6ss.bmp')/255.0
print('The shape of the image is {}.'.format(lena.shape))
dim1, dim2,dim3 = lena.shape
mask = np.round(np.random.rand(dim1, dim2,dim3)) # Generate a binary mask. mask1 = np.round(np.random.rand(dim1, dim2,dim3))
# mask2 = np.round(np.random.rand(dim1, dim2))
plt.figure(figsize=(15,12))
plt.imshow(lena)
plt.title('The original Lena')
plt.axis('off')
plt.figure(figsize=(15,12))
plt.imshow(sparse_lena)梦见狗咬我是什么意思
plt.title('The incomplete Lena')
plt.axis("off")
plt.show()
因为是彩⾊图⽚,所以需要将图⽚分成三原⾊再分别进⾏修复
import time
start = time.time()
rho = 0.005
maxiter = 50
mat_hat, rse_svt = LRMC(sparse_lena[:,:,0], lena[:,:,0], rho, maxiter) print('Running time:%dseconds.'%(end - start))
start = time.time()
mat_hat1, rse_svt1 = LRMC(sparse_lena[:,:,1], lena[:,:,1], rho, maxiter) print('Running time:%dseconds.'%(end - start))
start = time.time()
mat_hat2, rse_svt2 = LRMC(sparse_lena[:,:,2], lena[:,:,2], rho, maxiter) print('Running time:%dseconds.'%(end - start))
#修复完把三张图拼接在⼀起
c=[]
for i in range(dim1):
c.append([])
for j in range(dim2):
c[i].append([mat_hat[i][j],mat_hat1[i][j],mat_hat2[i][j]])
显⽰修复后的图⽚
plt.figure(figsize=(20,15))
# plt.imshow(mat_hat)
plt.imshow(c)
# plt.imshow(mat_hat2)
plt.savefig("lbk.png")
plt.axis('off')
plt.show()
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论