{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# How to recover rotating bounging boxes from given data. Lossless. <br>\nI'm trying to code as simple as possible.","metadata":{"_uuid":"c73927951492c76edb38310097007fe798874ee0"}},{"cell_type":"code","source":"import numpy as np \nimport pandas as pd \nfrom skimage.data import imread\nimport matplotlib.pyplot as plt\nimport matplotlib as mpl\nimport cv2","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-05-31T05:06:36.635899Z","iopub.execute_input":"2021-05-31T05:06:36.636393Z","iopub.status.idle":"2021-05-31T05:06:37.758859Z","shell.execute_reply.started":"2021-05-31T05:06:36.636351Z","shell.execute_reply":"2021-05-31T05:06:37.758084Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# set images to bigger size\nmpl.rcParams['figure.figsize'] = [8.0, 8.0]","metadata":{"_uuid":"dc40b0406dc67f72203b9fb56919e2efb5549440","execution":{"iopub.status.busy":"2021-05-31T05:06:37.762242Z","iopub.execute_input":"2021-05-31T05:06:37.762680Z","iopub.status.idle":"2021-05-31T05:06:37.766125Z","shell.execute_reply.started":"2021-05-31T05:06:37.762639Z","shell.execute_reply":"2021-05-31T05:06:37.764929Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ImageId = '002fdcf51.jpg'\nimg = imread('../input/train_v2/' + ImageId)\nmasks = pd.read_csv(\"../input/train_ship_segmentations_v2.csv\", index_col=\"ImageId\")","metadata":{"_uuid":"fe51d4c9a9a749dc8a71f92724236743942f33a4","execution":{"iopub.status.busy":"2021-05-31T05:06:37.767234Z","iopub.execute_input":"2021-05-31T05:06:37.767635Z","iopub.status.idle":"2021-05-31T05:06:39.421882Z","shell.execute_reply.started":"2021-05-31T05:06:37.767418Z","shell.execute_reply":"2021-05-31T05:06:39.421167Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## First, what image we have:","metadata":{"_uuid":"ff763bf481e80daba49621dc15502061724037e3"}},{"cell_type":"code","source":"plt.imshow(img)\nplt.show()","metadata":{"_uuid":"1e813b3a9a1b1709471f660e06cb6f30c4bee0d8","execution":{"iopub.status.busy":"2021-05-31T05:06:39.423039Z","iopub.execute_input":"2021-05-31T05:06:39.423257Z","iopub.status.idle":"2021-05-31T05:06:39.873335Z","shell.execute_reply.started":"2021-05-31T05:06:39.423225Z","shell.execute_reply":"2021-05-31T05:06:39.871857Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Get mask of image from RLE\nHow to turn RLE into image mask you probably know from other kernels. Nothing special here.","metadata":{"_uuid":"e5b43a8942eaa32ca168e0178bf8f72567775ecb"}},{"cell_type":"code","source":"def rle_decode(mask_rle, shape):\n    img = np.zeros(shape[0]*shape[1], dtype=np.uint8)\n    s = mask_rle.split()\n    starts, lengths = [np.asarray(x, dtype=int) for x in (s[0:][::2], s[1:][::2])]\n    starts -= 1\n    ends = starts + lengths\n    \n    for lo, hi in zip(starts, ends):\n        img[lo:hi] = 1\n    return img.reshape(shape).T","metadata":{"_uuid":"f71dd70f40d5c6dd2863c41fcb750f74e9da7f06","execution":{"iopub.status.busy":"2021-05-31T05:06:54.829166Z","iopub.execute_input":"2021-05-31T05:06:54.829658Z","iopub.status.idle":"2021-05-31T05:06:54.834315Z","shell.execute_reply.started":"2021-05-31T05:06:54.829443Z","shell.execute_reply":"2021-05-31T05:06:54.833739Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"rle_mask = masks.EncodedPixels[ImageId].tolist()[1] # this image has two ships, we'll use bigger one\nmask = rle_decode(rle_mask, (768, 768))\nplt.imshow(mask)\nplt.show()","metadata":{"_uuid":"0bebc2c1624bb398d1f80ee99868f365086749bd","execution":{"iopub.status.busy":"2021-05-31T05:06:56.696159Z","iopub.execute_input":"2021-05-31T05:06:56.696594Z","iopub.status.idle":"2021-05-31T05:06:57.031045Z","shell.execute_reply.started":"2021-05-31T05:06:56.696539Z","shell.execute_reply":"2021-05-31T05:06:57.029971Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Bounding box\nNow let's encode this ship into box with x, y, width, height:","metadata":{"_uuid":"1a479f7fc96aac0f90f78b15035683316f8895e1"}},{"cell_type":"code","source":"x, y, w, h = cv2.boundingRect(mask)\nrect1 = cv2.rectangle(img.copy(),(x,y),(x+w,y+h),(0,255,0),3) # not copying here will throw an error\nprint(\"x:{0}, y:{1}, width:{2}, height:{3}\".format(x, y, w, h))\nplt.imshow(rect1)\nplt.show()","metadata":{"_uuid":"ca1108fd9aeaea53afdb7fd3b725cc19f44f7421","execution":{"iopub.status.busy":"2021-05-31T05:07:00.580013Z","iopub.execute_input":"2021-05-31T05:07:00.580458Z","iopub.status.idle":"2021-05-31T05:07:01.080439Z","shell.execute_reply.started":"2021-05-31T05:07:00.580418Z","shell.execute_reply":"2021-05-31T05:07:01.079638Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Rotating Bounding Box\nAnd finally","metadata":{"_uuid":"e180327502a88177bec55b5141684f7935cfaabc"}},{"cell_type":"code","source":"_,contours,_ = cv2.findContours(mask.copy(), 1, 1) # not copying here will throw an error\nrect = cv2.minAreaRect(contours[0]) # basically you can feed this rect into your classifier\n(x,y),(w,h), a = rect # a - angle\n##ROI = mask[y:y+h, x:x+w]","metadata":{"_uuid":"580e5b715b5cb59fd4b768bf387fa788d9eb6160","execution":{"iopub.status.busy":"2021-05-31T05:07:04.363165Z","iopub.execute_input":"2021-05-31T05:07:04.363476Z","iopub.status.idle":"2021-05-31T05:07:04.383171Z","shell.execute_reply.started":"2021-05-31T05:07:04.363421Z","shell.execute_reply":"2021-05-31T05:07:04.382305Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Draw it","metadata":{"_uuid":"fff8fae979cb35964b67ca687c8e0092a826cb3d"}},{"cell_type":"code","source":"box = cv2.boxPoints(rect)\nbox = np.int0(box) #turn into ints\nrect2 = cv2.drawContours(img.copy(),[box],0,(255,255,255),thickness=cv2.FILLED)\n\nplt.imshow(rect2)\nplt.show()","metadata":{"_uuid":"4d8ff20fc701ef6e160c21cc8bd04fd9df83c14e","execution":{"iopub.status.busy":"2021-05-31T05:08:52.838095Z","iopub.execute_input":"2021-05-31T05:08:52.838604Z","iopub.status.idle":"2021-05-31T05:08:53.315559Z","shell.execute_reply.started":"2021-05-31T05:08:52.838559Z","shell.execute_reply":"2021-05-31T05:08:53.314645Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"width = int(rect[1][0])\nheight = int(rect[1][1])\nsrc_pts = box.astype(\"float32\")\n    # coordinate of the points in box points after the rectangle has been\n    # straightened\ndst_pts = np.array([[0, height-1],[0, 0],[width-1, 0],[width-1, height-1]], dtype=\"float32\")\n\n    # the perspective transformation matrix\nM = cv2.getPerspectiveTransform(src_pts, dst_pts)\n\n    # directly warp the rotated rectangle to get the straightened rectangle\nwarped = cv2.warpPerspective(img, M, (width, height))","metadata":{"execution":{"iopub.status.busy":"2021-05-31T05:08:58.411087Z","iopub.execute_input":"2021-05-31T05:08:58.411367Z","iopub.status.idle":"2021-05-31T05:08:58.417856Z","shell.execute_reply.started":"2021-05-31T05:08:58.411314Z","shell.execute_reply":"2021-05-31T05:08:58.416774Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nplt.imshow(warped)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-05-31T05:09:00.423084Z","iopub.execute_input":"2021-05-31T05:09:00.423391Z","iopub.status.idle":"2021-05-31T05:09:00.629071Z","shell.execute_reply.started":"2021-05-31T05:09:00.423333Z","shell.execute_reply":"2021-05-31T05:09:00.628029Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ImageId = '002fdcf51.jpg'\nimg = imread('../input/train_v2/' + ImageId)\n","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Voila !","metadata":{"_uuid":"31d3c2153e326820a9e3e71296bf7b6848c35891"}}]}