小言_互联网的博客

使用深度学习生成模糊背景

220人阅读  评论(0)

概述

  • 介绍我们使用的深度学习模型和ReLu6

  • 介绍如何使用深度学习生成模糊背景

介绍

背景模糊效果是一种常见的图像效果,主要用于拍摄特写镜头上。它可以给我们的图像增加了一种深度感,突出关注图像的某一部分。

为了获得这种效果,我们通常使用一些照片编辑应用程序,例如Photoshop,Gimp,Picsart,Snapseed等,但随着时间的推移,我们在计算机视觉和使用深度学习的图像处理方面取得了显着改善,我们可以使用深度学习来获得这种效果。

在本文中,会引导你完成完整的实现以及代码和一些理论方面的知识,以便更好地理解相关内容。

目录

  1. 实现原理

  2. 我们使用的深度学习模型

  3. ReLu6

  4. 实施

  5. 得分

  6. 结论

1. 实现原理

基本上,我们的整个目标是基于称为图像分割的卷积神经网络的高级实现。我们都熟悉CNN,它用于基于图像输入标签数量图像分类,但是,假设为此必须在给定图像中标识特定对象,我们必须使用对象检测和图像分割的概念。

这是图像分类和检测的经典示例,其中如果在单个图像中有多个类别的对象可用,那么我们在进行对象检测的过程中,一旦找到了多个对象的坐标,则给定图像将经过ROIPooling(region of interest pooling),对这些对象进行分类,并在每个标识的对象周围绘制边框。

由于边界框仅显示对象在图像内部的位置,所以不会提供有关对象形状的任何信息。

简而言之,图像分割是将图像像素分为小部分或片段,并根据相似的信息或属性将它们分组并为其分配标签的过程,这有助于捕获像素级别的非常小的细节。分割会为图像中的每个已识别对象创建一个像素级模板,请看下面的图片,其主要目的是以这种方式训练神经网络,使其可以提供图像的像素级模板。要了解更多详细信息,请单击以下链接

  • https://towardsdatascience.com/going-deep-into-object-detection-bed442d92b34

2. 我们使用的深度学习模型

在了解图像分割概念知乎,接下来让我们看一下要使用的模型,即在coco数据集上训练的mobilenetv2。

mobilenetv2是一种轻量级模型,可以在手机等低功耗设备上使用,这是2017年发布的mobilenetv1模型的第二个版本。

现在让我们简要了解模型架构。

v2是基于v1的,因此它继承了相同的深度方向的可分离卷积,其中包括深度方向的卷积和点方向的卷积,从而降低了卷积操作的成本。

深度卷积简单地说,假设一幅图像包含3个通道,那么每个内核将分别在每个通道上迭代。

例如,你有一张(10 x 10 x 3)的图像和(3 x 3 x 1)的3个滤波器,那么结果输出将是一个(8 x 8 x 1)这样的滤波器,之后所有其他滤波器的输出滤波器堆叠在一起,形成由(8 x 8 x 3)组成的特征图。

在逐点卷积中,我们采用(8 x 8 x 3)的先前特征图,并应用大小为(1 x 1 x 3)的过滤器,如果应用了15个此类滤波器,则最终结果将叠加起来形成(8 x 8 x 15)的特征图。

mobilenetv2对v1进行了一些改进,例如实现了反向残差,线性瓶颈和残差连接。

Source-MachineThink.Net

v2总共包含3个卷积层,其中第一个是扩展层,第二个是深度层,第三个是投影层。

扩展层:此层接收输入数据并将低维数据扩展为高维,以便保留重要信息并将其输出提供给深度层。扩展因子是一个超参数,可根据试验次数进行调整。

深度层:该层从扩展层接收输入,并执行深度和点向卷积,将特征图提供给投影层。

投影层:该层负责缩小数据的尺寸,以便仅有限数量的数据在网络中进一步传递,此时输入尺寸与输出尺寸匹配,这也称为“瓶颈”层”。

Source-MachineThink.Net

残差连接是基于ResNet的网络的新增功能,有助于控制通过网络的渐变流,使用时输入数据的维数与输出数据的维数相同。

3. ReLu6

该网络中的每个层都带有ReLu6,而不是带有批量标准化的ReLu。ReLu6将值的范围限制在0到6之间,这是一个线性激活函数。通过限制小数点左边的3位信息,还有助于将精度保持在小数点右边。

研究人员表示,最后一层(即投影层)的输出不具有激活功能,因为其输出是低维数据。

根据研究人员的说法,在最后一层中添加任何非线性函数都可能导致有用信息的丢失。

4. 实施

现在,我们对图像分割和使用的mobilenetv2有了一个大概的了解,接下来让我们来看一下如何去实现。

先决条件:该代码使用TensorFlow版本1.x,因此你需要拥有版本1.x才能正常工作,如果你使用的是2.x,则执行时会出错,因此建议你仅使用Google Collab来执行。

在GitHub上的笔记本中逐行解释快速介绍代码的所有重要方面和完整实现。

  • https://github.com/patrickn699/Background_Blur.git

为了演示,我们将使用以下尺寸为(596 x 900)的图片

步骤1:下载经过预先训练的模型。

由于模型是经过预训练的,因此只需下载并将我们的图像传递给它,它会返回分割后的图像。


   
  1. MODEL_NAME =  'mobilenetv2_coco_voctrainaug' #@参数[  'mobilenetv2_coco_voctrainaug',  'mobilenetv2_coco_voctrainval',  'xception_coco_voctrainaug',  'xception_coco_voctrainval'] _DOWNLOAD_URL_PREFIX =  ' http://download.tensorflow.org/models/'
  2. _MODEL_URLS = {
  3.      'mobilenetv2_coco_voctrainaug'
  4.          'deeplabv3_mnv2_pascal_train_aug_2018_01_29.tar.gz'
  5.      'mobilenetv2_coco_voctrainval'
  6.          'deeplabv3_mnv2_pascal_trainval_2018_01_29.tar.gz'
  7.      'xception_coco_voctrainaug'
  8.          'deeplabv3_pascal_train_aug_2018_01_04.tar.gz'
  9.      'xception_coco_voctrainval'
  10.          'deeplabv3_pascal_trainval_2018_01_04.tar.gz'
  11. }
  12. _TARBALL_NAME = 'deeplab_model.tar.gz'model_dir = tempfile.mkdtemp()
  13. tf.gfile.MakeDirs(model_dir)下载路径= os.path.join(model_dir,_TARBALL_NAME)
  14. 打印(“正在下载模型,这可能需要一段时间...”)
  15. urllib.request.urlretrieve(_DOWNLOAD_URL_PREFIX + _MODEL_URLS [MODEL_NAME],
  16.                    download_path)
  17. 打印( '下载完成!正在加载DeepLab模型...')MODEL = DeepLabModel(download_path)
  18. 打印( '模型加载成功!'

步骤2:用于可视化从输入中获取的分割图像的功能。

   
  1. def run_visualization():
  2.    "" "Inferences DeepLab model and visualizes result." ""
  3.    try:
  4.     original_im = Image.open(IMAGE_NAME)
  5.   except IOError:
  6.      print( 'Cannot retrieve image. Please check url: ' + url)
  7.     returnprint( 'running deeplab on image')
  8.   resized_im, seg_map = MODEL.run(original_im)
  9.   vis_segmentation(resized_im, seg_map)
  10.    return resized_im, seg_map

2.1:使用前面显示的图像调用上述功能。


   
  1. IMAGE_NAME =  'download2.jpg'
  2. resized_im, seg_map = run_visualization()

分割后输出。

2.2:现在,我们读取输入图像并将其转换为numpy数组。


   
  1. print(type(resized_im))
  2. numpy_image = np. array(resized_im)
步骤3:分离背景和前景。

在此步骤中,我们创建图像的副本,然后,通过将背景中的值替换为0,并在已创建蒙版的位置保留255,将背景和前景与分割后的图像分开,此处7表示汽车类别。


   
  1. person_not_person_mapping = deepcopy(numpy_image)
  2. person_not_person_mapping[seg_map !=  7] =  0
  3. person_not_person_mapping[seg_map ==  7] =  255

3.1:可视化分离的蒙版图像


   
  1. plt.imshow(person_not_person_mapping)

正如上一步中所述,背景已被黑色替换,汽车蒙版已变为白色,同样,通过替换这些值,我们也没有丢失任何重要信息。

3.2:调整蒙版图像的大小使其等于原始图像。

在分割过程之后,图像的大小减小了,在我们的例子中,图像的大小减小为(300 x 500),因此我们将图像的大小调整为原始大小,即(900 x 596)。


   
  1. orig_imginal = Image.open(IMAGE_NAME)
  2. orig_imginal = np. array(orig_imginal)mapping_resized = cv2.resize(person_not_person_mapping, 
  3.                              (orig_imginal.shape[ 1],
  4.                               orig_imginal.shape[ 0]),
  5.                               Image.ANTIALIAS)
  6. mapping_resized.shape

3.3:二值化

由于调整了大小,图像生成的值在0,1,2…255之间,为了再次将值限制在0–255之间,我们必须使用Otsu的Binarization技术对图像进行二值化。简而言之,Otsu的Binarization是一种寻找灰度图像阈值的自适应方法,它遍历0-255范围内的所有可能阈值,并找到给定图像的最佳可能阈值。

在内部,它基于一些统计概念(例如方差),以根据所选阈值找出类别。一旦选择了最佳阈值,则大于阈值的像素值将被视为白色像素,小于阈值的像素值将被视为黑色像素。

更多有关信息:

  • https://medium.com/@hbyacademic/otsu-thresholding-4337710dc519


   
  1. gray = cv2.cvtColor(mapping_resized, cv2.COLOR_BGR2GRAY)
  2. blurred = cv2.GaussianBlur(gray,( 15, 15), 0)
  3. ret3,thresholded_img = cv2.threshold(blurred, 0, 255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
  4. plt.imshow(thresholded_img)

输出将保持不变,与上一个没有任何区别。

步骤4:为阈值图像添加颜色。

现在我们完成了二值化,是时候将灰度图像转换为RGB图像了。


   
  1. mapping = cv2.cvtColor(thresholded_img, cv2.COLOR_GRAY2RGB)
  2. np.unique(mapping)

在输出中,将颜色应用于图像后,它包含两个唯一的像素值,即0,255。

我们将在接下来的步骤中应用背景模糊。

4.1:对原始图像应用模糊处理。

接下来,让我们将背景模糊效果应用于原始输入图像。


   
  1. blurred_original_image = cv2.GaussianBlur(orig_imginal,
  2.                                           ( 251, 251), 0)
  3. plt.imshow(blurred_original_image)

4.2:获得背景模糊。

在这个步骤中,我们使用简单的代码片段对输入图像的背景进行模糊处理。


   
  1. layered_image = np.where(mapping != ( 0, 0, 0), 
  2.                          orig_imginal, 
  3.                          blurred_original_image)
  4. plt.imshow(layered_image)

在上面的代码片段中,我们所做的只是简单地填充像素强度值为0的模糊图像,即填充所有黑色像素和填充像素强度值为255(白色像素)的原始图像,这产生了一个漂亮的散景效果,如下图所示。

4.3:最后保存图像。

现在剩下要做的就是保存散景图像了!


   
  1. im_rgb = cv2.cvtColor(layered_image, cv2.COLOR_BGR2RGB)
  2. cv2.imwrite( "Potrait_Image.jpg", im_rgb)

5. 得分

本文是参考Bhavesh Bhatt的视频而写的,在 GitHub 页面上提供了带有逐行注释的完整代码。

  • https://github.com/patrickn699/Background_Blur.git

6. 结论

总而言之,获得背景模糊只是深度学习可以做的事情之一,随着技术的进步,深度学习模型从分类到生成深层伪造的模型做的越来越好了,在不久的未来,相信会有更大的发展。

☆ END ☆

如果看到这里,说明你喜欢这篇文章,请转发、点赞。微信搜索「uncle_pn」,欢迎添加小编微信「 mthler」,每日朋友圈更新一篇高质量博文。

扫描二维码添加小编↓


转载:https://blog.csdn.net/woshicver/article/details/114314894
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场