{
  "id": 164828,
  "title": "Learning Rich Features for Image Manipulation Detection",
  "url": "/competitions/alaska2-image-steganalysis/discussion/164828",
  "author_name": "",
  "post_date": "2020-07-07T17:21:49.627944400Z",
  "votes": 10,
  "comment_count": 1,
  "views": 0,
  "content": "<p>Looks Promising ?</p>\n\n<p><img src=\"https://raw.githubusercontent.com/LarryJiang134/Image_manipulation_detection/master/_image/11.png\" alt=\"\"></p>\n\n<p><code>\nThe RGB stream models visual tampering artifacts, such as unusually\nhigh contrast along object edges, and regresses bounding boxes to the ground-truth. The noise stream first obtains the noise feature map\nby passing input RGB image through an SRM filter layer, and leverages the noise features to provide additional evidence for manipulation\nclassification.\n</code></p>\n\n<p>```python\ndef setup_srm_weights(input_channels: int = 3) -&gt; torch.Tensor:\n    \"\"\"Creates the SRM kernels for noise analysis.\"\"\"\n    # note: values taken from Zhou et al., \"Learning Rich Features for Image Manipulation Detection\", CVPR2018\n    srm_kernel = torch.from_numpy(np.array([\n        [  # srm 1/2 horiz\n            [0., 0., 0., 0., 0.],  # noqa: E241,E201\n            [0., 0., 0., 0., 0.],  # noqa: E241,E201\n            [0., 1., -2., 1., 0.],  # noqa: E241,E201\n            [0., 0., 0., 0., 0.],  # noqa: E241,E201\n            [0., 0., 0., 0., 0.],  # noqa: E241,E201\n        ], [  # srm 1/4\n            [0., 0., 0., 0., 0.],  # noqa: E241,E201\n            [0., -1., 2., -1., 0.],  # noqa: E241,E201\n            [0., 2., -4., 2., 0.],  # noqa: E241,E201\n            [0., -1., 2., -1., 0.],  # noqa: E241,E201\n            [0., 0., 0., 0., 0.],  # noqa: E241,E201\n        ], [  # srm 1/12\n            [-1., 2., -2., 2., -1.],  # noqa: E241,E201\n            [2., -6., 8., -6., 2.],  # noqa: E241,E201\n            [-2., 8., -12., 8., -2.],  # noqa: E241,E201\n            [2., -6., 8., -6., 2.],  # noqa: E241,E201\n            [-1., 2., -2., 2., -1.],  # noqa: E241,E201\n        ]\n    ])).float()\n    srm_kernel[0] /= 2\n    srm_kernel[1] /= 4\n    srm_kernel[2] /= 12\n    return srm_kernel.view(3, 1, 5, 5).repeat(1, input_channels, 1, 1)</p>\n\n<p>def setup_srm_layer(input_channels: int = 3) -&gt; torch.nn.Module:\n    \"\"\"Creates a SRM convolution layer for noise analysis.\"\"\"\n    weights = setup_srm_weights(input_channels)\n    conv = torch.nn.Conv2d(input_channels, out_channels=3, kernel_size=5, stride=1, padding=2, bias=False)\n    with torch.no_grad():\n        conv.weight = torch.nn.Parameter(weights, requires_grad=False)\n    return conv</p>\n\n<p>```</p>\n\n<p>```python\nclass AlaskaClassifierSRM(nn.Module):\n    def <strong>init</strong>(self, encoder, dropout_rate=0.5, num_class=4) -&gt; None:\n        super().<strong>init</strong>()\n        self.encoder = EfficientNet()\n        self.avg_pool = AdaptiveAvgPool2d((1, 1))\n        self.srm_conv = setup_srm_layer(3)\n        self.dropout = Dropout(dropout_rate)\n        self.fc = Linear(encoder_params[encoder][\"features\"], num_class)</p>\n\n<pre><code>def forward(self, x):\n    noise = self.srm_conv(x)\n    x = self.encoder.forward_features(noise)\n    x = self.avg_pool(x).flatten(1)\n    x = self.dropout(x)\n    x = self.fc(x)\n    return x\n</code></pre>\n\n<p>```</p>",
  "messages": [
    {
      "id": "919054",
      "postDate": "07/07/2020 17:21:49",
      "content": "<p>Looks Promising ?</p>\n\n<p><img src=\"https://raw.githubusercontent.com/LarryJiang134/Image_manipulation_detection/master/_image/11.png\" alt=\"\"></p>\n\n<p><code>\nThe RGB stream models visual tampering artifacts, such as unusually\nhigh contrast along object edges, and regresses bounding boxes to the ground-truth. The noise stream first obtains the noise feature map\nby passing input RGB image through an SRM filter layer, and leverages the noise features to provide additional evidence for manipulation\nclassification.\n</code></p>\n\n<p>```python\ndef setup_srm_weights(input_channels: int = 3) -&gt; torch.Tensor:\n    \"\"\"Creates the SRM kernels for noise analysis.\"\"\"\n    # note: values taken from Zhou et al., \"Learning Rich Features for Image Manipulation Detection\", CVPR2018\n    srm_kernel = torch.from_numpy(np.array([\n        [  # srm 1/2 horiz\n            [0., 0., 0., 0., 0.],  # noqa: E241,E201\n            [0., 0., 0., 0., 0.],  # noqa: E241,E201\n            [0., 1., -2., 1., 0.],  # noqa: E241,E201\n            [0., 0., 0., 0., 0.],  # noqa: E241,E201\n            [0., 0., 0., 0., 0.],  # noqa: E241,E201\n        ], [  # srm 1/4\n            [0., 0., 0., 0., 0.],  # noqa: E241,E201\n            [0., -1., 2., -1., 0.],  # noqa: E241,E201\n            [0., 2., -4., 2., 0.],  # noqa: E241,E201\n            [0., -1., 2., -1., 0.],  # noqa: E241,E201\n            [0., 0., 0., 0., 0.],  # noqa: E241,E201\n        ], [  # srm 1/12\n            [-1., 2., -2., 2., -1.],  # noqa: E241,E201\n            [2., -6., 8., -6., 2.],  # noqa: E241,E201\n            [-2., 8., -12., 8., -2.],  # noqa: E241,E201\n            [2., -6., 8., -6., 2.],  # noqa: E241,E201\n            [-1., 2., -2., 2., -1.],  # noqa: E241,E201\n        ]\n    ])).float()\n    srm_kernel[0] /= 2\n    srm_kernel[1] /= 4\n    srm_kernel[2] /= 12\n    return srm_kernel.view(3, 1, 5, 5).repeat(1, input_channels, 1, 1)</p>\n\n<p>def setup_srm_layer(input_channels: int = 3) -&gt; torch.nn.Module:\n    \"\"\"Creates a SRM convolution layer for noise analysis.\"\"\"\n    weights = setup_srm_weights(input_channels)\n    conv = torch.nn.Conv2d(input_channels, out_channels=3, kernel_size=5, stride=1, padding=2, bias=False)\n    with torch.no_grad():\n        conv.weight = torch.nn.Parameter(weights, requires_grad=False)\n    return conv</p>\n\n<p>```</p>\n\n<p>```python\nclass AlaskaClassifierSRM(nn.Module):\n    def <strong>init</strong>(self, encoder, dropout_rate=0.5, num_class=4) -&gt; None:\n        super().<strong>init</strong>()\n        self.encoder = EfficientNet()\n        self.avg_pool = AdaptiveAvgPool2d((1, 1))\n        self.srm_conv = setup_srm_layer(3)\n        self.dropout = Dropout(dropout_rate)\n        self.fc = Linear(encoder_params[encoder][\"features\"], num_class)</p>\n\n<pre><code>def forward(self, x):\n    noise = self.srm_conv(x)\n    x = self.encoder.forward_features(noise)\n    x = self.avg_pool(x).flatten(1)\n    x = self.dropout(x)\n    x = self.fc(x)\n    return x\n</code></pre>\n\n<p>```</p>",
      "rawMarkdown": "Looks Promising ?\n\n![](https://raw.githubusercontent.com/LarryJiang134/Image_manipulation_detection/master/_image/11.png)\n\n```\nThe RGB stream models visual tampering artifacts, such as unusually\nhigh contrast along object edges, and regresses bounding boxes to the ground-truth. The noise stream first obtains the noise feature map\nby passing input RGB image through an SRM filter layer, and leverages the noise features to provide additional evidence for manipulation\nclassification.\n```\n\n \n```python\ndef setup_srm_weights(input_channels: int = 3) -&gt; torch.Tensor:\n    \"\"\"Creates the SRM kernels for noise analysis.\"\"\"\n    # note: values taken from Zhou et al., \"Learning Rich Features for Image Manipulation Detection\", CVPR2018\n    srm_kernel = torch.from_numpy(np.array([\n        [  # srm 1/2 horiz\n            [0., 0., 0., 0., 0.],  # noqa: E241,E201\n            [0., 0., 0., 0., 0.],  # noqa: E241,E201\n            [0., 1., -2., 1., 0.],  # noqa: E241,E201\n            [0., 0., 0., 0., 0.],  # noqa: E241,E201\n            [0., 0., 0., 0., 0.],  # noqa: E241,E201\n        ], [  # srm 1/4\n            [0., 0., 0., 0., 0.],  # noqa: E241,E201\n            [0., -1., 2., -1., 0.],  # noqa: E241,E201\n            [0., 2., -4., 2., 0.],  # noqa: E241,E201\n            [0., -1., 2., -1., 0.],  # noqa: E241,E201\n            [0., 0., 0., 0., 0.],  # noqa: E241,E201\n        ], [  # srm 1/12\n            [-1., 2., -2., 2., -1.],  # noqa: E241,E201\n            [2., -6., 8., -6., 2.],  # noqa: E241,E201\n            [-2., 8., -12., 8., -2.],  # noqa: E241,E201\n            [2., -6., 8., -6., 2.],  # noqa: E241,E201\n            [-1., 2., -2., 2., -1.],  # noqa: E241,E201\n        ]\n    ])).float()\n    srm_kernel[0] /= 2\n    srm_kernel[1] /= 4\n    srm_kernel[2] /= 12\n    return srm_kernel.view(3, 1, 5, 5).repeat(1, input_channels, 1, 1)\n\n\ndef setup_srm_layer(input_channels: int = 3) -&gt; torch.nn.Module:\n    \"\"\"Creates a SRM convolution layer for noise analysis.\"\"\"\n    weights = setup_srm_weights(input_channels)\n    conv = torch.nn.Conv2d(input_channels, out_channels=3, kernel_size=5, stride=1, padding=2, bias=False)\n    with torch.no_grad():\n        conv.weight = torch.nn.Parameter(weights, requires_grad=False)\n    return conv\n\n```\n\n \n```python\nclass AlaskaClassifierSRM(nn.Module):\n    def __init__(self, encoder, dropout_rate=0.5, num_class=4) -&gt; None:\n        super().__init__()\n        self.encoder = EfficientNet()\n        self.avg_pool = AdaptiveAvgPool2d((1, 1))\n        self.srm_conv = setup_srm_layer(3)\n        self.dropout = Dropout(dropout_rate)\n        self.fc = Linear(encoder_params[encoder][\"features\"], num_class)\n        \n    def forward(self, x):\n        noise = self.srm_conv(x)\n        x = self.encoder.forward_features(noise)\n        x = self.avg_pool(x).flatten(1)\n        x = self.dropout(x)\n        x = self.fc(x)\n        return x\n\n```",
      "votes": null
    },
    {
      "id": "920572",
      "postDate": "07/08/2020 17:17:24",
      "content": "<p><a href=\"/bibek777\">@bibek777</a> Thanks for sharing. It's useful.</p>",
      "rawMarkdown": "bibek777 Thanks for sharing. It's useful.",
      "votes": null
    }
  ],
  "comments": [
    {
      "id": 920572,
      "author_name": "vishnurapps",
      "author_url": "",
      "post_date": "07/08/2020 17:17:24",
      "content": "<p><a href=\"/bibek777\">@bibek777</a> Thanks for sharing. It's useful.</p>",
      "votes": null,
      "replies": []
    }
  ],
  "raw_markdown_by_id": {
    "919054": "Looks Promising ?\n\n![](https://raw.githubusercontent.com/LarryJiang134/Image_manipulation_detection/master/_image/11.png)\n\n```\nThe RGB stream models visual tampering artifacts, such as unusually\nhigh contrast along object edges, and regresses bounding boxes to the ground-truth. The noise stream first obtains the noise feature map\nby passing input RGB image through an SRM filter layer, and leverages the noise features to provide additional evidence for manipulation\nclassification.\n```\n\n \n```python\ndef setup_srm_weights(input_channels: int = 3) -&gt; torch.Tensor:\n    \"\"\"Creates the SRM kernels for noise analysis.\"\"\"\n    # note: values taken from Zhou et al., \"Learning Rich Features for Image Manipulation Detection\", CVPR2018\n    srm_kernel = torch.from_numpy(np.array([\n        [  # srm 1/2 horiz\n            [0., 0., 0., 0., 0.],  # noqa: E241,E201\n            [0., 0., 0., 0., 0.],  # noqa: E241,E201\n            [0., 1., -2., 1., 0.],  # noqa: E241,E201\n            [0., 0., 0., 0., 0.],  # noqa: E241,E201\n            [0., 0., 0., 0., 0.],  # noqa: E241,E201\n        ], [  # srm 1/4\n            [0., 0., 0., 0., 0.],  # noqa: E241,E201\n            [0., -1., 2., -1., 0.],  # noqa: E241,E201\n            [0., 2., -4., 2., 0.],  # noqa: E241,E201\n            [0., -1., 2., -1., 0.],  # noqa: E241,E201\n            [0., 0., 0., 0., 0.],  # noqa: E241,E201\n        ], [  # srm 1/12\n            [-1., 2., -2., 2., -1.],  # noqa: E241,E201\n            [2., -6., 8., -6., 2.],  # noqa: E241,E201\n            [-2., 8., -12., 8., -2.],  # noqa: E241,E201\n            [2., -6., 8., -6., 2.],  # noqa: E241,E201\n            [-1., 2., -2., 2., -1.],  # noqa: E241,E201\n        ]\n    ])).float()\n    srm_kernel[0] /= 2\n    srm_kernel[1] /= 4\n    srm_kernel[2] /= 12\n    return srm_kernel.view(3, 1, 5, 5).repeat(1, input_channels, 1, 1)\n\n\ndef setup_srm_layer(input_channels: int = 3) -&gt; torch.nn.Module:\n    \"\"\"Creates a SRM convolution layer for noise analysis.\"\"\"\n    weights = setup_srm_weights(input_channels)\n    conv = torch.nn.Conv2d(input_channels, out_channels=3, kernel_size=5, stride=1, padding=2, bias=False)\n    with torch.no_grad():\n        conv.weight = torch.nn.Parameter(weights, requires_grad=False)\n    return conv\n\n```\n\n \n```python\nclass AlaskaClassifierSRM(nn.Module):\n    def __init__(self, encoder, dropout_rate=0.5, num_class=4) -&gt; None:\n        super().__init__()\n        self.encoder = EfficientNet()\n        self.avg_pool = AdaptiveAvgPool2d((1, 1))\n        self.srm_conv = setup_srm_layer(3)\n        self.dropout = Dropout(dropout_rate)\n        self.fc = Linear(encoder_params[encoder][\"features\"], num_class)\n        \n    def forward(self, x):\n        noise = self.srm_conv(x)\n        x = self.encoder.forward_features(noise)\n        x = self.avg_pool(x).flatten(1)\n        x = self.dropout(x)\n        x = self.fc(x)\n        return x\n\n```",
    "920572": "bibek777 Thanks for sharing. It's useful."
  },
  "source": "meta"
}