专业技能大赛之图片处理算法-Python+OpenCV实现对图像处理

T2_1 图片缩放和拓展:

利用 P y t h o n O p e n C V Python OpenCV 图像缩放,用最近邻插值将图片进行缩放。

c v 2. i m r e a d ( ) , c v 2. i m s h o w ( ) , c v 2. i m w r i t e ( ) cv2.imread(), cv2.imshow(), cv2.imwrite() ,读取,显示,保存图片

最近邻插值: 不需要计算,在待求象素的四邻象素中,将距离待求象素最近的邻象素灰度赋给待求象素 。

详细代码:

# i:/vscode/vscode_python/.vscode/数学建模
# -*- coding: utf-8 -*-
'''
@Time    : 2019/11/21 03:51
@Author  : nuoyanli
@Version : 1.0
@Contact : [email protected]
@Site    : 1.69KB
@File    : 图片缩放和拓展.py
@Software: VSCode
'''
import numpy as np
from cv2 import cv2

# 读入原图片
img = cv2.imread('Original_img.jpg')
# 打印出图片尺寸
print(img.shape)
# 将图片高和宽分别赋值给x,y
x, y = img.shape[0:2]

# 显示原图
cv2.imshow('Original_img', img)
# 最近邻插值法缩放
# 放大到原来的二倍,输出尺寸格式为(宽,高)
img_1 = cv2.resize(img, (y*2, x*2), interpolation=cv2.INTER_NEAREST)
cv2.imshow('Double_img', img_1)
cv2.imwrite('Double_img.jpg', img_1)  # 保存已经图片
# 缩放到原来的二分之一
img_2 = cv2.resize(img, (0, 0), fx=0.5, fy=0.5,
                   interpolation=cv2.INTER_NEAREST)
cv2.imshow('Half_img', img_2)
cv2.imwrite('Half_img.jpg', img_2)  # 保存已经图片
cv2.waitKey(0)
cv2.destroyAllWindows()

T2_2:图像修复:

分析过程:

基本思路: 微分方程求解,用邻近的像素替换那些坏标记,使其看起来像是邻居

假设图像里的一个区域要修复。算法从这个区域的边界开始,逐渐地进入区域,把边界内的所有东西填充上。它取要修复的部分周围的一个像素周围的一小片邻居。这个像素被周围已知的像素的标准加权和替换掉。选择权重是很重要的。要修复的点周围像素的权重较高。和正常边界近的,还有在边界轮廓上的像素的权重较高。当像素被修复以后,它会通过快速匹配方法( F M M FMM )移动到最近的像素。 F M M FMM 保证那些已知像素周围的像素首先被修复,所以这个就像人工启发式的操作一样。

O p e n C V OpenCV 提供了两种算法。两者都可以通过相同的函数访问, c v 2. i n p a i n t cv2.inpaint()

第一种算法基于 A l e x a n d r u T e l e a Alexandru Telea 于2004年发表的“基于快速行进方法的图像修复技术”。它基于快速行进方法。考虑图像中要修复的区域。算法从该区域的边界开始,然后进入区域内,逐渐填充边界中的所有内容。它需要在邻近的像素周围的一个小邻域进行修复。该像素由邻居中所有已知像素的归一化加权和代替。选择权重是一个重要的问题。对于靠近该点的那些像素,靠近边界的法线和位于边界轮廓上的像素,给予更多的权重。一旦像素被修复,它将使用快速行进方法移动到下一个最近的像素。 F M M FMM 确保首先修复已知像素附近的像素,这样它就像手动启发式操作一样工作。使用标志 c v 2. I N P A I N T T E L E A cv2.INPAINT_TELEA 启用此算法。

第二种算法基于 B e r t a l m i o Bertalmio M a r c e l o Marcelo A n d r e a Andrea L . B e r t o z z i L. Bertozzi G u i l l e r m o S a p i r o Guillermo Sapiro 2001 2001 年撰写的“Navier-Stokes,流体动力学和图像和视频修补”一文。该算法基于流体动力学并利用偏微分方程。基本原则是 h e u r i s i t i c heurisitic 。它首先沿着已知区域的边缘行进到未知区域(因为边缘是连续的)。它继续等照片(连接具有相同强度的点的线,就像轮廓连接具有相同高度的点一样),同时在修复区域的边界处匹配渐变矢量。为此,使用来自流体动力学的一些方法。获得颜色后,填充颜色以减少该区域的最小差异。使用标志 c v 2. I N P A I N T N S cv2.INPAINT_NS 启用此算法。

简而言之,就是利用那些已经被破坏的区域的边缘, 即边缘的颜色和结构,根据这些图像留下的信息去推断被破坏的信息区的信息内容,然后对破坏区进行填补 ,以达到图像修补的目的。

实现过程:

我创建了一个与输入图像大小相同的蒙版,其中非零像素对应于要修复的区域。我的图像因一些黑色笔画而降级(当然因为找不到合适的图片,我自己手动添加的)。

1.第一次提交文档我用 P S PS 工具创建了相应的 T o b e r e p a i r e d . j p g To_be_repaired.jpg ,同时得到 b e i j i n . j p g beijin.jpg (蒙版)。

2.不久前我发现可以将要修复的图经过阈值处理生成 m a s k mask 这样就很方便对于任意给定的一张图片进行修复。

优化前不能自动生成Mask的代码:

# i:/vscode/vscode_python/.vscode/数学建模
# -*- coding: utf-8 -*-
'''
@Time    : 2019/11/20 23:51
@Author  : nuoyanli
@Version : 1.0
@Contact : [email protected]
@Site    : 0.79KB
@File    : 图片修复.py
@Software: VSCode
'''
from matplotlib import pyplot as plt
import numpy as np
from cv2 import cv2

img = cv2.imread('To_be_repaired.jpg')
cv2.imshow('To_be_repaired', img)
mask = cv2.imread('beijin.jpg', 0)  # 灰度mask

repair = cv2.inpaint(img, mask, 3, cv2.INPAINT_TELEA)
cv2.imshow('Repaired', repair)  # 展示已经修复好的图片
cv2.imwrite('Repaired.jpg', repair)  # 保存已经修复好的图片
cv2.waitKey(0)
cv2.destroyAllWindows()

优化后可以自动生成Mask的代码:

# i:/vscode/vscode_python/.vscode/数学建模
# -*- coding: utf-8 -*-
'''
@Time    : 2019/11/22 16:51
@Author  : nuoyanli
@Version : 1.0
@Contact : [email protected]
@Site    : 2.79KB
@File    : 图片修复.py
@Software: VSCode
'''

from matplotlib import pyplot as plt
import numpy as np
from cv2 import cv2 

img_path = 'test2.jpg'
img = cv2.imread(img_path)
cv2.imshow('Color', img)

# 计算mask, B,G,R三个通道阈值,需根据待修复区域颜色确定
# test1.jpg: >220, >220, >220
# test2.jpg: <20, <20, <20
# test3.jpg: <80, <80, >180
# test4.jpg: ==255,==255,==255

# 修复区域若是
# 黑色  <20, <20 ,<20
# 白色:>220,>220,>220
# 红色: <80, <80, >180
# 无色:==255,==255,==255

mask_B = (img[:, :, 0] < 20).astype(np.uint8)  # 数据类型由float64转化为int8,否则无法显示
mask_G = (img[:, :, 1] < 20).astype(np.uint8)
mask_R = (img[:, :, 2] < 20).astype(np.uint8)
# print(mask_B)
# print(mask_G)
# print(mask_R)
mask = mask_B * mask_G * mask_R * 255

# 闭运算
kernel = cv2.getStructuringElement(
    cv2.MORPH_RECT, (5, 5))  # 定义结构元素, 核尺寸通常是3,5,7
print(kernel)
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)  # 闭运算
# 再膨胀一次,扩大mask区域
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
mask = cv2.dilate(mask, kernel)
cv2.imshow('Mask', mask)

repair = cv2.inpaint(img, mask, 7, cv2.INPAINT_TELEA)  # 3,5,7
# repair = cv2.inpaint(img, mask, 7, cv2.INPAINT_NS)
cv2.imshow('Repaired', repair)  # 展示已经修复好的图片
save_path = img_path.split('.')[0] + '_res.jpg'
cv2.imwrite(save_path, repair)  # 保存已经修复好的图片
cv2.waitKey(0)
cv2.destroyAllWindows()

发布了293 篇原创文章 · 获赞 212 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/nuoyanli/article/details/103281554
今日推荐