当前位置:   article > 正文

Python cv2 实现图像拼接——双图篡改任务数据准备(1)_an end-to-end solution to constrained image splici

an end-to-end solution to constrained image splicing localization and detect

    在之前的博客中我介绍了图像篡改任务深度学习解决双图篡改问题的一般性思路,这篇博客讲讲对于双图篡改检测任务如何做数据集。

1 概述

    深度学习是数据驱动的模型,数据集的制作有着举足轻重的作用,在双图检测篡改任务中,模型的输入是 possible donor(潜在供体图像)和 query (查询)图像、对应的 mask 以及判断是否篡改的标签 0 或者 1,如下图所示的三种情况输入[1],前面两种是 postive, 第三种是 negative。

                                              

2 实现思路

    

    以第一种情况为例,相同的篡改区域是前景部分,制作模型的输入数据。原始数据为 coco 数据,总体思路如下:

1. 一个文件夹放所有的 raw 图片,一个文件夹放所有的 mask

2. 对于 raw 图片均分成3份,第一份为 p, 第二份为 q, 第三份为 world;

3. 随机选择 mask 文件夹中的一个 mask ,crop mask 找到 mask 的 ROI, 将 ROI 做随机定位,制作新的 mask,对于同一个 mask 做两个 ROI 位置不一样的新的 mask,这样是为了保证 p 和 q 的篡改区域不同;

4. 随机选择 world 文件夹中的一个 world 图片, 两个 mask 从world 中扣取相同的图像,拼接到 p 和 q 上面。

3 代码

  1. """
  2. fig_path 为原始图片路径
  3. mask_paht 为 mask 图片路径
  4. 把 fig_path 路径文件夹下面的图片等分3份,命名 p, q, world
  5. 随机选取 mask 图片一张和 world 的图片一张,根据 mask 抠出 world 图片上面的一个随机区域,拼接到 p 和 q 中的每对图片上面
  6. 此时篡改的区域是来自 world 的抠图,相同的区域是前景
  7. """
  8. import cv2
  9. import numpy as np
  10. import os
  11. fig_path = "D:/AAAASXQ/SDL/raw_data/fig"
  12. mask_path = "D:/AAAASXQ/SDL/raw_data/mask"
  13. out_path = "D:/AAAASXQ/SDL/data_for_model_pos1"
  14. try:
  15. os.makedirs(os.path.join(out_path, 'p'))
  16. os.makedirs(os.path.join(out_path, 'p_maske'))
  17. os.makedirs(os.path.join(out_path, 'q'))
  18. os.makedirs(os.path.join(out_path, 'q_mask'))
  19. except:
  20. pass
  21. out_p_path = os.path.join(out_path, 'p')
  22. out_pmask_path = os.path.join(out_path, 'p_maske')
  23. out_q_path = os.path.join(out_path, 'q')
  24. out_qmask_path = os.path.join(out_path, 'q_mask')
  25. p_list = os.listdir(fig_path)
  26. mask_list = os.listdir(mask_path)
  27. len_mask = len(mask_list)
  28. l = len(pro_list)
  29. l1 = int(l/3)
  30. p = p_list[:l1]
  31. q = p_list[l1: 2*l1]
  32. world = p_list[2*l1:]
  33. len_world = len(world)
  34. def two(fig_path, mask_path, k):
  35. # 生成两张原始 mask,后面增加随机篡改区域
  36. mask1 = np.zeros((256, 256))
  37. mask2 = np.zeros((256, 256))
  38. # 获取 mask 的 ROI
  39. n = np.random.randint(len_mask)
  40. mask = cv2.imread(os.path.join(mask_path, mask_list[n]),-1)
  41. mask = cv2.resize(mask, (256, 256), interpolation=cv2.INTER_NEAREST)
  42. y = mask.sum(axis=1)
  43. y_top = (y != 0).argmax(axis=0)
  44. y_btm = (y != 0).cumsum(axis=0).argmax(axis=0)
  45. x = mask.sum(axis=0)
  46. x_left = (x != 0).argmax(axis=0)
  47. x_right = (x != 0).cumsum(axis=0).argmax(axis=0)
  48. maskROI = mask[y_top:y_btm+1, x_left:x_right+1]
  49. # 读取待篡改图片两张(按照顺序),分别来自 p 和 q
  50. # 读取抠图对象图片一张(随机),来自 world
  51. fig1 = cv2.imread(os.path.join(fig_path, p[k]))
  52. fig1 = cv2.resize(fig1, (256, 256), interpolation=cv2.INTER_CUBIC)
  53. fig2 = cv2.imread(os.path.join(fig_path, q[k]))
  54. fig2 = cv2.resize(fig2, (256, 256), interpolation=cv2.INTER_CUBIC)
  55. w = cv2.imread(os.path.join(fig_path, world[np.random.randint(len_world)]))
  56. w = cv2.resize(w, (256, 256), interpolation=cv2.INTER_CUBIC)
  57. # 生成 p 的 mask
  58. try:
  59. x1_begin = np.random.randint(256 - maskROI.shape[0] - 1)
  60. y1_begin = np.random.randint(256 - maskROI.shape[1] - 1)
  61. except:
  62. x1_begin = 1
  63. y1_begin = 1
  64. mask1[x1_begin:x1_begin + maskROI.shape[0], y1_begin:y1_begin + maskROI.shape[1]] = maskROI
  65. mask1 = mask1.astype(np.uint8)
  66. mask1_inv = cv2.bitwise_not(mask1)
  67. # 生成 q 的 mask
  68. try:
  69. x2_begin = np.random.randint(256 - maskROI.shape[0] - 1)
  70. y2_begin = np.random.randint(256 - maskROI.shape[1] - 1)
  71. except:
  72. x2_begin = 11
  73. y2_begin = 11
  74. mask2[x2_begin:x2_begin + maskROI.shape[0], y2_begin:y2_begin + maskROI.shape[1]] = maskROI
  75. mask2 = mask2.astype(np.uint8)
  76. mask2_inv = cv2.bitwise_not(mask2)
  77. # 生成篡改后的 p
  78. img1 = cv2.bitwise_and(w, w, mask=mask1)
  79. img11 = cv2.bitwise_and(fig1, fig1, mask=mask1_inv)
  80. pfig = cv2.add(img1, img11)
  81. # 生成篡改后的 q
  82. w[x2_begin:x2_begin + maskROI.shape[0], y2_begin:y2_begin + maskROI.shape[1], :] = w[x1_begin:x1_begin + maskROI.shape[0], y1_begin:y1_begin + maskROI.shape[1], :]
  83. img2 = cv2.bitwise_and(w, w, mask=mask2)
  84. img22 = cv2.bitwise_and(fig2, fig2, mask=mask2_inv)
  85. qfig = cv2.add(img2, img22)
  86. return pfig, mask1, qfig, mask2
  87. fig_path = fig_path
  88. mask_path = mask_path
  89. for i in range(100): # 循环制作100次
  90. print(i)
  91. for j in range(l1): # 遍历每个 p 图片
  92. k = j
  93. try:
  94. p, mask1, q, mask2 = two(fig_path, mask_path, k)
  95. cv2.imwrite(out_p_path + '/' + str(i) + '_' + str(j) + '_' + 'p.jpg', p)
  96. cv2.imwrite(out_pmask_path + '/' + str(i) + '_' + str(j) + '_' + 'p_mask.png', mask1)
  97. cv2.imwrite(out_q_path + '/' + str(i) + '_' + str(j) + '_' + 'q.jpg', q)
  98. cv2.imwrite(out_qmask_path + '/' + str(i) + '_' + str(j) + '_' + 'q_mask.png', mask2)
  99. except:
  100. print('error',' ',i, j)
  101. pass

4 结果展示

    篡改后的 probe 和 query:

 

                                       

    对应的 mask:

                                       

5 缺点

    最重要的缺点在于拼接的图像没有逻辑......明眼人一看就知道图像是篡改过的,哪还需要算法做判断。。。后续训练的模型对于真实场景的判断效果可能有限。然而如果是手工制作逼真的篡改图像,想必成本是非常高的。

6 改进

    采用分割数据集做训练数据,这样至少保证 P 中的图像是真实的。数据集做缩放、旋转等数据增广操作。

 

 

参考资料:

[1] Y. Wu, W. Abd-Almageed, and P. Natarajan, “Deep matching and validation network: An end-to-end solution to constrained image splicing localization and detection,” in Proc. 25th ACM Int. Conf. Multimedia, Oct. 2017, pp. 1480–1502.
 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/81408
推荐阅读
相关标签
  

闽ICP备14008679号