{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Can your predicted positions really stand?\n\n* Predicted positions is not always able to stand\n* This notebook show a simple way to analyze positions and how to correct them\n\n## Reference and acknowledgement\n* Notebooks\n * https://www.kaggle.com/devinanzelmo/wifi-features\n* Datasets\n * https://www.kaggle.com/hiro5299834/indoor-navigation-and-location-wifi-features"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# load libraries\nimport os\nimport cv2\nimport json\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"floor_map = {\"B2\":-2, \"B1\":-1, \"F1\":0, \"F2\":1, \"F3\":2, \"F4\":3, \"F5\":4, \"F6\":5, \"F7\":6, \"F8\":7, \"F9\":8,\n             \"1F\":0, \"2F\":1, \"3F\":2, \"4F\":3, \"5F\":4, \"6F\":5, \"7F\":6, \"8F\":7, \"9F\":8}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# First, load submission.csv\n# change submission_csv path into yours\nsubmission_csv = \"../input/indoor-location-navigation-sample-submission/sample_submission.csv\"\nsubmission_df = pd.read_csv(submission_csv)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# list buildings\nsite_df = submission_df[\"site_path_timestamp\"].str.split(\"_\", expand=True)\nsite_df[0].unique()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# sample\nsite = \"5da1383b4db8ce0c98bc11ab\"\nfloor = \"F3\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# extract a given building from submission.csv\nsubmission_df_ext = submission_df[site_df[0] == site]\nsubmission_df_ext = submission_df_ext[submission_df_ext[\"floor\"] == floor_map[floor]]\n\n# load train positions\ntrain_csv = \"../input/indoor-navigation-and-location-wifi-features/%s_train.csv\" % (site)\ntrain_df = pd.read_csv(train_csv)\ntrain_df_ext = train_df[train_df[\"f\"] == floor_map[floor]]\n\n# load building infomation\nfloor_image = \"../input/indoor-location-navigation/metadata/%s/%s/floor_image.png\" % (site, floor)\njson_path = \"../input/indoor-location-navigation/metadata/%s/%s/floor_info.json\" % (site, floor)\nwith open(json_path, \"r\") as f:\n    train_floor_info = json.load(f)\n\n# load image\nimg_bgr = cv2.imread(floor_image)\nimg_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)\nimg_height, img_width, _ = img_bgr.shape\n\n# caliculate positions\nsubmission_x = submission_df_ext[\"x\"].values * img_width / train_floor_info[\"map_info\"][\"width\"]\nsubmission_y = img_height - submission_df_ext[\"y\"].values * img_height / train_floor_info[\"map_info\"][\"height\"]\ntrain_x = train_df_ext[\"x\"].values * img_width / train_floor_info[\"map_info\"][\"width\"]\ntrain_y = img_height - train_df_ext[\"y\"].values * img_height / train_floor_info[\"map_info\"][\"height\"]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# plot positions\nfig = plt.figure(figsize=(15, 15))\nplt.imshow(img_rgb, alpha=1)\nplt.scatter(train_x, train_y, marker=\"o\", color=\"blue\", label=\"train\")\nplt.scatter(submission_x, submission_y, marker=\"o\", color=\"red\", label=\"predicted\")\nplt.legend(fontsize=16)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Discussion\n\n* Every position in train data is located black areas where people seem to be able to stand\n* However some predicted positions are located light blue areas where people seem not to be able to stand\n* We have to correct forbidden positions in some way\n* In this notebook, I simply correct them into nearest permitted position in a black area"},{"metadata":{"trusted":true},"cell_type":"code","source":"# find contours\nimg_gray = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2GRAY)\nimg_th = cv2.threshold(img_gray, 1, 255, cv2.THRESH_BINARY)[1]\ncontours, hierarchy = cv2.findContours(img_th, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)\ncontour_arr = np.vstack(contours)\ncoords = np.round(np.vstack([submission_x, submission_y]).T).astype(np.int32)\n\n# correct forbidden positions into nearest permitted positions\ncoords_list = [contour_arr[np.argmin(np.linalg.norm(contour_arr - coord, axis=2))] if img_gray[coord[1], coord[0]] != 0 else coord for coord in coords]\nnew_coords = np.vstack(coords_list)\nnew_x, new_y = np.vsplit(new_coords.T, 2)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# plot positions\nfig = plt.figure(figsize=(15, 15))\nplt.imshow(img_rgb, alpha=1)\nplt.scatter(train_x, train_y, marker=\"o\", color=\"blue\", label=\"train\")\nplt.scatter(submission_x, submission_y, marker=\"o\", color=\"red\", label=\"predicted\")\nplt.scatter(new_x, new_y, marker=\"o\", color=\"orange\", label=\"corrected\")\nplt.legend(fontsize=16)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":4}