{
  "id": 289037,
  "title": "Which bbox is right?",
  "url": "/competitions/sartorius-cell-instance-segmentation/discussion/289037",
  "author_name": "",
  "post_date": "2021-11-19T03:59:51.583068500Z",
  "votes": 1,
  "comment_count": 1,
  "views": 0,
  "content": "<p>When I was making a coco format data set, I found that the function I defined was different from the result obtained by pycocotools. They differ by only one pixel. Which one is right? Why they are different？</p>\n<p>First define two functions：</p>\n<pre><code>from pycocotools import mask as mutils\n\ndef rle_decode(mask_rle, shape, color=1):\n    s = mask_rle.split()\n\n    starts = list(map(lambda x: int(x) - 1, s[0::2]))\n    lengths = list(map(int, s[1::2]))\n    ends = [x + y for x, y in zip(starts, lengths)]\n    if len(shape)==3:\n        img = np.zeros((shape[0] * shape[1], shape[2]), dtype=np.float32)\n    else:\n        img = np.zeros(shape[0] * shape[1], dtype=np.float32)\n    for start, end in zip(starts, ends):\n        img[start : end] = color\n\n    return img.reshape(shape)\n\ndef coco_rle_encode(mask):\n    rle = {'counts': [], 'size': list(mask.shape)}\n    counts = []\n    for i, (value, elements) in enumerate(groupby(mask.ravel(order='F'))):\n        if i == 0 and value == 1:\n            counts.append(0)\n        counts.append(len(list(elements)))\n    rle['counts'] = counts\n    return rle\n\ndef get_box(a_mask):\n        pos = np.where(a_mask)\n        xmin = np.min(pos[1])\n        xmax = np.max(pos[1])\n        ymin = np.min(pos[0])\n        ymax = np.max(pos[0])\n        return [xmin, ymin, xmax, ymax]\n</code></pre>\n<p>Then I pass in a piece of rle data.</p>\n<pre><code>for rle in list(df_temp.annotation.values)[0]:\n        print(rle)\n        mask = rle_decode(rle, img.shape[:2])\n        bbox = get_box(mask)\n        print(bbox)\n        rles = coco_rle_encode(mask)\n        rles = mutils.frPyObjects(rles, height, width) \n        bboxes = mutils.toBbox(rles)\n        area = mutils.area(rles)\n        bboxes[2] += bboxes[0]\n        bboxes[3] += bboxes[1]\n        print(bboxes)\n</code></pre>\n<p>The output result is as follows：</p>\n<pre><code>185738 7 186439 12 187141 15 187844 17 188547 18 189251 19 189954 20 190659 19 191364 18 192068 18 192773 17 193478 16 194184 15 194890 12 195596 8 196302 3\n\n[577, 263, 597, 278]\n[577. 263. 598. 279.]\n</code></pre>",
  "messages": [
    {
      "id": "1587898",
      "postDate": "11/19/2021 03:59:51",
      "content": "<p>When I was making a coco format data set, I found that the function I defined was different from the result obtained by pycocotools. They differ by only one pixel. Which one is right? Why they are different？</p>\n<p>First define two functions：</p>\n<pre><code>from pycocotools import mask as mutils\n\ndef rle_decode(mask_rle, shape, color=1):\n    s = mask_rle.split()\n\n    starts = list(map(lambda x: int(x) - 1, s[0::2]))\n    lengths = list(map(int, s[1::2]))\n    ends = [x + y for x, y in zip(starts, lengths)]\n    if len(shape)==3:\n        img = np.zeros((shape[0] * shape[1], shape[2]), dtype=np.float32)\n    else:\n        img = np.zeros(shape[0] * shape[1], dtype=np.float32)\n    for start, end in zip(starts, ends):\n        img[start : end] = color\n\n    return img.reshape(shape)\n\ndef coco_rle_encode(mask):\n    rle = {'counts': [], 'size': list(mask.shape)}\n    counts = []\n    for i, (value, elements) in enumerate(groupby(mask.ravel(order='F'))):\n        if i == 0 and value == 1:\n            counts.append(0)\n        counts.append(len(list(elements)))\n    rle['counts'] = counts\n    return rle\n\ndef get_box(a_mask):\n        pos = np.where(a_mask)\n        xmin = np.min(pos[1])\n        xmax = np.max(pos[1])\n        ymin = np.min(pos[0])\n        ymax = np.max(pos[0])\n        return [xmin, ymin, xmax, ymax]\n</code></pre>\n<p>Then I pass in a piece of rle data.</p>\n<pre><code>for rle in list(df_temp.annotation.values)[0]:\n        print(rle)\n        mask = rle_decode(rle, img.shape[:2])\n        bbox = get_box(mask)\n        print(bbox)\n        rles = coco_rle_encode(mask)\n        rles = mutils.frPyObjects(rles, height, width) \n        bboxes = mutils.toBbox(rles)\n        area = mutils.area(rles)\n        bboxes[2] += bboxes[0]\n        bboxes[3] += bboxes[1]\n        print(bboxes)\n</code></pre>\n<p>The output result is as follows：</p>\n<pre><code>185738 7 186439 12 187141 15 187844 17 188547 18 189251 19 189954 20 190659 19 191364 18 192068 18 192773 17 193478 16 194184 15 194890 12 195596 8 196302 3\n\n[577, 263, 597, 278]\n[577. 263. 598. 279.]\n</code></pre>",
      "rawMarkdown": "When I was making a coco format data set, I found that the function I defined was different from the result obtained by pycocotools. They differ by only one pixel. Which one is right? Why they are different？\n\nFirst define two functions：\n```\n\nfrom pycocotools import mask as mutils\n\ndef rle_decode(mask_rle, shape, color=1):\n    s = mask_rle.split()\n\n    starts = list(map(lambda x: int(x) - 1, s[0::2]))\n    lengths = list(map(int, s[1::2]))\n    ends = [x + y for x, y in zip(starts, lengths)]\n    if len(shape)==3:\n        img = np.zeros((shape[0] * shape[1], shape[2]), dtype=np.float32)\n    else:\n        img = np.zeros(shape[0] * shape[1], dtype=np.float32)\n    for start, end in zip(starts, ends):\n        img[start : end] = color\n\n    return img.reshape(shape)\n\ndef coco_rle_encode(mask):\n    rle = {'counts': [], 'size': list(mask.shape)}\n    counts = []\n    for i, (value, elements) in enumerate(groupby(mask.ravel(order='F'))):\n        if i == 0 and value == 1:\n            counts.append(0)\n        counts.append(len(list(elements)))\n    rle['counts'] = counts\n    return rle\n\ndef get_box(a_mask):\n        pos = np.where(a_mask)\n        xmin = np.min(pos[1])\n        xmax = np.max(pos[1])\n        ymin = np.min(pos[0])\n        ymax = np.max(pos[0])\n        return [xmin, ymin, xmax, ymax]\n\n```\n\nThen I pass in a piece of rle data.\n\n```\n\nfor rle in list(df_temp.annotation.values)[0]:\n        print(rle)\n        mask = rle_decode(rle, img.shape[:2])\n        bbox = get_box(mask)\n        print(bbox)\n        rles = coco_rle_encode(mask)\n        rles = mutils.frPyObjects(rles, height, width) \n        bboxes = mutils.toBbox(rles)\n        area = mutils.area(rles)\n        bboxes[2] += bboxes[0]\n        bboxes[3] += bboxes[1]\n        print(bboxes)\n\n```\n\nThe output result is as follows：\n```\n185738 7 186439 12 187141 15 187844 17 188547 18 189251 19 189954 20 190659 19 191364 18 192068 18 192773 17 193478 16 194184 15 194890 12 195596 8 196302 3\n\n[577, 263, 597, 278]\n[577. 263. 598. 279.]\n\n```",
      "votes": null
    },
    {
      "id": "1589652",
      "postDate": "11/20/2021 13:23:24",
      "content": "<blockquote>\n<pre><code> bboxes[2] += bboxes[0]\n    bboxes[3] += bboxes[1]\n</code></pre>\n</blockquote>\n<p>问题出在这行代码👀<br>\nx+w, y+h多算了个1，如果想特别精确，减1就可以了。实际上不管也无所谓，毕竟不是数值很大🎶👀</p>",
      "rawMarkdown": ">      bboxes[2] += bboxes[0]\n        bboxes[3] += bboxes[1]\n\n问题出在这行代码👀\nx+w, y+h多算了个1，如果想特别精确，减1就可以了。实际上不管也无所谓，毕竟不是数值很大🎶👀",
      "votes": null
    }
  ],
  "comments": [
    {
      "id": 1589652,
      "author_name": "blueboy97",
      "author_url": "",
      "post_date": "11/20/2021 13:23:24",
      "content": "<blockquote>\n<pre><code> bboxes[2] += bboxes[0]\n    bboxes[3] += bboxes[1]\n</code></pre>\n</blockquote>\n<p>问题出在这行代码👀<br>\nx+w, y+h多算了个1，如果想特别精确，减1就可以了。实际上不管也无所谓，毕竟不是数值很大🎶👀</p>",
      "votes": null,
      "replies": []
    }
  ],
  "raw_markdown_by_id": {
    "1587898": "When I was making a coco format data set, I found that the function I defined was different from the result obtained by pycocotools. They differ by only one pixel. Which one is right? Why they are different？\n\nFirst define two functions：\n```\n\nfrom pycocotools import mask as mutils\n\ndef rle_decode(mask_rle, shape, color=1):\n    s = mask_rle.split()\n\n    starts = list(map(lambda x: int(x) - 1, s[0::2]))\n    lengths = list(map(int, s[1::2]))\n    ends = [x + y for x, y in zip(starts, lengths)]\n    if len(shape)==3:\n        img = np.zeros((shape[0] * shape[1], shape[2]), dtype=np.float32)\n    else:\n        img = np.zeros(shape[0] * shape[1], dtype=np.float32)\n    for start, end in zip(starts, ends):\n        img[start : end] = color\n\n    return img.reshape(shape)\n\ndef coco_rle_encode(mask):\n    rle = {'counts': [], 'size': list(mask.shape)}\n    counts = []\n    for i, (value, elements) in enumerate(groupby(mask.ravel(order='F'))):\n        if i == 0 and value == 1:\n            counts.append(0)\n        counts.append(len(list(elements)))\n    rle['counts'] = counts\n    return rle\n\ndef get_box(a_mask):\n        pos = np.where(a_mask)\n        xmin = np.min(pos[1])\n        xmax = np.max(pos[1])\n        ymin = np.min(pos[0])\n        ymax = np.max(pos[0])\n        return [xmin, ymin, xmax, ymax]\n\n```\n\nThen I pass in a piece of rle data.\n\n```\n\nfor rle in list(df_temp.annotation.values)[0]:\n        print(rle)\n        mask = rle_decode(rle, img.shape[:2])\n        bbox = get_box(mask)\n        print(bbox)\n        rles = coco_rle_encode(mask)\n        rles = mutils.frPyObjects(rles, height, width) \n        bboxes = mutils.toBbox(rles)\n        area = mutils.area(rles)\n        bboxes[2] += bboxes[0]\n        bboxes[3] += bboxes[1]\n        print(bboxes)\n\n```\n\nThe output result is as follows：\n```\n185738 7 186439 12 187141 15 187844 17 188547 18 189251 19 189954 20 190659 19 191364 18 192068 18 192773 17 193478 16 194184 15 194890 12 195596 8 196302 3\n\n[577, 263, 597, 278]\n[577. 263. 598. 279.]\n\n```",
    "1589652": ">      bboxes[2] += bboxes[0]\n        bboxes[3] += bboxes[1]\n\n问题出在这行代码👀\nx+w, y+h多算了个1，如果想特别精确，减1就可以了。实际上不管也无所谓，毕竟不是数值很大🎶👀"
  },
  "source": "meta"
}