{
  "id": 150359,
  "title": "RGB, YUV or DCT which one should be used?",
  "url": "/competitions/alaska2-image-steganalysis/discussion/150359",
  "author_name": "Johnny Lee",
  "post_date": "2020-05-12T02:18:06.537000",
  "votes": 31,
  "comment_count": 34,
  "views": 0,
  "content": "<p>I have tried RGB + augmentation + binary classification. It can get LB 0.85~. Multiclass classification is useful. It can get LB 0.88~. Since the secret data is hidden in DCT, I also tried DCT. But it's more easily to become overfitting, because it's difficult to apply augmentation to DCT. \nAny idea?</p>",
  "messages": [
    {
      "id": 843366,
      "postDate": "2020-05-12T02:18:06.537Z",
      "content": "<p>I have tried RGB + augmentation + binary classification. It can get LB 0.85~. Multiclass classification is useful. It can get LB 0.88~. Since the secret data is hidden in DCT, I also tried DCT. But it's more easily to become overfitting, because it's difficult to apply augmentation to DCT. \nAny idea?</p>",
      "rawMarkdown": "I have tried RGB + augmentation + binary classification. It can get LB 0.85~. Multiclass classification is useful. It can get LB 0.88~. Since the secret data is hidden in DCT, I also tried DCT. But it's more easily to become overfitting, because it's difficult to apply augmentation to DCT. \nAny idea?",
      "votes": 29
    },
    {
      "id": 843382,
      "postDate": "2020-05-12T02:37:11.500Z",
      "content": "<p>Hello There,\nDid you try YCbCr ? And can you tell how it works by contrast to RGB ?\nI would guess that YCbCr is more relevant since data is hidden is the DCT after RGB-&gt;YCbCr transformation\nAlso, I understand that using DCT coefficient only might hurt, but what if you use both (either in the same net, or using two different net and then merging) ?\nAnyway, thanks for the great job and very valuable comment</p>",
      "rawMarkdown": "Hello There,\nDid you try YCbCr ? And can you tell how it works by contrast to RGB ?\nI would guess that YCbCr is more relevant since data is hidden is the DCT after RGB-&gt;YCbCr transformation\nAlso, I understand that using DCT coefficient only might hurt, but what if you use both (either in the same net, or using two different net and then merging) ?\nAnyway, thanks for the great job and very valuable comment",
      "votes": 8,
      "replies": [
        {
          "id": 843402,
          "postDate": "2020-05-12T03:06:55.150Z",
          "content": "<p>I'm not familiar to JPEG. I tried the YUV transformation, and the result was not so good.\nSo the right one is YCbCr. :) I'll try it again. Thank you for pointing it out.</p>",
          "rawMarkdown": "I'm not familiar to JPEG. I tried the YUV transformation, and the result was not so good.\nSo the right one is YCbCr. :) I'll try it again. Thank you for pointing it out.",
          "votes": 1
        },
        {
          "id": 843465,
          "postDate": "2020-05-12T04:01:46.950Z",
          "content": "<p>Yes you are right, I can provide you with a code that starts by reading the DCT coefficients from JPEG (not imread that does a conversion into RGB automatically) and then decompressed directly the YCbCr values of pixels</p>",
          "rawMarkdown": "Yes you are right, I can provide you with a code that starts by reading the DCT coefficients from JPEG (not imread that does a conversion into RGB automatically) and then decompressed directly the YCbCr values of pixels",
          "votes": 6
        },
        {
          "id": 844106,
          "postDate": "2020-05-12T13:01:54.877Z",
          "content": "<p><a href=\"/remicogranne\">@remicogranne</a> hi, would you mind to share a notebook on that, please?</p>",
          "rawMarkdown": "@remicogranne hi, would you mind to share a notebook on that, please?"
        },
        {
          "id": 844561,
          "postDate": "2020-05-12T17:18:19.587Z",
          "content": "<p>JMiPOD, JUNIWARD and UERD make embedding changes on the quantized DCT coefficients. So, when transforming back to the original spatial domain, these changes are spread all over the pixels. That's why it might be better to work with YCbCr, right? For instance JMiPOD uses the IDCT to work with the original spatial space (YCbCr). I guess converting RGB directly to YCbCr it's not the optimal solution?</p>\n\n<p>Let us know if this makes a difference! :)</p>",
          "rawMarkdown": "JMiPOD, JUNIWARD and UERD make embedding changes on the quantized DCT coefficients. So, when transforming back to the original spatial domain, these changes are spread all over the pixels. That's why it might be better to work with YCbCr, right? For instance JMiPOD uses the IDCT to work with the original spatial space (YCbCr). I guess converting RGB directly to YCbCr it's not the optimal solution?\n\nLet us know if this makes a difference! :)"
        },
        {
          "id": 844684,
          "postDate": "2020-05-12T19:12:13.727Z",
          "content": "<p>As per request from <a href=\"/ipythonx\">@ipythonx</a> \nI have tried to make this notebook that does : \n (1) the YCbCr extraction from JPEG \n (2) show how the quality factor is involved in this process (at the very end)</p>\n\n<p><a href=\"https://www.kaggle.com/remicogranne/jpeg-explanations\">https://www.kaggle.com/remicogranne/jpeg-explanations</a></p>",
          "rawMarkdown": "As per request from @ipythonx \nI have tried to make this notebook that does : \n (1) the YCbCr extraction from JPEG \n (2) show how the quality factor is involved in this process (at the very end)\n\n[https://www.kaggle.com/remicogranne/jpeg-explanations](https://www.kaggle.com/remicogranne/jpeg-explanations)\n",
          "votes": 6
        },
        {
          "id": 844879,
          "postDate": "2020-05-12T22:47:16.877Z",
          "content": "<p>Hi <a href=\"/remicogranne\">@remicogranne</a>,</p>\n\n<p>Is converting to YCbCr as easy as <code>imgYCC = cv2.cvtColor(img, cv2.COLOR_BGR2YCR_CB)</code> or is this not the way we should be doing it?</p>",
          "rawMarkdown": "Hi @remicogranne,\n\nIs converting to YCbCr as easy as `imgYCC = cv2.cvtColor(img, cv2.COLOR_BGR2YCR_CB)` or is this not the way we should be doing it?",
          "votes": 4
        },
        {
          "id": 845000,
          "postDate": "2020-05-13T02:01:42.280Z",
          "content": "<p>I have the same question.</p>",
          "rawMarkdown": "I have the same question."
        },
        {
          "id": 845167,
          "postDate": "2020-05-13T04:51:20.583Z",
          "content": "<p><a href=\"/vaillant\">@vaillant</a> &amp; <a href=\"/wuliaokaola\">@wuliaokaola</a> \nYes you can get YCbCr by using conversion from RGB to YCbCr. \nHowever, think about what you are actually doing, when you open jpeg file you actually decompress it (hence, transform DCT back into RGB value), there you are doing something like this : \nJPEG --&gt; YCbCr --&gt; RGB --&gt; YCbCr\nWhile this it not completely wrong, each and every conversion adds some \"noise\", some errors (mostly because of rounding).\nWhat I propose i to do only one-step conversion:\nJPEG --&gt; YCbCr\nIn order to avoid adding extra error that may end up being quite large as compare to the tiny signal we want to detect</p>",
          "rawMarkdown": "@vaillant &amp; @wuliaokaola \nYes you can get YCbCr by using conversion from RGB to YCbCr. \nHowever, think about what you are actually doing, when you open jpeg file you actually decompress it (hence, transform DCT back into RGB value), there you are doing something like this : \nJPEG --&gt; YCbCr --&gt; RGB --&gt; YCbCr\nWhile this it not completely wrong, each and every conversion adds some \"noise\", some errors (mostly because of rounding).\nWhat I propose i to do only one-step conversion:\nJPEG --&gt; YCbCr\nIn order to avoid adding extra error that may end up being quite large as compare to the tiny signal we want to detect",
          "votes": 8
        },
        {
          "id": 845503,
          "postDate": "2020-05-13T08:38:05.207Z",
          "content": "<p>Thank you for your explanation.</p>",
          "rawMarkdown": "Thank you for your explanation."
        },
        {
          "id": 845981,
          "postDate": "2020-05-13T14:17:22.937Z",
          "content": "<p>Thanks <a href=\"/remicogranne\">@remicogranne</a>. When I run your code to get the YCbCr image, I notice that it returns floats in approximately the range (-130, 130). Is this normal? </p>",
          "rawMarkdown": "Thanks @remicogranne. When I run your code to get the YCbCr image, I notice that it returns floats in approximately the range (-130, 130). Is this normal? "
        },
        {
          "id": 847192,
          "postDate": "2020-05-14T08:15:18.113Z",
          "content": "<p>Yes, CbCr are in the range ( -128,128 )\nNot sure whether an offset is added to encode the value as an unsigned integer or if a signed bit is used :c </p>",
          "rawMarkdown": "Yes, CbCr are in the range ( -128,128 )\nNot sure whether an offset is added to encode the value as an unsigned integer or if a signed bit is used :c "
        },
        {
          "id": 851159,
          "postDate": "2020-05-17T12:05:44.893Z",
          "content": "<p>Hi <a href=\"/remicogranne\">@remicogranne</a>. If I am not mistaken during the process of jpeg encoding chroma channels are downsampled. Is it somehow taken into account?</p>",
          "rawMarkdown": "Hi @remicogranne. If I am not mistaken during the process of jpeg encoding chroma channels are downsampled. Is it somehow taken into account?"
        },
        {
          "id": 855273,
          "postDate": "2020-05-20T18:14:11.750Z",
          "content": "<p>It seems the given JPEGs are non-standard ones, without chrome subsampling.</p>",
          "rawMarkdown": "It seems the given JPEGs are non-standard ones, without chrome subsampling.",
          "votes": 2
        }
      ]
    },
    {
      "id": 845590,
      "postDate": "2020-05-13T09:52:15.973Z",
      "content": "<p>A simple test of loading (100 images) time via kaggle kernel:\n| cv2 read | jpio read | jpio + imDecompressYCbCr|\n| --- | --- |\n| 750ms | 1.94s |20s |</p>\n\n<p><a href=\"/remicogranne\">@remicogranne</a> do you have any advices to optimize the processing time of YCbCr? 20s for 100 images is too slow : (</p>",
      "rawMarkdown": "A simple test of loading (100 images) time via kaggle kernel:\n| cv2 read | jpio read | jpio + imDecompressYCbCr|\n| --- | --- |\n| 750ms | 1.94s |20s |\n\n@remicogranne do you have any advices to optimize the processing time of YCbCr? 20s for 100 images is too slow : (",
      "votes": 5,
      "replies": [
        {
          "id": 845610,
          "postDate": "2020-05-13T10:15:45.090Z",
          "content": "<p>Im facing the same problem. Let's see if we can reduce the processing time</p>",
          "rawMarkdown": "Im facing the same problem. Let's see if we can reduce the processing time"
        },
        {
          "id": 847186,
          "postDate": "2020-05-14T08:12:55.177Z",
          "content": "<p>Excellent remark, I never pay attention to this (running my code on a 150+ cores machine in multithreading ....)\nI'll have a look a difference between the two ways, perhaps loading pixels values and converting to YCbCr may be enough 😢 </p>",
          "rawMarkdown": "Excellent remark, I never pay attention to this (running my code on a 150+ cores machine in multithreading ....)\nI'll have a look a difference between the two ways, perhaps loading pixels values and converting to YCbCr may be enough 😢 ",
          "votes": 3
        },
        {
          "id": 847239,
          "postDate": "2020-05-14T08:48:18.223Z",
          "content": "<p>You can also process them once and save in a raw npy format. Using imageio+freeimage, you can save 4x16=64bits to a PNG. \nWould be nice to see jpegio add ycbcr output natively using underlying libjpeg.</p>",
          "rawMarkdown": "You can also process them once and save in a raw npy format. Using imageio+freeimage, you can save 4x16=64bits to a PNG. \nWould be nice to see jpegio add ycbcr output natively using underlying libjpeg.",
          "votes": 1
        },
        {
          "id": 850599,
          "postDate": "2020-05-16T19:59:16.473Z",
          "content": "<p>Perhaps I am wrong but, I think you can accomplish this objective with PIL using:\n<code>\nimage = Image.open(file_name)\nimage.draft('YCbCr', None)\nimage.load()\n</code></p>",
          "rawMarkdown": "Perhaps I am wrong but, I think you can accomplish this objective with PIL using:\n```\nimage = Image.open(file_name)\nimage.draft('YCbCr', None)\nimage.load()\n```",
          "votes": 1
        },
        {
          "id": 867736,
          "postDate": "2020-05-30T15:13:58.827Z",
          "content": "<p>Hi <a href=\"/yiheng\">@yiheng</a> I have made a version which is nearly 6x faster here: <a href=\"https://www.kaggle.com/anjum48/faster-ycbcr-decoding\">https://www.kaggle.com/anjum48/faster-ycbcr-decoding</a></p>",
          "rawMarkdown": "Hi @yiheng I have made a version which is nearly 6x faster here: https://www.kaggle.com/anjum48/faster-ycbcr-decoding",
          "votes": 12
        },
        {
          "id": 868838,
          "postDate": "2020-05-31T14:21:55.453Z",
          "content": "<p>thanks!</p>",
          "rawMarkdown": "thanks!"
        },
        {
          "id": 929228,
          "postDate": "2020-07-14T14:45:46.400Z",
          "content": "<p>Thanks</p>",
          "rawMarkdown": "Thanks"
        }
      ]
    },
    {
      "id": 942393,
      "postDate": "2020-07-23T18:09:15.307Z",
      "content": "<p>One question: does DCT stand for discrete cosine transform (it seems to be but I would like to be sure)? If that's the case, you said that augmentation is hard to apply to DCT. Isn't it possible to apply the transformation first then move to the DCT space? Thanks! </p>",
      "rawMarkdown": "One question: does DCT stand for discrete cosine transform (it seems to be but I would like to be sure)? If that's the case, you said that augmentation is hard to apply to DCT. Isn't it possible to apply the transformation first then move to the DCT space? Thanks! ",
      "votes": 1,
      "replies": [
        {
          "id": 942525,
          "postDate": "2020-07-23T19:44:02.560Z",
          "content": "<p><a href=\"/yassinealouini\">@yassinealouini</a> by DCT we mean <strong>quantized</strong> discrete cosine transform domain. The mapping is not bijective with the spatial domain. If you do what you suggest, you will introduce additional (double compression) noise which will most likely weaken the stego signal.</p>",
          "rawMarkdown": "@yassinealouini by DCT we mean **quantized** discrete cosine transform domain. The mapping is not bijective with the spatial domain. If you do what you suggest, you will introduce additional (double compression) noise which will most likely weaken the stego signal.",
          "votes": 2
        },
        {
          "id": 942552,
          "postDate": "2020-07-23T20:07:23.860Z",
          "content": "<p>Awesome, thanks for the details! Any resources to read more about these (even Kaggle discussion threads)? I could find some by Googling but I am being lazy :p </p>",
          "rawMarkdown": "Awesome, thanks for the details! Any resources to read more about these (even Kaggle discussion threads)? I could find some by Googling but I am being lazy :p "
        },
        {
          "id": 942572,
          "postDate": "2020-07-23T20:38:27.573Z",
          "content": "<p><a href=\"/yassinealouini\">@yassinealouini</a> that's a very nice question. I was also wondering the same answer, thank you for the clarification <a href=\"/yousfi\">@yousfi</a>. However, I'm new in sense of applying CNN on DCT or YCbCr, would you mind to refer some baseline code example regarding this? Thanks. </p>",
          "rawMarkdown": "@yassinealouini that's a very nice question. I was also wondering the same answer, thank you for the clarification @yousfi. However, I'm new in sense of applying CNN on DCT or YCbCr, would you mind to refer some baseline code example regarding this? Thanks. "
        },
        {
          "id": 942583,
          "postDate": "2020-07-23T20:55:50.957Z",
          "content": "<p>Check out this Computerphile video on how JPEG and DCT works (the rest of the series is good too):\n<a href=\"https://www.youtube.com/watch?v=Q2aEzeMDHMA\">https://www.youtube.com/watch?v=Q2aEzeMDHMA</a></p>\n\n<p>To add to what <a href=\"/yousfi\">@yousfi</a> said, most augmentations like crops &amp; rotations will require a final interpolation (e.g. cv2.INTER_LINEAR) etc. That interpolation will add noise and destroy the stego payload. Augmentations that don't use interpolation, e.g. GridShuffle keep the stego payload intact</p>",
          "rawMarkdown": "Check out this Computerphile video on how JPEG and DCT works (the rest of the series is good too):\nhttps://www.youtube.com/watch?v=Q2aEzeMDHMA\n\nTo add to what @yousfi said, most augmentations like crops &amp; rotations will require a final interpolation (e.g. cv2.INTER_LINEAR) etc. That interpolation will add noise and destroy the stego payload. Augmentations that don't use interpolation, e.g. GridShuffle keep the stego payload intact\n",
          "votes": 3
        },
        {
          "id": 942592,
          "postDate": "2020-07-23T21:06:22.007Z",
          "content": "<p><a href=\"/anjum48\">@anjum48</a> \nthanks for this info, cool. One query, wasn't the rotation safe in this case?</p>",
          "rawMarkdown": "@anjum48 \nthanks for this info, cool. One query, wasn't the rotation safe in this case?"
        },
        {
          "id": 942603,
          "postDate": "2020-07-23T21:18:51.737Z",
          "content": "<p>I think that if you use rotations in multiples of 90 degrees it is safe, but anything else requires interpolation.</p>\n\n<p>I didn't spend too much time in this comp, but with my B0 model, I got decent results using <code>RandomRotate90</code>,  <code>Flip</code>, <code>Transpose</code> and <code>RandomGridShuffle</code>. As long as the size of each square in the grid shuffle is larger than 8x8 pixels and a multiple of 8, the DCT coeffs should be undisturbed. Jonny Lee had a great idea of not shuffling the border since this was where UERD placed most of the changes</p>",
          "rawMarkdown": "I think that if you use rotations in multiples of 90 degrees it is safe, but anything else requires interpolation.\n\nI didn't spend too much time in this comp, but with my B0 model, I got decent results using `RandomRotate90`,  `Flip`, `Transpose` and `RandomGridShuffle`. As long as the size of each square in the grid shuffle is larger than 8x8 pixels and a multiple of 8, the DCT coeffs should be undisturbed. Jonny Lee had a great idea of not shuffling the border since this was where UERD placed most of the changes",
          "votes": 1
        },
        {
          "id": 942617,
          "postDate": "2020-07-23T21:47:13.830Z",
          "content": "<p><a href=\"/anjum48\">@anjum48</a> I was just about to link to your decompression notebook: <a href=\"https://www.kaggle.com/anjum48/faster-ycbcr-decoding\">https://www.kaggle.com/anjum48/faster-ycbcr-decoding</a> a great starter if anyone wants to change their inputs to DCT.</p>",
          "rawMarkdown": "@anjum48 I was just about to link to your decompression notebook: https://www.kaggle.com/anjum48/faster-ycbcr-decoding a great starter if anyone wants to change their inputs to DCT.",
          "votes": 1
        },
        {
          "id": 942621,
          "postDate": "2020-07-23T22:01:27.243Z",
          "content": "<p><a href=\"/anjum48\">@anjum48</a> <a href=\"/yousfi\">@yousfi</a> Here is <a href=\"https://www.kaggle.com/wuliaokaola/alaska2-best-b6-inference-private-lb-0-929\">my method</a> if you use TPU and tf.data.Dataset. I rewrite <a href=\"/anjum48\">@anjum48</a> 's method in TF way.</p>",
          "rawMarkdown": "@anjum48 @yousfi Here is [my method](https://www.kaggle.com/wuliaokaola/alaska2-best-b6-inference-private-lb-0-929) if you use TPU and tf.data.Dataset. I rewrite @anjum48 's method in TF way.",
          "votes": 2
        }
      ]
    },
    {
      "id": 844933,
      "postDate": "2020-05-13T00:02:37.130Z",
      "content": "<p>i think the split DCT table can't easy let dnn to study. so i have try combine the different position of DCT table of the whole picture, but this method dont bing some prove. I plot the diff of same picture different steganaly . i find the DCT different just +-1 different. maybe dnn dont easy to study this little different. so I think we should transfer the color/shape space to another obvious different space.</p>",
      "rawMarkdown": "i think the split DCT table can't easy let dnn to study. so i have try combine the different position of DCT table of the whole picture, but this method dont bing some prove. I plot the diff of same picture different steganaly . i find the DCT different just +-1 different. maybe dnn dont easy to study this little different. so I think we should transfer the color/shape space to another obvious different space.",
      "votes": 2
    },
    {
      "id": 846550,
      "postDate": "2020-05-13T20:49:52.647Z",
      "content": "<p>hey please checkout this kernel it might be helpful \n<a href=\"https://www.kaggle.com/pranshu29/more-image-processing-ideas-analysis\">https://www.kaggle.com/pranshu29/more-image-processing-ideas-analysis</a></p>",
      "rawMarkdown": "hey please checkout this kernel it might be helpful \nhttps://www.kaggle.com/pranshu29/more-image-processing-ideas-analysis"
    },
    {
      "id": 843401,
      "postDate": "2020-05-12T03:06:24.947Z",
      "rawMarkdown": "",
      "isDeleted": true
    }
  ],
  "comments": [
    {
      "id": 843382,
      "author_name": "Rémi Cogranne",
      "author_url": "",
      "post_date": "2020-05-12T02:37:11.500000",
      "content": "<p>Hello There,\nDid you try YCbCr ? And can you tell how it works by contrast to RGB ?\nI would guess that YCbCr is more relevant since data is hidden is the DCT after RGB-&gt;YCbCr transformation\nAlso, I understand that using DCT coefficient only might hurt, but what if you use both (either in the same net, or using two different net and then merging) ?\nAnyway, thanks for the great job and very valuable comment</p>",
      "votes": 8,
      "replies": [
        {
          "id": 843402,
          "author_name": "Johnny Lee",
          "author_url": "",
          "post_date": "2020-05-12T03:06:55.150000",
          "content": "<p>I'm not familiar to JPEG. I tried the YUV transformation, and the result was not so good.\nSo the right one is YCbCr. :) I'll try it again. Thank you for pointing it out.</p>",
          "votes": 1,
          "replies": []
        },
        {
          "id": 843465,
          "author_name": "Rémi Cogranne",
          "author_url": "",
          "post_date": "2020-05-12T04:01:46.950000",
          "content": "<p>Yes you are right, I can provide you with a code that starts by reading the DCT coefficients from JPEG (not imread that does a conversion into RGB automatically) and then decompressed directly the YCbCr values of pixels</p>",
          "votes": 6,
          "replies": []
        },
        {
          "id": 844106,
          "author_name": "Innat",
          "author_url": "",
          "post_date": "2020-05-12T13:01:54.877000",
          "content": "<p><a href=\"/remicogranne\">@remicogranne</a> hi, would you mind to share a notebook on that, please?</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 844561,
          "author_name": "GuillemDelgado",
          "author_url": "",
          "post_date": "2020-05-12T17:18:19.587000",
          "content": "<p>JMiPOD, JUNIWARD and UERD make embedding changes on the quantized DCT coefficients. So, when transforming back to the original spatial domain, these changes are spread all over the pixels. That's why it might be better to work with YCbCr, right? For instance JMiPOD uses the IDCT to work with the original spatial space (YCbCr). I guess converting RGB directly to YCbCr it's not the optimal solution?</p>\n\n<p>Let us know if this makes a difference! :)</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 844684,
          "author_name": "Rémi Cogranne",
          "author_url": "",
          "post_date": "2020-05-12T19:12:13.727000",
          "content": "<p>As per request from <a href=\"/ipythonx\">@ipythonx</a> \nI have tried to make this notebook that does : \n (1) the YCbCr extraction from JPEG \n (2) show how the quality factor is involved in this process (at the very end)</p>\n\n<p><a href=\"https://www.kaggle.com/remicogranne/jpeg-explanations\">https://www.kaggle.com/remicogranne/jpeg-explanations</a></p>",
          "votes": 6,
          "replies": []
        },
        {
          "id": 844879,
          "author_name": "Ian Pan",
          "author_url": "",
          "post_date": "2020-05-12T22:47:16.877000",
          "content": "<p>Hi <a href=\"/remicogranne\">@remicogranne</a>,</p>\n\n<p>Is converting to YCbCr as easy as <code>imgYCC = cv2.cvtColor(img, cv2.COLOR_BGR2YCR_CB)</code> or is this not the way we should be doing it?</p>",
          "votes": 4,
          "replies": []
        },
        {
          "id": 845000,
          "author_name": "Johnny Lee",
          "author_url": "",
          "post_date": "2020-05-13T02:01:42.280000",
          "content": "<p>I have the same question.</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 845167,
          "author_name": "Rémi Cogranne",
          "author_url": "",
          "post_date": "2020-05-13T04:51:20.583000",
          "content": "<p><a href=\"/vaillant\">@vaillant</a> &amp; <a href=\"/wuliaokaola\">@wuliaokaola</a> \nYes you can get YCbCr by using conversion from RGB to YCbCr. \nHowever, think about what you are actually doing, when you open jpeg file you actually decompress it (hence, transform DCT back into RGB value), there you are doing something like this : \nJPEG --&gt; YCbCr --&gt; RGB --&gt; YCbCr\nWhile this it not completely wrong, each and every conversion adds some \"noise\", some errors (mostly because of rounding).\nWhat I propose i to do only one-step conversion:\nJPEG --&gt; YCbCr\nIn order to avoid adding extra error that may end up being quite large as compare to the tiny signal we want to detect</p>",
          "votes": 8,
          "replies": []
        },
        {
          "id": 845503,
          "author_name": "Johnny Lee",
          "author_url": "",
          "post_date": "2020-05-13T08:38:05.207000",
          "content": "<p>Thank you for your explanation.</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 845981,
          "author_name": "Ian Pan",
          "author_url": "",
          "post_date": "2020-05-13T14:17:22.937000",
          "content": "<p>Thanks <a href=\"/remicogranne\">@remicogranne</a>. When I run your code to get the YCbCr image, I notice that it returns floats in approximately the range (-130, 130). Is this normal? </p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 847192,
          "author_name": "Rémi Cogranne",
          "author_url": "",
          "post_date": "2020-05-14T08:15:18.113000",
          "content": "<p>Yes, CbCr are in the range ( -128,128 )\nNot sure whether an offset is added to encode the value as an unsigned integer or if a signed bit is used :c </p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 851159,
          "author_name": "Arthur Stsepanenka",
          "author_url": "",
          "post_date": "2020-05-17T12:05:44.893000",
          "content": "<p>Hi <a href=\"/remicogranne\">@remicogranne</a>. If I am not mistaken during the process of jpeg encoding chroma channels are downsampled. Is it somehow taken into account?</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 855273,
          "author_name": "Eugene Khvedchenya",
          "author_url": "",
          "post_date": "2020-05-20T18:14:11.750000",
          "content": "<p>It seems the given JPEGs are non-standard ones, without chrome subsampling.</p>",
          "votes": 2,
          "replies": []
        }
      ]
    },
    {
      "id": 845590,
      "author_name": "Yiheng Wang",
      "author_url": "",
      "post_date": "2020-05-13T09:52:15.973000",
      "content": "<p>A simple test of loading (100 images) time via kaggle kernel:\n| cv2 read | jpio read | jpio + imDecompressYCbCr|\n| --- | --- |\n| 750ms | 1.94s |20s |</p>\n\n<p><a href=\"/remicogranne\">@remicogranne</a> do you have any advices to optimize the processing time of YCbCr? 20s for 100 images is too slow : (</p>",
      "votes": 5,
      "replies": [
        {
          "id": 845610,
          "author_name": "GuillemDelgado",
          "author_url": "",
          "post_date": "2020-05-13T10:15:45.090000",
          "content": "<p>Im facing the same problem. Let's see if we can reduce the processing time</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 847186,
          "author_name": "Rémi Cogranne",
          "author_url": "",
          "post_date": "2020-05-14T08:12:55.177000",
          "content": "<p>Excellent remark, I never pay attention to this (running my code on a 150+ cores machine in multithreading ....)\nI'll have a look a difference between the two ways, perhaps loading pixels values and converting to YCbCr may be enough 😢 </p>",
          "votes": 3,
          "replies": []
        },
        {
          "id": 847239,
          "author_name": "robga",
          "author_url": "",
          "post_date": "2020-05-14T08:48:18.223000",
          "content": "<p>You can also process them once and save in a raw npy format. Using imageio+freeimage, you can save 4x16=64bits to a PNG. \nWould be nice to see jpegio add ycbcr output natively using underlying libjpeg.</p>",
          "votes": 1,
          "replies": []
        },
        {
          "id": 850599,
          "author_name": "Brian Farrar",
          "author_url": "",
          "post_date": "2020-05-16T19:59:16.473000",
          "content": "<p>Perhaps I am wrong but, I think you can accomplish this objective with PIL using:\n<code>\nimage = Image.open(file_name)\nimage.draft('YCbCr', None)\nimage.load()\n</code></p>",
          "votes": 1,
          "replies": []
        },
        {
          "id": 867736,
          "author_name": "datasaurus",
          "author_url": "",
          "post_date": "2020-05-30T15:13:58.827000",
          "content": "<p>Hi <a href=\"/yiheng\">@yiheng</a> I have made a version which is nearly 6x faster here: <a href=\"https://www.kaggle.com/anjum48/faster-ycbcr-decoding\">https://www.kaggle.com/anjum48/faster-ycbcr-decoding</a></p>",
          "votes": 12,
          "replies": []
        },
        {
          "id": 868838,
          "author_name": "Yiheng Wang",
          "author_url": "",
          "post_date": "2020-05-31T14:21:55.453000",
          "content": "<p>thanks!</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 929228,
          "author_name": "Prachi",
          "author_url": "",
          "post_date": "2020-07-14T14:45:46.400000",
          "content": "<p>Thanks</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 942393,
      "author_name": "Yassine Alouini",
      "author_url": "",
      "post_date": "2020-07-23T18:09:15.307000",
      "content": "<p>One question: does DCT stand for discrete cosine transform (it seems to be but I would like to be sure)? If that's the case, you said that augmentation is hard to apply to DCT. Isn't it possible to apply the transformation first then move to the DCT space? Thanks! </p>",
      "votes": 1,
      "replies": [
        {
          "id": 942525,
          "author_name": "Yassine Yousfi",
          "author_url": "",
          "post_date": "2020-07-23T19:44:02.560000",
          "content": "<p><a href=\"/yassinealouini\">@yassinealouini</a> by DCT we mean <strong>quantized</strong> discrete cosine transform domain. The mapping is not bijective with the spatial domain. If you do what you suggest, you will introduce additional (double compression) noise which will most likely weaken the stego signal.</p>",
          "votes": 2,
          "replies": []
        },
        {
          "id": 942552,
          "author_name": "Yassine Alouini",
          "author_url": "",
          "post_date": "2020-07-23T20:07:23.860000",
          "content": "<p>Awesome, thanks for the details! Any resources to read more about these (even Kaggle discussion threads)? I could find some by Googling but I am being lazy :p </p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 942572,
          "author_name": "Innat",
          "author_url": "",
          "post_date": "2020-07-23T20:38:27.573000",
          "content": "<p><a href=\"/yassinealouini\">@yassinealouini</a> that's a very nice question. I was also wondering the same answer, thank you for the clarification <a href=\"/yousfi\">@yousfi</a>. However, I'm new in sense of applying CNN on DCT or YCbCr, would you mind to refer some baseline code example regarding this? Thanks. </p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 942583,
          "author_name": "datasaurus",
          "author_url": "",
          "post_date": "2020-07-23T20:55:50.957000",
          "content": "<p>Check out this Computerphile video on how JPEG and DCT works (the rest of the series is good too):\n<a href=\"https://www.youtube.com/watch?v=Q2aEzeMDHMA\">https://www.youtube.com/watch?v=Q2aEzeMDHMA</a></p>\n\n<p>To add to what <a href=\"/yousfi\">@yousfi</a> said, most augmentations like crops &amp; rotations will require a final interpolation (e.g. cv2.INTER_LINEAR) etc. That interpolation will add noise and destroy the stego payload. Augmentations that don't use interpolation, e.g. GridShuffle keep the stego payload intact</p>",
          "votes": 3,
          "replies": []
        },
        {
          "id": 942592,
          "author_name": "Innat",
          "author_url": "",
          "post_date": "2020-07-23T21:06:22.007000",
          "content": "<p><a href=\"/anjum48\">@anjum48</a> \nthanks for this info, cool. One query, wasn't the rotation safe in this case?</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 942603,
          "author_name": "datasaurus",
          "author_url": "",
          "post_date": "2020-07-23T21:18:51.737000",
          "content": "<p>I think that if you use rotations in multiples of 90 degrees it is safe, but anything else requires interpolation.</p>\n\n<p>I didn't spend too much time in this comp, but with my B0 model, I got decent results using <code>RandomRotate90</code>,  <code>Flip</code>, <code>Transpose</code> and <code>RandomGridShuffle</code>. As long as the size of each square in the grid shuffle is larger than 8x8 pixels and a multiple of 8, the DCT coeffs should be undisturbed. Jonny Lee had a great idea of not shuffling the border since this was where UERD placed most of the changes</p>",
          "votes": 1,
          "replies": []
        },
        {
          "id": 942617,
          "author_name": "Yassine Yousfi",
          "author_url": "",
          "post_date": "2020-07-23T21:47:13.830000",
          "content": "<p><a href=\"/anjum48\">@anjum48</a> I was just about to link to your decompression notebook: <a href=\"https://www.kaggle.com/anjum48/faster-ycbcr-decoding\">https://www.kaggle.com/anjum48/faster-ycbcr-decoding</a> a great starter if anyone wants to change their inputs to DCT.</p>",
          "votes": 1,
          "replies": []
        },
        {
          "id": 942621,
          "author_name": "Johnny Lee",
          "author_url": "",
          "post_date": "2020-07-23T22:01:27.243000",
          "content": "<p><a href=\"/anjum48\">@anjum48</a> <a href=\"/yousfi\">@yousfi</a> Here is <a href=\"https://www.kaggle.com/wuliaokaola/alaska2-best-b6-inference-private-lb-0-929\">my method</a> if you use TPU and tf.data.Dataset. I rewrite <a href=\"/anjum48\">@anjum48</a> 's method in TF way.</p>",
          "votes": 2,
          "replies": []
        }
      ]
    },
    {
      "id": 844933,
      "author_name": "Zhang Yunfei",
      "author_url": "",
      "post_date": "2020-05-13T00:02:37.130000",
      "content": "<p>i think the split DCT table can't easy let dnn to study. so i have try combine the different position of DCT table of the whole picture, but this method dont bing some prove. I plot the diff of same picture different steganaly . i find the DCT different just +-1 different. maybe dnn dont easy to study this little different. so I think we should transfer the color/shape space to another obvious different space.</p>",
      "votes": 2,
      "replies": []
    },
    {
      "id": 846550,
      "author_name": "pranshu",
      "author_url": "",
      "post_date": "2020-05-13T20:49:52.647000",
      "content": "<p>hey please checkout this kernel it might be helpful \n<a href=\"https://www.kaggle.com/pranshu29/more-image-processing-ideas-analysis\">https://www.kaggle.com/pranshu29/more-image-processing-ideas-analysis</a></p>",
      "votes": 0,
      "replies": []
    },
    {
      "id": 843401,
      "author_name": "",
      "author_url": "",
      "post_date": "2020-05-12T03:06:24.947000",
      "content": "",
      "votes": 0,
      "replies": []
    }
  ],
  "raw_markdown_by_id": {
    "843366": "I have tried RGB + augmentation + binary classification. It can get LB 0.85~. Multiclass classification is useful. It can get LB 0.88~. Since the secret data is hidden in DCT, I also tried DCT. But it's more easily to become overfitting, because it's difficult to apply augmentation to DCT. \nAny idea?",
    "843382": "Hello There,\nDid you try YCbCr ? And can you tell how it works by contrast to RGB ?\nI would guess that YCbCr is more relevant since data is hidden is the DCT after RGB-&gt;YCbCr transformation\nAlso, I understand that using DCT coefficient only might hurt, but what if you use both (either in the same net, or using two different net and then merging) ?\nAnyway, thanks for the great job and very valuable comment",
    "845590": "A simple test of loading (100 images) time via kaggle kernel:\n| cv2 read | jpio read | jpio + imDecompressYCbCr|\n| --- | --- |\n| 750ms | 1.94s |20s |\n\n@remicogranne do you have any advices to optimize the processing time of YCbCr? 20s for 100 images is too slow : (",
    "942393": "One question: does DCT stand for discrete cosine transform (it seems to be but I would like to be sure)? If that's the case, you said that augmentation is hard to apply to DCT. Isn't it possible to apply the transformation first then move to the DCT space? Thanks! ",
    "844933": "i think the split DCT table can't easy let dnn to study. so i have try combine the different position of DCT table of the whole picture, but this method dont bing some prove. I plot the diff of same picture different steganaly . i find the DCT different just +-1 different. maybe dnn dont easy to study this little different. so I think we should transfer the color/shape space to another obvious different space.",
    "846550": "hey please checkout this kernel it might be helpful \nhttps://www.kaggle.com/pranshu29/more-image-processing-ideas-analysis",
    "843401": ""
  }
}