{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":67836,"databundleVersionId":7527339,"sourceType":"competition"},{"sourceId":7472080,"sourceType":"datasetVersion","datasetId":4348994}],"dockerImageVersionId":30636,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!pip install ultralytics -q","metadata":{"execution":{"iopub.status.busy":"2024-01-27T15:54:34.632175Z","iopub.execute_input":"2024-01-27T15:54:34.632926Z","iopub.status.idle":"2024-01-27T15:54:51.097154Z","shell.execute_reply.started":"2024-01-27T15:54:34.632885Z","shell.execute_reply":"2024-01-27T15:54:51.095950Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"![differencee](https://www.freecodecamp.org/news/content/images/2023/04/compvision_tasks.png)","metadata":{}},{"cell_type":"code","source":"from ultralytics import YOLO","metadata":{"execution":{"iopub.status.busy":"2024-01-27T15:54:56.714520Z","iopub.execute_input":"2024-01-27T15:54:56.715333Z","iopub.status.idle":"2024-01-27T15:55:01.176404Z","shell.execute_reply.started":"2024-01-27T15:54:56.715298Z","shell.execute_reply":"2024-01-27T15:55:01.175470Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"![image.png](attachment:1880c471-0352-47c1-87db-71afbe45b412.png)","metadata":{},"attachments":{"1880c471-0352-47c1-87db-71afbe45b412.png":{"image/png":"iVBORw0KGgoAAAANSUhEUgAAAdEAAAElCAYAAAC7wNiUAAABW2lDQ1BJQ0MgUHJvZmlsZQAAKJFjYGBiSSwoyGFhYGDIzSspCnJ3UoiIjFJgf8HAyCDBIMbAzcCXmFxc4BgQ4ANUwgCjUcG3a0DVQHBZF2RWWHDQqT9P3zfFBEgv0MrW7MNUjwK4UlKLk4H0HyDWSi4oKmFgYNQAsgPKSwpA7AogW6QI6CgguwfEToewF4DYSRD2FrCakCBnIPsEkC2QnJGYAmTfALJ1kpDE05HYuTmlyVA3gFzPk5oXGgyk+YBYhsGDIYBBgcEICNMYyoFhg12tCVitM0M+QwFDJUMRQyZDOkMGQwlQpyNQpIAhhyEVyPZkyGNIZtBj0AGbaADEJqAwRg87hFiqNAOD8QqgVZwIsSw5Bobd6xgYBKcjxNTnAr2xioHhQE9BYlEiPEQZv7EUpxkbQdg8UgwMrAf+///0n4GBPYGB4e+5//9/z/j//+80BgbmLwwM+/0AmexhhnJ4TjsAAABWZVhJZk1NACoAAAAIAAGHaQAEAAAAAQAAABoAAAAAAAOShgAHAAAAEgAAAESgAgAEAAAAAQAAAdGgAwAEAAAAAQAAASUAAAAAQVNDSUkAAABTY3JlZW5zaG90gqMI/gAAAdZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDYuMC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iPgogICAgICAgICA8ZXhpZjpQaXhlbFlEaW1lbnNpb24+MjkzPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxYRGltZW5zaW9uPjQ2NTwvZXhpZjpQaXhlbFhEaW1lbnNpb24+CiAgICAgICAgIDxleGlmOlVzZXJDb21tZW50PlNjcmVlbnNob3Q8L2V4aWY6VXNlckNvbW1lbnQ+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgp3bHLWAABAAElEQVR4AexdBbxVRRMfFFspEQTpEOlUukS6O6RDKUEkpENEQEBClBABBeRDMCgJpUEQkRKQEkQQUDEppc43/3nuuefed+vdV/fxZn6/+845W2f3P7s7s7Oz5yWxmI4dO0lKioAioAgoAoqAIhA8AjlzZqWkJjkelBQBgwAUK+0TBo3wvSqfwpc34Vgz7S8xxxWz+Lwj5orUkhQBRUARUAQUgcSFgArRxMVvba0ioAgoAopADCKgQjQGwdSiFAFFQBFQBBIXAipEExe/tbWKgCKgCCgCMYiAS4haAUoNFB8gu0YrAoqAIqAIKAJhiUAg+eYn3iVEkwRoWqD4ANk1WhFQBBQBRUARCEsEAsk3P/EuIRqWLdNKKQKKgCKgCCgC4YuACtHw5Y3WTBFQBBQBRSDMEVAhGuYM0uopAoqAIqAIhC8CKkTDlzdaM0VAEVAEFIEwR0CFaJgzSKunCCgCioAiEL4IqBANX95ozRQBRUARUATCHAGXEPVzDkbaECg+zBuq1VMEFAFFQBFQBLwiEEi++Yl3CVE/52DkpYHivdZMAxUBRUARUAQUgTBHIJB88xPvEqJh3katniKgCCgCioAiEG4IxJgQvXnzFh0+fIz+/PMvr21csGAJjR//Fn25/Wuv8bEZOGjwa1S8RFXauu0r+zX8v8hp+Yo1UqcRI8bRr7/+RocOHaFSpWvQ88/3ttPF9s3iJcuo2JPP0LTpc2P7VVp+CAgkBv5cvnyFDhz4jn755UIICGkWg0B8zB/m3eF09Tbfhlq/q1f/kTkasuPnn38JtZhYzWf/U+5Q3wLBNHXqLPrmm32EwQjKmPExGjz4Japdq6pd7MKFH9PuPfspSZIkVKrkk3Z4XNzsYMF9+vRPdPTIcSpTuri88pVXxtOMme/J/T333EPNmtWnH344zb8f6dKlSwSl4M47Y0zHoAsXfqcvvtgk72vQoCbdfffdcr9v30E6e/Y847dXnhP6n//97xN6qfcQt2akTZuGnnqyMBUvXoRat25GSZPe6RYfzMOiDz8l65ZFZcoUpwwZ0geTJUppEgt/nKCg37Vr30MEKJRKUMqUKWj8uBFUvXolZ9Lb7h4Cb//+Q5QiRTKqVi3qbfXWH2Nz/ohvBkDRR3/p/3JP6tGjk12dAQNG0nvvL6JUqVLSF59/RI8+moa8zbd2hijeXL16ld6YOE1yVa5cgTCXhBtFS4h+++0hnhS70j///OvWLgisbt360R1J7qCaNSu7xcXHw6xZk2QV2rRJPfv1mzZ/KfctWzamUaMG0V1Jk1KOHNlo4sRXKV/eJ2JUgOJFJ0+esoVL1aoVbSHar293yp4tM9VyKBx2JW+TG2iQWPXjh4E4eHDUV/p9+w6jGzdu0jszJ8aKEE1s/Pnjjz+pTt2Wwg90s3vvvUfGMcKfe74XvTf3LXr66bK3SQ+M3IzPWaEdO3YKPfFEzpCEqLf+WLXq07E2f0RuQfyHrFz5uQhQLIymTH5NBChq5W2+jf/axl4NorXUGjlyggw8rNigoez6+gtavHg2Zc6cQSa8Pv9NfLFX/eBKzpo1M7Vq2cQWXMh15sxZyfxMpXIiQPGAdkDQ5mUhGleULNlD1K5dC3rkkYfj6pVx8h6sNufMniJCr0OHZyltmkfkvTBbYwJLKHS78mfz5u0iQO+66y5aMH86fX98F+38ai3lyZNLrDCLFn2aUFgUNvWMj/kjvhqPhVLvPkPl9V26tHNTuLzNt/FVz7h4b8hCFPsnZo+xW7cOssRPn/5RKl3qKRmUd9xxB/3119+0zbEP6dkgMKJzlz5UslQ11ghLiGYMc6CTDh48TK1adaXChStSgYLlqFnzTvTVV984k9DSpauoXv3W9ETuklIWyjx37mc7TYeOPalK1cb0yScradOmL+X+ypWrEj98+Ovy/Ntvf9DGjdvkvkHDtnZe3MyZu5BaPPs85c5Tip6uVJ8GDRpFJj/iYbfHvmoljsv5+FNU6ZkG9OqoN+j6jRuIFrPxi70Gyz3+NGrUTsxouJ8y5R15J+ph6Pr16zThjbepfoM20qYmTTrQW2+9S7du3TJJqG27FyTfsmWrxZxeukxNyl+grKx2jVndThwPN0koCUEzhyVi5CsDaOXKhZQmTWqC2RD7G07avn0XdWXLRaHCFQTfwUNGi/kbaRAH3mEVChr56nh5Br9A165do3HjplLt2s9S3nxlqE3b7gRMPMkfD2HWT2z8MWOoQIE8VLFiGdlmgZl87Nih1LRpfXo0nbvZDOPy2ZadZQxgrE2eMlOErRNn+D00adqRiharRL24v2N1D97hd+LED5LU2W8nTZ4hvgqFizwtY8T0jSJFn5Yyhg4b49bnUUCgejjLxzaTt3GBvjZ3zkKpz8mTP0r9UBdDME/WqtVC5qRSpapTl659xWcC8f76o6/548PFS6lNm27SP6tWa0LDho+l33+P6L8oE+ZKYPTqqxNEwaxZsznl4vkQWGJ7KdwI81rXrv3o778vUrFihWQB5ayjc75FeFTahz7UuHH7iD700hCfPjbO98X3vcuciy0RP2685BH/7YFDdt27du1g3+MmW7YsNGniKPr9jz/owQcfcIszD3BAqly5If198RIlT56M7rvvPtq1a6/8MJiaN28gA68WT47//vuvMOsW71Nu2bKDvvxyJwvE96lokYIEx4+ePQfKarJsuZJ04vsfZBJFmq92rOVy76WjR7+n7zkc+17Yi8SANgLpLAvbpL9eoBs3b4jQh4NFsoceNNWkiZOmyySNAOwXHeF9VThQfbN7H61c8T9ZvTZv8Rzt3LmbsLf66KOP0HffHZUfzJhvThlDmPBhxjT0w6nTlISVDNBPP52TPanHHksnz6hX9+79xfSJAOw1QFnBD0rHmDER2h/2d1HO29Nmy94OlBbkxSRToEBeatummZQXLn+gYPXt05369htOhxkfCD/wAji2bNVZFBFYMKCczZ69gL7+eg99tGQOXbl6xZ6A0Zbz538VPt68eVPaC6xWrFwr2GfJkpHWrdsse8/Xr9+ghg1rSfMD8TAx8idN2gjLwIEDhwn7e3XrVBeTLsYUfk56990FNGToaEIfy5kzG2EfH/0d1pxxrw+XpOh34C0I5j2UeeTocenbCDNbPqbfTp8xV/qtGYdQQvfs3k/Llq+RMQWfhFmz5tPDD6einj2eQxEUTD1M+f7GBcacEWLoh5gP4FgIev31NwkCFW3NlCkDt/EnGWe7uW5fblvltz9i0eA5f6AvQykEpUiRXOKxDQb8Fn84W+ZHMwdgnoOy9++/16Rvb926g0aPnkwzZkyQ/OHyB2ZwjFu0Z/q08ZF8HJzzLeocbPs+/niF3YeQb9GiT+gYz91xQh7yLdI7/cS7VqL+BChK9IjHpjwIG71OoSOB/KdRo9r0XKfWVLSo+4A08Yd4In2aTanPP9eGDny7lfbs2UCNG9WR6JWffS7X1Ws2iAB96qkitGzpfFqx4gPW1gaKpvwzT6agZUsjVh1YDc+fN402b14hZWIV9OOPZySN8w9WRsePfU0PPHC/BL/55mh5NuZGZ1owH6sc0IjhL3M9t8hAQnvR/u3bd8qEDgGB9n61Yw1t/3I1vTFhpORZw/XHCmrggBfpw0WzJAx/YPbGJrw3WsH7DNg7hGloCQsRvHPWO5Mk6fvzPqRtrBw4CcrIju1r6Oudn7PjTlGJWrNmvTNJ2Nxj1QOCJnvo0FG5f4m1TazkX+z5vGCHfoB2YKKZ9e58qvR0OeGPcUZ6a+pYecaqFlhBgMIUvv3LVbRh/ac07/23ZbXbt98weU8wPEyM/KlXt7ooaJi4sWqEFad2nWfF4mG2OsAgKDVYOUEwfrBghmC8betKFm4pCasGCAMovcM5Dah8+VK0d89G2v3NerftE4l0/AHPkQ5jwYy9zawgb9ywlB0Ad9rOh5v/810Iph6O4mUF42tcLP10HltsukryXLlySH8axfMK6C9eXdWrV4OW8LbUl9s+o82blotAhQK7/9uDfvujFOD4gzoPGTpGQrDddfDAVrbMfSaLBigi03lrw0lwTJoz+01WMrdT+/bPStSGjVsJlqlwoSUfLaNp0+ZIdZqxxQJzX7AUqH3oZ6AihQvwQmkVoZ9hcRMn5CHfIr3TT7xLiEbK5T/AmNPg3RYKwUP37bdep6FD+4imsmfvt3Tx0mUpygi/VLzyA+3Z8y0P0tdp/fotvLqoLdpvjRrPSFzKVMnlCu9fmG/2sAfwwIEvShoMkOgQOjroIRaanTq1kokEqyWsgv+38B3WVDNS6tSppB1TJo+WeEz+V//5R/Jd4vbAUSMqtJu9nEFly5a0JxK0NV++3BIObd1JjRrW4Xo8RunSpSV4/YIwsYUjQXM1BFMQrBDHjp2QoHTp09LatRt4kt4iGi4CPdtq8pqrwQoT/P79ByW/mXCw8vmOBXUwPDTlBXM170zo/MmSJZMIijq1q8oqHisyeNiPem2imEBXr14ncOzlcYnVIgTlP9yvwSOstq5fi5jY4XF/ipVV8BI0aGAvUWrgpQnlxBc1qF9Txg4m4SfZcxsEz/nHH88u1qNKz5SXMFgeQMHUQxL+9yfUcQFhinkJ4w0WpfPnf5H2o9jTP/7kfEXAe9QZuMFpq3v3DjI/ZMmcUfwukBnYOQkLjnJsTYP1rl3b5hKFOeTgwSPOZPF6f/z4SWkTKvHJp5+J9S7YCvlrHxQOI1OGDetLwAl7q0OG9Am2+HhL5zLnRrEK8GAFYU8hlOMgGLQw4XzM+5Qwg3gjmOM2sia2fMVamvnO+/KDI0Q1XmWOGzec4PQxoP+LrOEdpu/YxPra6IgVGybrNq2bUr9+L0jH9VZ2MGFHj0WYEjL8Z2o1eXLnfpxyR8g0CcIK8c033xFlwKQJ9Yp2gDKzKclJEJSYvEy8icOKwFCaR1LLrdk/NOHhcoUZ3FC+fE/QEcfzyy+/YqLsq2db7Yj/bkw8BiD2wjzpu8NH7b3xQDz0zOvr2bzzduAPPFOnT5/AR7oui/K5evV6+ohNalBwsEd8qEpFt/7mDePD3x2j/PkjLAzAzGxL4N7fUSTnNk/SuyKmoXvvuwfZhO7mce4kgzvCfNXDmT7UcYFthP58bAPbNsbU7Cw3KvemzjjyB/OwIYxl0HeMnZOcdX6ELS2GsHURToSFz5gxU+TcJs6ETn0zYrUdqI7+2of9c0PZs2cxt3xiIqt9H643IQtRY5qDMPxq5zf2qgkNhVBt0LCNaBYw08HU6UnjJ7wt9n9oGyNGvMzHPLKIZoM9BEMQmBjk/XnvD5v22CP4fO1GMXfef/994k6OFdi6dZ+IjX77l1/LxjwGAhwfsvLRkSaN65rionzNxJ0f9DNP0p4EDRMER6X+/V8RbX748H5UkPcjf/75V3GY8swTzDNWulu2RH4nBAXIc/IOpsxwSQPNFYTVB/Z6zaoRYcuXL+BtgYdwa5Mx4doBHjdmMoJjzPBh/TxisdXwiH021x8PsZINlm4X/mDf6gab1TF+sNePlTV+MKXDMQ+C9MyZc2TGAPb7165ZHAmmZMkeZEXVJSAO8vlLcxYbToExRcHUI7rvusir6Ubs1IJ+CY/5qqxEYOKvXKVRSEWbsYr5wEm/sA8GCH0poREsF52fb0s32OcAixbsY9ao/gwZy2Co7UmXzmUWxuof8wPo/LlfQi0yzvK5en8UX5mTzS5G08SeCvaeQBAu48dPFccQeJaVLRvxcQPP4uFEBMIeJQQdlvoX/utcJu0X7CSCjfYzvB8BRxnsDbZtF2HmwB4FCPsySJM8WTI2mXQk7HeYIyomjSkvqlc46IDghAAhDsIAgzfxYxnyywrZtAMrc+wBYxL6w8tXm8zHFVCGc88Jz04qVDCfPH7JjkTGGQlasdmDLlgwok7OPOF8j/4AsxgcUz79T4hizwmE/XRzeBpmIjit4IcJHObEvXsP2E0z+J35KeJoEiIMVsATfRF5oZRhHwn5scIKhocoy5SP+8TAnzHsHPIMO/b16DHQTZk5xQorCII1Q4Z0VKhQRH/Eqgz79IZH4CkwPnXqjHhdwzwM6t9/pCiyq1atI6xSYoqCqUdU3mX4DS9+Y7nZz1sxGN84Mw5TNEyrUOS9kcnv7I+e6Uyd0Z9hBgdhL3j58rVyn9DGMiqdJ0+EBbJLl/Z233i5/wjbFCsNC+FPxozpbSfUt3nPFf0Ni7G3354dQmlxmyXklSg6Ghx5cGAbwurJpypTbjYP/XrhN/t4gpwP9PGFifz5c9OOHbtozpwPRACjM8MDzkkQIjhOgg6L85spUiZnZ5vlkqQKf7AAtIVXpzjSgMkY5t+Lf19iU8wxMeNWqVxB0oT6B2aFOnWqSfntO/SgEiWKESZ7TLLYC0X599wdMcjgrYYPT9x7770yiXu+E3ssqCM8dhvyERccZIdnmyfVYk1vNmOCL6pAA8Ym+86vd4s3KwR0hQqlPbOE5TOchzJnLkS3rIjBYCqJr1g598r69+8hji0w5677YjPdxXjiEDcsHJP5ALehZ3iPDHwexUeHcKQJfa828wYKFLCqVr2JKDDfsHIGMxp417lzW/YcTBqQh3hHYuMPvN/hgLZu/WYqUbKafGDkPK+YsKcPwliCCRJKCcYevG1xtAWOXufO/8wOfNtl73L1qg8l/Yzp46luvVbi6YrjHKYMfwqJJAryT7D1CLI4wvnwkSPHy1bSU8UrU8cOLalFi4bSZvRdHHN7gn0q8FEWKA+Y0J3krT8643EPxcJg9xx/SrRkyYj5AwsOOMZhtZtQCZjgBAaO5mAvE4LUOECG0iZYg+BkiqN9WN1i0QIF/K7/TP2hlBlXeUJeiaKCcAJ4b+5UMd/A3IPJC8dIHnnkYTkbCI9WX9S7dzcRJHBWwPlNaHy9X+rilrzls41o8KCXCKbbefMj9h0B7ID+PalTx1aSFi72WMn+9ddforUgHfZl3n//Lbe9GreCg3wAY9+cMlo+CQjnIjD23LnzcgRg+bIPxGGgCpt8uvJhYxylwcoZ5qzXxw6L9AZ0ugEDeoopE2dMnfuDzsTw/F34wUwZ5DC3YZLDZIYV+3vvvSVmY2f6cL7HZITJB8oDzECvjhzAzl9j3PaHMMmMHj1EnKPgaYu+ABMhjvIYb220sUvndvIhAJw/xaocqwdgBY9RmdhZCZs/fzEd5lV7ZRa4wBB9KhgeovzExh9gBE9mmHOhwOIDGBCg6Od9+StazrE7fvwrYgm68447RZhCgMIvYP686bIyBX7YF92wfqmMe3iWzpz5htuXqZx7gkgfCgVTj2DLxYoaSj6O18F8CGEPX4q33x4npkRgsfbzjTRkcB9ZlXuW660/eqbBs6kzVvbY+sFRGijD6J9wnknIhPm/z39ezp999oUIv+i0p1evztLPgBWsf5Aj4Ee4UxIWStaxY2xKwwauv60hbAH6icfK4Vt2fEn3aNoouT1DoNzgjXNMiP4Ine/WrZu2+c8zLZb/0PAwKOBwFBuE8nFuDd52noRJHcdNsEINRBAsmLQDEdJBaEMpiMq+XaByg4mXPpGT+0QcEjRauLSbIw/eXg0lCj/PSRlYneYzfenYKxQKnS/yx0OTJyHwx9Q1JvgExff770+yQH2Uv3ud3m9fg7BJhjHmMV7feWeeeO+WK1eKjJkSZ0fxHWWMRxxjC7THbdoUzNVXPYLJ65nGG78x32BfLtA49dUfPd+BZ1jWMD8YU7C3NLEdFhP9JbbriLkcc6nZF43t90n5AeSb53cSkMdg6TLn+hGQ8pIA8egYnoe0JV+AP1hlBkPQSvwRJlV4wcUmOT0PPd+DCSIYAYp8gQamKRvpzL6zCbudr07vPV/thDLhTaEAVsFo9v54aN6Z2PiDfhts3/XVH+FdOfe9/9GbfMysJB9fwz9xgIMfqA37M8SkAEWZvuqBuKiSN34Hmm/MO3z1RxPvvEblTKUzX2K7x1wepwIUAAeQb/7iXUI0sXFK26sIKAIxhsDIkQMpIx/Lgjken/qENaD4U0WpcZO60fKQj7EKakGKQCwhoEI0loDVYhWBxIQAVnNd2JELPyVFIDEhEHhjLjGhoW1VBBQBRUARUASigIAK0SiApUkVAUVAEVAEFAEnAipEnWjovSKgCCgCioAiEAUEVIhGASxNqggoAoqAIqAIOBFwCVGck/FHgeL95dU4RUARUAQUAUUgXBEIJN/8xLuEaDTOyYQrLlovRUARUAQUAUUgIALRkH8uIRrwLZpAEVAEFAFFQBFQBJwIqBB1oqH3ioAioAgoAopAFBBQIRoFsDSpIqAIKAKKgCLgRECFqBMNvVcEFAFFQBFQBKKAgArRKIClSRUBRUARUAQUAScCKkSdaOi9IqAIKAKKgCIQBQRcQtTPORgpL1B8FF6qSRUBRUARUAQUgbBBIJB88xPvEqLROCcTNkBoRRQBRUARUAQUgagiEA35l4T/M7uF/9CtpAgoAoqAIqAIKALBI5AzZ1ay/58oHpQUAYMAFCvtEwaN8L0qn8KXN+FYM+0vMccVs/h0mXNjrmwtSRFQBBQBRUARSBQIqBBNFGzWRioCioAioAjEBgIqRGMDVS1TEVAEFAFFIFEgoEI0UbBZG6kIKAKKgCIQGwi4hKifczDy4kDxsVE7LVMRUAQUAUVAEYhtBALJNz/xLiEajXMysd0+LV8RUAQUAUVAEYg1BKIh/1xCNNZqpwUrAoqAIqAIKAK3JwIqRG9PvmqrFAFFQBFQBOIAARWicQCyvkIRUAQUAUXg9kRAhejtyVdtlSKgCCgCikAcIKBCNA5A1lcoAoqAIqAI3J4IqBC9PfmqrVIEFAFFQBGIAwRcQtTPORipR6D4OKisvkIRUAQUAUVAEYhxBALJNz/xLiEajXMyMd4gLVARUAQUAUVAEYgrBKIh/1xCNK4qq+9RBBQBRUARUARuEwTiXYj+738f04EDh2MNzgsXfqcrV67EWvn+Cv7rr79p9uwPCHVQCh6B2Mbt+vUbdO7cz8FXSFN6RSC2+WRZlvDpxo0bXt+vgYpAOCAQ70J08ODXaP36zTGOxZw5H9Djjz9F2bIVofTp81Hx4lVo795vY/w9/gr8+edf6cUXB9Lp02f8JYuRuM8++5y+//5kjJQV34XEFm6//HKB6tR5ltKly025chWnDBnyU79+I+jmzZtx1mTlU2CoITRfemmw8Ad8SpcuD9Wv35p++y1xKaMYz+gv4UClS1enIkUq0j///BupOphXkyXLQt9++12kuMQQEO9CNDZAXrJkOfXsOZAaN65LO3d+TmvWLKY0aVJTtWpN6ezZ87Hxyngvs337nrRyZXgMuHgHw0cFatRoSidP/kgLF77DCtVGGj78ZZozZwENGjTKR46YD1Y+Bca0b99htGDBEho1apDwad68aXTkyDGqW7dl4My3UQqMZ/SXcKHjx0/S6NGTwqU6YVOPpGFTkxisyLJlq6hUqadkEJpiFyyYQVmyFKYvvthErVs3NcF6TSQIfPfdUTp69HtavvwDKl++lLQ6W7YsdOrUaVqyZBmNGTM0kSAR3s2ECXfZstXUo8dz1LZtc5tPd9xxBzVq1I6VoFOUNWvm8G7EbVy7iROnUYMGNalgwXy3cSuj1rSQV6LNmnWiV14ZF+ltVas2phkz5kr4v/9eY21/LJUtW5OyZy/Kg6I77dixK1IeZ4C/PH/++Rc99VRlWr16nTMLHTt2gooVq0R79uyX8OvXr9Ojj6ZxS/Pggw/QAw/cT9gPA+3bd0DyHDp0hFq27EyZMxeiAgXKyR6mW8YAD++/v0hMhDANPvNMA8Ierz9atOgTKleuNpuo8gouixcv9ZdczNDLl6+h8ePfoieeKEF58pSiPn2GEfajQNu3fy3tuHr1Kk2aNF3ut2zZ4bfM2Io0/PFcEUNQgT+7du2VV//44xl64YX+lC9fGR6M5cXkHchC4C/Phg1bpPxff/3NrWngBfoe+pThu2e/wDPMh5i8Qe++u4Bq124hfal69Sa8FQA+1RKc3Qr3eMB2gfKJKLp8gmn95s1blDat+/g1z4aPofLJyTaYIcFrjN3ChSvSyJHjpS+YNOg3CCtVqhrlzl1S+uyZM2dNtFx///0PMT1jXGJ8jhs3VfoB+oMvMnU/cuS4vP+xx/LJKhv9x1C7dt1lPGNcY+y0atXFRMXbtUOHZ9mkW5C6du1rjydUxowdc0UYlFaY4LFwATbPPfcSXbx4CVFCKAOyYeHCj6hkyWrCg8aN29NPP50zSeSKuQxtz5q1CCu/dXhh9IYbj9wSx9ODS4j6OQcjdfOIL1QoH82fv9gGEGkgmDCplypVXLJ069aP5s37kDtIDXrttcECIrRJdB5f5C9PihTJxSwLc62T0PkgVAoUyCvBzZs3pLVrN9DWrV/J861bt7hDzpC9r9q1q0rYlStXZWXy3HO9eDLPzWaKIZQxY3rq1WsQYU8uGELbevQYwPtrObn817iz5KLnn+9NEKzeCPsbXbr0FU3uww/fZaFbnjp06Ml7wlu8JZcwrJ5ef/1NWrduEw0d2pfTt6RPPlkhnRKdFqupAQN60d1330WVKpWX+xw5svosLzYjXPxxVwzAH0w26DN//31RVhRQeHr16kLdunXgPrOLmjbt4NMBLFCeEiWK0Zkz5yLtHy1a9Kngc889d3PfyEP58+fmfjjR3tfBhD9r1nxCf0mSJMLHHftue/Z8K4pKgwa1aciQ3nT58mXhsz/slE8UkLfB8Clp0qTUpEk9mjnzPeEpMIcgGTNmEhUtWpD9HLILG0Llk+EhxjgU/gwZ0ot5v3v3jjR9+lyZpE0azAUY4+gfAwa8yKblA9SsWUepD9JA+WrTphutWLGWOnVqJeNzy5btIkjRH3wR6r5//yG2iHXlRUERnjtG0f3338eLjG68/bRbsrVu3UzGM8Y1xnf79i18FRdn4XfeeSe9/fbrMn9jReqLMBdXqlSfMO++/vownqtaE3DBIsoQlJGlS1fTBx98xEr08zKvffXVNzRhwlsmCcuTg7wl117m7bFjh1L16pW4X7xPvXvHgtXIQ77ZlTA3/uJ5IraOHj2BS5To+PET1kMPZba44XY+1tosXinKM2sQEr9x4zY7nleIVoUKdSwGxg7jFao1efKMoPPMnbvQYs3Runbtul0GymQHEfsZN2vWrLcefjiHxc5FFq8mLF7xWLwistN8+eVOqd+bb75jh7EXr+SZPXuBHebrhrVUK3XqnNawYWPckvTv/4rFGpiEsbIg79i9e588s8C1eBXqlp4FjMUrNLcw50OKFNks3tC3UDdDGzZslXJZ+JogK23a3DaOdmA0bkLpE3gd+MOOIBY7INhvr1KlkcWOIvLMQszKmrWwxZOYHX/69FmLtXFrypSZEuaJWzB5WBmxGjZsa5fJA1l4CXwNsSZsNWjQRsLz5i1tsTOExSsHiwe7SWKNHTtFsOVVih0GnNHX2eJhh3neKJ8sK6b4BH7wikP4Az5hHLPwsliZsWEPlU+mALYACU+dZbIAs1ggShIzP3z99R6TxWJLh5UpU0GLLW0SxkqxlIF8htDvy5SpYaE/+CJTd1a27SS8AreqVWtsVa7c0A7DvIhxHZMU6rjm1bjVu/cQqQor9cITXm3KM+Y3jA8WevLMyqnFCyy3OQuYYb408wJbAKwcOYq58ZQtmzJfm/HIPgwWfsDG0MqVa+VdrISboHi7GixdK1EjcYO8Zs+eVZb2WGUYgkbWqFEdeYSp5JFHHrb3nxAILbNevRo+vWSDyVO3bnXRBLdu3S7vgRlw9+79rL3WlWf8wSrnxRcHUc6c2dmkUFPeeenSJV4F9qFLly7b6XBTvnxp+/m+++5jbbeQrIwQCO84aD7OHxweQIcOHRYzYbNmDeTZ/MGK9uOP3zOPbtdcuXKwB9sh1qon0w8//ChxtWpVEQ3bLaHHQ5061Qh1M1ShQmnBdv/+gyYobK7gz7Vr12jTpm1SJ5hYoWHCyQsEbb5cuVJiUZAA/pMhQzrCKgUrQG8UTB7wH+80/IUlAphVqVLRLnLo0NG0bdtOqlWrqvSLsmVLEDTqDz/81E6Dm+TJk7nt+ZQs+aT0XVhZ/JHyKTBvg+ETLFxTp84i9PMGDWpRjRqV2VqzlUaMGO8GfyA+wRToHLu4h+kfhLkB1ocXXhjA88c+WTU9+WRhqlmzssSbvvjwwyllHxZ7sRcvXqRUqVLKfINE6JcZMz5GyGcIVg9Y3gJRxB5vxFyJtHhu2LCOeLiyVAiUPV7je/XqzObtXGxF6ie4eVYGmDz7bCMZf1h1Y7vt8uUrMl9euODacgFu999/v529bNmScqQJ2z/AAPjWr19LsDGJqld/RvIY/pjw+LxGy7EIAwIdc+TIAXTixA8sWI7QokWzpD0w2XpzAEDY+fO/iOknWbKH3NoeTB6YDCtXriD7DhUrlhWPVJQJUw8I4Lds2YUFfAGaO3eqTH4IxzthYhg48FWaMmU0goSSJ3evA/ZOzbm0gwePiBnJpMUVezPoIMZc462NzvTO+86d24pZc8aM98SsCFNsu3bNxYnCmBOd6c090nkS3ovOGW7k5A8EGEzYjz2Wjvd2i0pVweP69SNPMmjP9u07vTYnmDxPP12WHnzwQTHjY+KFcgeBDnMYCGa5OXMWsln8Y1H+zIsmTHhbJgMI8cyZM0qwZ7+899576K67ktr9wuT1vCqfAvM2EJ/Qp3Es7JVXBoip32AMXwqYX4sVK2grZIH4tGrVF5F8FKDoYN4oWDAv739PFoW2QoW6lDJlCil30KBecs+rLHk19uw9KVWqFBKEs8Zp0qT2jOY54pFIYZ4B6dOnZSFzr1twtmyZZesACwOMmXAlLIamTRvPC5BaYgIvWbKYW1Vhxn311QlsJv9Y9jihICDMkzz599BDD0qSGzduijDFHiowcRLmyaxZM/ndEnSmj4v7kFeiqBwmK6yoIDwxaUGzMBNRpkwZvB4nOXfuPGGi9QQQ5QWbB3smcF6BwFyxYo3bKhSD8PTpn9j+3twWoCgbDiRYgaxbtxmPQREG3IkTu91+27evlrxZsmSS608/uTsa+CsYnWnw4N50/PjXrBEvZaFeljfXX5c9FH/5PDfbkRYDDfs54UhYdUJ4YuCgXzRuXMfec8ycGf3i50jVRr8A/71RMHkwsOE1iP4Ah5C1azfK3popD2eRCxfO7yZAEdexY0teOV+3989N+lCuyqfAvA3Ep82bt4tjkeceIJScfPmeiNL4hR+G5/iF74IhWM127VrHK8sNosguYS9t7HGCMLZgbfvrr5ORfl98EeE8iPpAwfMUEMF8PAZnlo2ybuqDMQ2lLxghbPLE1xVt79OnO1sHxsmxMWc9pk2bIz4oQ4b04bluF/3xR4RXvDNNoHsoJ1BegYknIQxzQrhQtIQoBFO5ciVlosRk6TSpQtPD5rFZsZkGr1u3RZw8zLPzGmyeatUqiZMSBOLWrTtszRRlpUuXVlYNx45F3thHWEyBDycVCMXVq9c7myDeZgMGjHQLMw8wV8NUgQ16rJwnTBjJWnGZgB7LcDxymngwcDFhwyHKUNKkd4rJxDzH5xUml6tX/5HjRDCxGlMu6gTnL95vknhTR5hgee/Jdgwz4eYabB68Z82aDfxbz0rag1SmTISDG8rJlCmjKHyeE5dZzfsS4KYOwVyVT8Hx1h+fMD4hlI4f/8ENcihGp06dsZV0t8gQHmA5g3MPCI54vXt35bPlz/HWw24Za3CCgwkX4wyrH/PDFsrhw8ckX5kyJcRJDR68huBcyX4B5tHnFYobFAYnwXkQWz5QNEC4Xr9+TZQ8Z7pwuYcQzZEjCy9YurtVCds3WFC1aNFQVurA7ptv9rmlCfSAtufJ80SkD/FgDv3jjz95rsgXqIg4i4+WEEUtMSDgdgyvMtivDWGvEdoj3JOxP4XVKr5OhHOavXtHaHsmrbkGmwdmkNq1q8m+J4DOmTObKYJgEoAZDyu8d96ZJwMBXl59+gyVd7do0chOG50b7Le99FIXfs9Yeu+9/4lpFSZDfOTB2yob74IZF6YjdrYSJYAdhKRzQREBYXDyZrsIYgn47w8GM/Z48UWQzz/fKNoyNMFKlcrZybBvt3TpKvaC2yFl2xHxcAP+YNUPT2xo83nzPmHXAis/eLt26vSiHHmBmc4MQl/nd4PNA5MxrBww2TdsWNttLwXP2Jdh5yMR4lDwoPi1bt1FPHg9TVJ2hb3cKJ+8n7OOCT5hXwx7as2bdxJrBryusY9dv34rOVYBn4qYoB07vpHjT/iyGTzHwdNPP10lihcm/QoVyrDpuBAvDNrLvAGhO336HFZ66xG2eUDwxh89ejArw2/LERgcXatevSl7mj7rVkUc48C4NiZiRGIvEB+VwJjFuzGHfvTRCvFYN5nRJ3GkB/v24fg1MmxxvP32eFvom3rnz59HlOKPP14hVkHscZtjjyZNMNd+/bqzf8lKwQYYwbrVrl0PWXgUL14kmCLiJg2vcELyzkU+ELwg4ZlVp07LiADHX95Etpo06SDemvCE5LNTFp/dc6SwLKd3LiKCyYN0LIzlvcajE2GG4AUML1k+oyRpUD8+k2jBI8+Q8b5zeuwiDt6b7dq9YJL5vbLGbPGq0+JPk8l74AXME7jFqx3JxytGCTfeubzJbrFSIZ5tqBM8UlmxsFBfEG+kW48+msdi4S/P+AMvPz6GYbH7u3grpkyZ3eLzixYPajsNbuBBWrFiXSt58qwWn6N1iwvlwXiehZIXeQx/+HxrpCLgzchnaq1UqbILFrzXJW03CT1xQ3igPCYvvKWBrTfvPYTBcxIYIg08H3mytsAXQ/Cc5HNt5tG+pkmTyzJe28qnCFhii0/wgoUHf5o0TwifwC94tfPK0eZHMHyyE3u5wZjjfTuZm9AX4DnatGlH8cA1ydnkKvXAmEQaPktuTZs220TbV14giGf5G2+8bcHT/IMPlkgfMwkwnlEGr6IkyNSdFxfijYqyMYd4GyvsDCne7J5e/absqF5DHddO71zPd+JUBtpgvHPh8cxn72XuQvjTT9eTuRf3rLxKdnjnPv/8S25F4ZQC0rB1yA6Ht/+TTz4j4Zgvn332eZE5doJ4vDFYwnQRIURdXv7eq+UjHhMQJhj+iID3fByKDsvans94bxGh5PFWDjo1fwTAW1SMhuHIBoRqMIS2sVOC16RGAJtICFHW5OSRPYwtPjNporxejQu518goBJoOEoUsbkkxQaDucHf3RRhszqM7vtI5w0PJ48yPez4jbPHq3s113jNNoGflk3+EYoJPwBh84q0B/y+LZizGIsakLzLj1XN8Y+776KPlFoStk3hf1eJvzTqDbMUagUaI4h5lstMjbn0S0uBIXUxQdMd1VOqAsQ2FKCYIWHuOuZgo1y4j0NTtJd5g6fLOjThr7nv56xEPmz7s0/hKDjxW4WTki2DfhvdbVCiUPN7Kx/GJuCBvXnq+3ou2YT/ZG2G/1Bc98MADvqLscLjYxydhvwLu5zCpwgEMpjlf5HRv95XGMzyUPJ5lwNxsHMM844J9Vj75Ryom+ASMo8sn/7WMiPU1Fk1eX+MV3uD47nLq1KnYQa2VbCVgXxyfLRwzZojJLldf/QWm40COREhjvMzdCg3zB2x5OY/mRae6OFoUq+Qh3yK9y098yHuiOO/DplreT/iTz9m9G8kuHqkSGhASAthfSJkyeUh54yMTzvN17txbvg40btzw+KhCvLxT+RQvsMfrSyHY1q37RM5M8ocR2NdjCDuvneZjf2/wV3ra+KwbhGbu3I/7jNeIhIVAEixnjx07yc45WRNWzbW2sYqA9olYhTfGClc+xRiUiaIg7S8xx2aDZcgr0ZiripakCCgCioAioAgkTARUiCZMvmmtFQFFQBFQBMIAARWiYcAErYIioAgoAopAwkRAhWjC5JvWWhFQBBQBRSAMEHAJ0UD/OCBQfBg0RqugCCgCioAioAhEGYFA8s1PvEuI+jkHIxUKFB/lWmsGRUARUAQUAUUgDBAIJN/8xLuEaBi0Q6ugCCgCioAioAgkJARUiCYkbmldFQFFQBFQBMIKARWiYcUOrYwioAgoAopAQkJAhWhC4pbWVRFQBBQBRSCsEFAhGlbs0MooAoqAIqAIJCQEVIgmJG5pXRUBRUARUATCCgGXEPVzDkZqHCg+rJqllVEEFAFFQBFQBIJEIJB88xPvEqJ+zsFINQLFB1lXTaYIKAKKgCKgCIQVAoHkm594lxANqxZpZRQBRUARUAQUgfBHwP5/ouFfVa2hIqAIKAKKgCIQPgjg/3AnNdXRf8ptkNArEDD/cFbRCG8ElE/hzZ9wq532l5jjCLAEqTk35jDVkhQBRUARUAQSGQIqRBMZw7W5ioAioAgoAjGHgArRmMNSS1IEFAFFQBFIZAi4hKifczCCSaD4RAacNlcRUAQUAUXgNkEgkHzzE+8Son7OwQhMgeJvEyy1GYqAIqAIKAKJDIFA8s1PvEuIJjLMtLmKgCKgCCgCikB0EVAhGl0ENb8ioAgoAopAokVAhWiiZb02XBFQBBQBRSC6CKgQjS6Cml8RUAQUAUUg0SKgQjTRsl4brggoAoqAIhBdBFSIRhdBza8IKAKKgCKQaBFwCVE/52AEnUDxiRZCbbgioAgoAopAgkYgkHzzE+8Son7OwQg4geITNIJaeUVAEVAEFIFEi0Ag+eYn3iVEEy162nBFQBFQBBQBRSA0BFSIhoab5lIEFAFFQBFQBOL/X6H9738f04EDh2ONFRcu/E5XrlyJtfJ9FfzXX3/T7NkfEN6vFDUEYhu769dv0LlzP0etUpo6EgKxzSfLsoRPN27ciPRuDYgfBG7dukXff3+SfvrpXJxWwCknYrvfRbVh8b4SHTz4NVq/fnNU6x0w/Zw5H9Djjz9F2bIVofTp81Hx4lVo795vA+aLqQQ///wrvfjiQDp9+kxMFemznM8++1w6ts8ECSwitrD75ZcLVKfOs5QuXW7Klas4ZciQn/r1G0E3b96ME4SUT8HBDKH50kuDhT/gU7p0eah+/db022+JRyGFoEJ/CReC8BwwYKTwonDhipQ7d0nKnLkQLVmyLE6q6JQTsTU/hNqQeBeioVbcX74lS5ZTz54DqXHjurRz5+e0Zs1iSpMmNVWr1pTOnj3vL2uCjGvfvietXBk+Ay5cQaxRoymdPPkjLVz4DitUG2n48JdpzpwFNGjQqDipsvIpOJj79h1GCxYsoVGjBgmf5s2bRkeOHKO6dVsGV8BtkArjGf0lXGjYsLE0c+Z71L9/T5lT16//lKpWfZrr2INWr14XLtWMl3okjZe3xvJLly1bRaVKPSWD0LxqwYIZlCVLYfrii03UunVTE6zXRILAd98dpaNHv6flyz+g8uVLSauzZctCp06dFm16zJihiQSJ8G4mTLjLlq2mHj2eo7Ztm9t8uuOOO6hRo3asBJ2irFkzh3cjbsPaffrpZywwW1KvXl3s1hUrVogOHz5GixZ9wguUSnZ4YrtxrUT9nIMRUDzimzXrRK+8Mi4SXlWrNqYZM+ZK+L//XmNtfyyVLVuTsmcvyoOiO+3YsStSHmeAvzx//vkXPfVU5Uiaz7FjJ6hYsUq0Z89+Ker69ev06KNpnMXSgw8+QA88cD9hP8wQzLu1a7cQsxFMFCNHjqeo7L+8//4iMQ/CLPjMMw0Idnt/hM5WrlxtNonkFUwWL17qL7mYoJcvX0Pjx79FTzxRgvLkKUV9+gwj7AmAtm//Wtp99epVmjRputxv2bLDb5mxGWn447kqhqACf3bt2iuv//HHM/TCC/0pX74yVLBgeTF7B7IQ+MuzYcMWKf/XX39zax74gb6HPmX47tkv8AyeY/I2pHyKPz7BtH7z5i1Km9Z9/Jpnw0fwKqp8MvzFNZixj/Fdq1ZzUb5btuxM27btdBZBv//+h5idMS4xPseNm8pK2hoZt24JHQ/vvrtA5pwjR47L9bHH8skKG/kMtWvXXcYzxjXGTatWLsFl0sTlFZifPXuOMmZMH+m1S5bMEYuOicC2GZQgzFOY84sUqUiff75RsGrf/gWZa5988hmaN+9Dk0WuK1aspYoV6/LWW17Bb8yYyW5j0i1xbDy4hr/30v3Eu4Son3MwUqpHfKFC+Wj+/MVuDd2374BM7KVKFZcs3br1E7Dq1q1Br702mC5evCTaJDqQL/KXJ0WK5GKWhbnWSeiAECwFCuSV4ObNG9LatRto69av5Bn2/EmTZsjeV+3aVSUMdnUI/AwZ0ot5r3v3jjR9+lxevb7hLNrnPTpBjx4DeG8tJ5f9Ggu4XPT8870JA88bYX+jS5e+1KBBTfrww3dZ6JanDh168n7wFm/JJQwrp9dff5PWrdtEQ4f25fQt6ZNPVtBzz70kuGMlNWBAL7r77ruoUqXycp8jR1af5cV2hIs/7soB+IMJB33m778vSh+AwgOttlu3DtxndlHTph18OoAFylOiRDE6c+ZcpD2kRYs+5T3xLHTPPXdz38hD+fPn5n44kf7551+BAoJ51qz5hP6SJElEB1c+xS+fkiZNSk2a1BPTIXgKgjAZM2YSFS1akP0csktYKHySjPwnmLG/cOFHrNwN4ncWYuE4XPpHkybtxZqBcqB4tWnTjTD5d+rUSsbnli3bRZBi3Poi7Ovu33+IrWFdeUFQhOeOUXT//ffxAqMbm0l3S7bWrZvJeMa4xvhu376Fr+LiJPyuu5KyMC9Mb775Dnkq6dgmy5w5o10PtB2LkTvvvJOxGCHzK3Bq3vw5XtikpalTxxLmKCjRBw9GOJRu3LiNWrR4TuaHt956napUqcgLh6k0efIMu9xYv/GQb5He5y+eNXDr6NETuESJjh8/YT30UGbrq6++sfMxeBavFOWZwZZ4BsiO5xWiVaFCHatx4/Z2GGsrFoMVdJ65cxdavPKzrl27bpeBMtlBxH7GzZo1662HH85hsXORxdqNxSsei1dEdhpeBUr9Ll++bIdxJ7Z4UNjPvm54ZWOlTp3TGjZsjFuS/v1fsdgBQsJYUZDyd+/eJ88scC1ehbqlZ+Fi8erMLcz5kCJFNos1OYu9i+3gDRu2SrksfO2wtGlz2xjagdG8CaVP4JXgDzuCWCyo7BpUqdLIYkcReWYhZmXNWtjiicyOP336rMUauTVlykwJ88QumDyskFgNG7a1y2SlSvgPjA2xEmc1aNBGwvPmLW0lS5bF4tWDxUqWSWIpn+KfT+AHK7PCH/AJ47hZs46Wc6yGwifD5EBjH3NLmjS5rDfeeNtksXiFbFWv3sTiFamEsRCXcYg5wxD6fJkyNSyMW180duwUycfKtp0EZVer1tiqXLmhHYY5EeM6pinUcY25k1fcUndcO3fuLXMsKxNuVUTbeSVth/3xx59W8uRZLd47tcOAU6pU2S1elUsYMFy6dJUdjxvgDLwNOeWE5/xg0sT11WDpWolGEr3+A7Jnz8pL9YJivjApoZU1alRHHmEueeSRh+39JwRCy6xXr4ZPL9lg8tStW100061bt8t7YAbcvXs/a6915Rl/sMqBFpkzZ3b26qsp77x06RKvBPvQpUuXJR3isPp44YUBnH8fYbX65JOFqWbNyhIP7XfmzPcj/bAqOnTosJgImzVrIGnNn9Gjh9DHH79nHt2uuXLloG+/PcQa9WT64YcfJa5WrSqiXbsl9HioU6ca3XfffXZohQqlBdf9+w/aYeF0A/5cu3aNNm3aJtWCiZUVLXHyQsDevQfYpF1KLAqm3hkypCOsJvfs8e49HUwe8B/vNPyFJQK4Qas1NHToaDHJ1apVVfpF2bIlaOLEaWwZ+NQkYcuC8glgBIO5Ddp/N8HkCYZPsHBNnTqL0NcbNKhFNWpUZovNVhoxYrz9ykB8worJc/zC7A8KNPa/4/3zq1f/EcsW9mDxw5ZEjhzZxNKGMtDWjBkfkzkDzyBYPGB1C0QR+7sR8yTS4rlhwzo8P3znZtkLVE5cxmfKlIHbvImtj9N5BV1YTLTYo8Y2GLBxUunSJexHWKewlVasWEE7DDjBPH/hQsT2C+ZdzHOYgzGfA39YFv2t6O3CwuAmWo5FGBDoqCNHDqATJ35g4XKE9ylmSbNgsvXmAICw8+d/EbNesmQPuUEQTB4wpXLlCiK8K1YsK16pKBOmHhBrI9SyZRcW8AVo7typIrgRjndWqlSfBg58laZMGc17cXnp3Xcni1CrUKEupUyZQib6QYN6yf3Fi5fFhIS8TqpSpYLNXG/tc6Z13nfu3FZMmjNmvCcmRZgZ27VrLg4UxpToTG/ukc6T8F7sA4cjOfkDAQaz22OPpeN9jqJSXfC4fv3IEw3atH27+56TaV8weZ5+uiwP1gfFjI+JFyZkCHSYxEAwv8+Zs5BN4x+L8mfKnjDhbTYp9xMhDrOU8il++YR+jaNhr7wyQEz9hk/wpcD2CyZjeN0H4tOqVV9E8lHARI05I9DYP3z4qLwWx2q8EbYDcM44DZsyPSlt2kc8gyI9p0+flhW8e93Cs2XLTLzSFiGC8RKOBLMuMMQP+6Tw6ejXb7hsL+EEhKF7773H3NpXmHed5JzzeLUqi5516zaLXMB7nHvfznzheB/yShSNwWSFVRWEJyYtaBTGPg7NxZuzyLlz5wkTracARXnB5sGeCZxXIDBXrFjjtgrFIDx9+ieCZx9WvobgQIIVCBhlCKvmXbvW8Up0gwgznHmC/R6EAXLixO5IvyxZMrGjQSZJ89NPZ+UazB9om4MH96bjx7+mDRuWskAvS8OHvy57KP7yezvUDFyxlxuuhEkOwhOaJfpF48Z17D3HzJnRL36OVHX0C/DfGwWTB7zGfjP6AxyJ1q7dKHtrpjycRS5cOL+bAEVcx44teeV83d4/Vz5FbP4Eg7nB1lyDyROIT5s3bxfHIs99QFgq8uV7wh6/gfgEHwzP8QvfBUP+xr4ZW0eOfMUropORfhASqMsRVgjRx50UzIdjcF7Z04ERYxoKXzBC2Pm+uLjHeMJeLuZbQxB0LVo05AVLY9uSZ+KieoWvCFb2s2dP4Y84HOB3HaeXX+7hdREW1bLjIn20hCgEU7lyJWWixGTpNKlC2ztz5qy9ajONWbduizh5mGfnNdg8cKeGkxIE4tatO2xTIcpKly4tgcHHjkXe3EcYBjoIK2ds8IOw0d27d1c+W/ocmx53u3UWSeDxBw4qGMSrV693i4EzAg4keyOYqmH2gEaGVfOECSNZKy4T0FsZjkfOzouBC8GaL19u+zVJk97JWuwV+zm+b6pXf0bMYThOBBMrhKohOH99+eVOiTdhMMF+/fUe2zHMhJtrsHnwnjVrNvBvPStpD1KZMhEObignU6aMovB5Tl5mRW8EuPIpAvVgMTc8wjXYPP74hPEJwXT8+A/OokUxOnXqjK2kh8onFBpo7KMdWCnBUQhX8/vxxzP2eC1TpoQ4qMGJxhAcK9knwDz6vEJpg7LgJDgPwkRtFH9cr1+/JgqeM1183EccKypCcADyJJyEgBUJ82GoFLHdU0e2Xh566EEpxnjyh1pmnObjCTokxyLkA2GDHA5G+P3scBbB5jE2yuFoxJOaxZ5YFh9qt1KmzG45nWKcG8bB5sF72UPVgtNBmTI18ehG2NiGYwCbmi0eMBZrOVbv3kOkjmzWk7R8mFscF2bPXmCxlmWxHV4cf+B4EgyNGPG69cgjj4sjDdvuBQc8wwkGxMJO3mcci7ARz+dULTgG8b6qYJApU0GL9+QkPd4PLD74YIk84w826XPkKCbOLizwLd7ns9iF3CpVqho7G1210/HehITzwJSy7Yho3JhN81CL6NSpl7Qf9XUSWy7EsejZZ5+3WHBafExHHILgAMbKgST1xC6YPMjIk684P6BfsDLjfK21b99B6RP8xSJr27avLLZWWOyKb+XOXUKczuD0BlI+RcAWDOaxwSfMW2tNZAAAQABJREFUAXBcAQ9XrlzLfDprsZe9OJmkSfOExVavoPgU0Qrvf4MZ+3AShEMiK8Yyh/AiQZwUe/YcYBc6ffoc6eN8vMUqW7aWONSh3zkdizCeMa5NveFYBIchOAzy2UuZd159dYKUA4cnQ5g3MKeyD4UFJ86YolDHNeZyjFE+Nmahb4D3cMrDfG7mPNQRbec9bbfqwmmQjz26hYHHwAKEMVmgQDkZl6zUWkOHjhHnUYQZcsoJz35n0sT11WCJVU6EEHU5KHqvi494eEGC2XXqtIyUjzeOrSZNOkjngickJlQwwUlOcBAeTB6k41WOvNd4dCLMECZEDAIILSPg+Uyi5eykSIPOC09SpIG3bdOmHS12hDHF+L1iwsaA4c+SSX4MON5vtYy3miejIaj5vJd4GuJ96Fj8KSvLTN4Q9I8+msd655159nvRIfkIhsXu7yLw0WHhsQbFwElQSviMlXjB8ddDnFEh35sOEmoBhj98xjVSEfDG43O14qEHz0ve6xJFxyT0xA7hgfKYvPCYBr7sXGaC7CvC4D0JHJEGk1nz5p1EiTKJlE8GicCYxxafMAbhwQ+hCT6BX/BshyJpKBCfTDpv12DGPjxme/ceauXM+aTUAf0UAhRC3kkQjpiD4MkLgQ+hifoawnjGuOaVswRBcECAQCGGUEL7MId4GyfsCCkKp6dXvyk7lGuo4xqe7bzVJWMWdcYP7YKQd1IoQhTzGRYGKBNyAu3GSY84FaI+5JvdNi/xBkuXELVTR+0GnRmrPj747DMjOi2fE/QZ7y0ilDzeykHH5o8AeIuyw9hJwBZmdmAUbrACh1ANhtAuvM8bGQFs4pwdkr2LA64yPQe4KSeUq+kgoeRFHkwSqD+bwHwWgSMLzuM7PhM6IkLJ48gut1jFs4lKji14xpln5ZNBwpKjJfHBJ4wH8Ik9ZV2V8bjzxyePpF4fgxn73tJg3vvoo+UW72+6lQtBU7p0dbcw57g2QhQJMGeww6NbWs8HpMGRupii6I5r1AUKP1bHwc55wdYdmGKeSyhksHR53kTRiAy7PvYl8KUcuCvDycgXwb4P79eoUCh5vJWP4xOByPMrNoHSe8an8eKl55nGPKNdvt7n6cFm8uD6wAMPOB+93sN1PL4JnnY4qgIvaDiA4RiAL7r//vt9RfkMDyWPZ2HwjDTOYZ5x5ln5ZJAg/hhA/PAJ4yE6fHK1wPedr7HozOEtDTzB8c3l1KlTsXNaK3GWhP8CvtYzZswQZ3bxg3AL+O8Be62BHImQxniYeysjrsNQF/iuxAalSpUyNoqN9TJD3g3GGR821fKxjT/lCzyYdJRiFoH8+fOw8pE8ZguN5dJwno/3FeXrQPjSS2Ig5VNi4LJ7GyFM1q37hP+bSS75sg77XLDj2mk+8vcGH/lo457Y8QShmTv3444QvU3oCCTB0vnYsZN8ADlrQm+L1j8GEdA+EYNgxmJRyqdYBPc2LFr7S8wx1WAZ8ko05qqiJSkCioAioAgoAgkTARWiCZNvWmtFQBFQBBSBMEBAhWgYMEGroAgoAoqAIpAwEXAJUdcXnby3JFC891waqggoAoqAIqAIhDcCgeSbn3iXEI34ZKbvhgaK951TYxQBRUARUAQUgfBFIJB88xPvEqLh2zytmSKgCCgCioAiEJYIqBANS7ZopRQBRUARUAQSAgIqRBMCl7SOioAioAgoAmGJgArRsGSLVkoRUAQUAUUgISCgQjQhcEnrqAgoAoqAIhCWCKgQDUu2aKUUAUVAEVAEEgICLiHq5xyMNCRQfEJordZREVAEFAFFQBHwRCCQfPMT7xKifs7ByPsCxXtWSp8VAUVAEVAEFIGEgEAg+eYn3iVEE0JDtY6KgCKgCCgCikAYIWD/K7QwqpNWRRFQBBQBRUARCHsE8C9E7f+krf9PNOz5FacVNP8rL05fqi+LMgLKpyhDlqgzaH+JOfYDS5Cac2MOUy1JEVAEFAFFIJEhoEI0kTFcm6sIKAKKgCIQcwioEI05LLUkRUARUAQUgUSGgEuI+jkHI5gEik9kwGlzFQFFQBFQBG4TBALJNz/xLiHq5xyMwBQo/jbBUpuhCCgCioAikMgQCCTf/MS7hGgiw0ybqwgoAoqAIqAIRBcBFaLRRVDzKwKKgCKgCCRaBFSIJlrWa8MVAUVAEVAEoouACtHoIqj5FQFFQBFQBBItAipEEy3rteGKgCKgCCgC0UVAhWh0EdT8ioAioAgoAokWARWiiZb12nBFQBFQBBSB6CKgQjS6CGp+RUARUAQUgUSLgArRRMt6bbgioAgoAopAdBFQIRpdBDW/IqAIKAKKQKJFIN6F6P/+9zEdOHA41hhw4cLvdOXKlVgrP6oFb9y4jb74YlNUsyWq9H/99TfNnv0BgXexQdev36Bz536OjaITVZmxzSfLsoRPN27cSFS4amOJtmzZQWvWrLeh+Oyzz2nt2g32czjdxLsQHTz4NVq/fnOMYzJnzgf0+ONPUbZsRSh9+nxUvHgV2rv32xh/T1QLfO+9hTRjxntRzRbl9N9/f5LQ8RIi/fzzr/TiiwPp9OkzMVr9X365QHXqPEvp0uWmXLmKU4YM+alfvxF08+bNGH1PVApTPkVGC0LzpZcGC3/Ap3Tp8lD9+q3pt99iR6mKXIPwDcGYRp+JaypYsDylTZubLl267PPVw4ePpWTJstDq1et8pgk2YsGCxfTWW+/ayYcPf51GjhxvP4fTjUuI+vlKvVQ4UHwYtWrJkuXUs+dAaty4Lu3c+TlrNIspTZrUVK1aUzp79nwY1TT2qrJy5efUvn3P2HtBAiy5Ro2mdPLkj7Rw4TusUG2k4cNfpjlzFtCgQaPirTXKp8jQ9+07jBYsWEKjRg0SPs2bN42OHDlGdeu2jJw4kYVgTKPPxDXde+89dPXqVVqyZJnXV0MRnTfvQ69xMRH46afzaPHiOTFRlPcyAsk3P/FJ7RL9fKVe0gSKtwuK/5tly1ZRqVJPySA0tVmwYAZlyVJYTKmtWzc1wXpNJAh8991ROnr0e1q+/AMqX76UtDpbtix06tRpmRjGjBmaSJAI72bChLts2Wrq0eM5atu2uc2nO+64gxo1asdK0CnKmjVzeDfiNqxd0qR3SqvefXe+zRdnM7FF9euvvzmDYvQ+ffpHY7S8SIUFkm9+4l0r0Uil+g9o1qwTvfLKuEiJqlZtzObKuRL+77/XWNsfS2XL1qTs2Ysy+N1px45dkfI4A/zl+fPPv+ippypHMhccO3aCihWrRHv27Jeirl+/To8+msZZLD344AP0wAP3E/bDQPv2HZA8+/cf4hVrezEdVavWhE6c+IEQhnakS5eXnn66Hn3zzT63svw9XLt2XXBBmzNnLiRmKFMvb/lgomrf/gXKmfNJMT+3b9/D717gu+8uoNq1W7Bmflyujz2WTzT05cvX2MW3a9edJk2aLpojcGnVqosdF5s3hj+emjIEFeqxa9deef2PP56hF17oT/nylSGYiWC6DWQh8Jdnw4YtUr7nIMZ+O/iAPmX47tkv8AzzISZvkMH3q6++Ed7D5NupUy/ZV//kk5VUtOjTlDFjAWratCP9/vsfksfbH1OO8snF22D4hBXNzZu32HToPn7Ns+GjwTe6fPLk3aJFn1C5crVl7KPvLF681C3J6dM/iZUrd+6SVLJkNRox4nXCmHcS+gm2DTA2a9ZsZo9V1NkXde3aV+bKVau+kK0nzB2YF4y/yPbtX0sfx2oQYxvjCfuGcUmNGtXhefOgtMfzvViFIt6TMPZghi1VqhoBM4z7M2fOuiX79tvvCHMW2lyiRFWvK+1evQbRwIGvSj74laD9wMJJbdp0o3HjpkpQbM3vzveZ+5CFaKFC+Wj+/MX25IMCUXEwu1Sp4lJ+t279ZIlft24Neu21wXTx4iXRJjGx+CJ/eVKkSC5mWZhrnQQBAieHAgXySnDz5g1lE3rr1q/k+datW9zxZsjeV+3aVSXsypWrsjLp2XMAVahQmsEfTj/9dI5atuwsnbdu3eo0efIounz5CjVp0p5QRjDUvfvL4hRTu3Y1afOtW5aYkQ8e9O48Va9eK/rhh9M0bdp4wmoIK6ZmzTr6fBWELoR869ZdWaEowu0aRffffx8rKN3YdL1b8rVu3YwqVSpPd999Fw0Y0Ivb08JneTEZ4eKP+8QD/kDgoM/8/fdF6QNQLHr16kLdunXgPrOLhVIHnw5ggfKUKFGMB+a5SHvAixZ9ynviWeiee+7mvpGH8ufPzTyZSP/88680G4J51qz5hP6SJEmEqgl89+49IAO/Y8dWvGf6Ai1d+hmneZ77yJvUu3c3GjKkD09g21n4D/IJn/IpMm+D4VPSpEl5vNWjmTPfE54CYEyWY8ZMYgWmICua2QXzmOKTk4HYb+zSpS81aFCTPvzwXXrmmfLUoUNP9tnYIsngoNikSQcRJAMH9uI+0YDef38R9enjsmJs2LCVx1sPSpkyBc8fr1Hp0sVl8QBBgTr7IgiW1avXc98aTW3aNGOB2k/mJ4yLP/74U/oxxjLGNMY27nPkyOqruFgJz5kzm1j4PM22cACE8Pdm4YPwQ3qMsQEDXpSxhfnNCEDMC2gjFkJoM8oYOnQ07d4dsSAyDcH4PncuYisO+7KwKnnOyadOnSH4PYBia3439XG7sgZuHT16Apco0fHjJ6yHHspssSZo52ONw+KVojyzliTxrDXY8bxCtCpUqGPxys8O4xWqNXnyjKDzzJ270OLVgcXan10GymQHEfsZN+zZZT38cA6LnYus9OnzWrzisXhFZKf58sudUj/WDu2wFSvWShg7JdlhqD/ayUyzw3zdsNCWtGzasJOgntWrN7F48pYwFnYWm6Xknj1EJT1vxNvpUUfudBZrcHaY82bs2CmShwevHczau1WtWmOrcuWGdhgwZUcA+zmqN6H0CbwD/GFHEIsFlf3KKlUaWewoIs/AIWvWwhY7D9nxp0+ftVhrt6ZMmSlhrGRJG3fv3hd0Hp7srIYN29plslIl/GcBboexEmc1aNBGwvPmLW2xE4TFmqvFg9FOY/B18vvll0dIfdDnDb366gQrR45i5jHS1ZSjfHLnbTB8Aj9GjXpD+AM+YRzzxGtdvnzZxtngG10+2QXyTY8eAyxehTqDLPQftqBIGN6J+YSFmp3GzA+sJEtYmTI1pY85+9THH6+Q/oP8voitS1bq1DktVqLtJOfP/2LxFpTFFj87DGPazJd2YBRuQh3XvJKUOYz3qi3M2ZjLDU2dOkvmV4RhrmSBKlFmjv366z0mqcXWIitTpoIWWysljFfy0ka01RAwABbAxBDmTMydIPAE77l06ZKJlmv58nWsPn2Gyb15d0zO724v4weDZcgr0ezZs1KRIgV5j8llRmQhZC/p4Qn7yCMP2/tPkNzQMuvVq8HaiHcv2WDyYIUILWbr1u2iDMAMCK2lSZO6tnKAVQ5WCTlzZmdzak15JwPOWmafSN5lZcpErJqROWPGx6SMokUL2WVlyZJR7i9ciLD3w4Qyc+b7bj+YqUA86VPq1KlYUywnz/hz111JeYW0SLQwO/C/G6RNlSoljR49mT7/fCO36x/KlCkDr4Ybi8bpmd48R+wPuUwneG7YsA5B22XemmTxcgV/rl27Rps2bZP3w8QKkxucvEBY5ZUrV0osChLAfzJkSMdmnGJsjvfVLwLnAf/xTuM9CHf4++67j6pUqWheIxrutm07qVatqtIvypYtQRMnTuNVx6d2GtzACQ1atyHwJHnyZLwl4dL8M2fO6NfsjrzKp8i8DYZPsHDxxCwWogYNalGNGpV5NbiVTafu3pmh8Am89hy/hw8fE1bnypWDx9AhXvVOZuvQjxJWq1YVWQHjAVa2DBnSy8oQe7P4oe+CYIWDWfe7747wSraWbdlAXJ061QiOOYGoYMF89MQTOe1kadM+IvMnTKjhQvXr15B5CqtmQ1hpeluFmvH88MMpBSvgdfHiRZnzzEoTVrXy7KOAthoCBsAiJiiq83so73Q5FoWQGwMCHXLkyAGyl3jo0BFatGiWlASTrTcHAISx1iFmvWTJHnJ7azB5YDKsXLmCCO+KFcuK/RxlwtQDghBp2bILC/gCNHfuVBHcCMc7K1WqL3b1KVNGI0jIW+e+806XbmHMfCY9zBbYa3MSBgnqAhMDzIfBEpSKTz99n3DMB04TMNVUq1aJ+vfvSXnzPuGzmPTp07KAuNctPlu2zGx6vix7i489FjGw3RLE0YOTPxBgMJGhPsWLF5UagMcYiJ4EHm7fvtMzOOg8Tz9dlve9HxQzPiYxKHcQ6MAUhIE+Z85CWrfuY1H+JJD/TJjwNpuU+4kQh2AE3XNP5AnvzjvvlDjzx7NfmHDnVfkUgYaTt4H4BLMe9shfeWWAmPoNnvClgJ9CsWIFbYUsFD7heBkmcyclS/agCK/OndvKtgPSwOyPsdyuXXNxcgK/163bLNmwj+9J6Ncw10KQQrg7CX0HCnMg8jZ3ZM2aiT7+eGWgrHEWD8W0ceM6Mp6gYMBfBPNeixYNI9WBV5QS5g2vVKlSSBz4DfO5JwGL8+ejf5Y7qvO7Zz2CeXZJi2BSe6TBZAWNDcITk9aTTxbmzeGIiQjauzdnEdi1MdF6ClAUHWwe7JnAeQUCc8WKNW6rUDAFm//w7IOQMgQHEqxAzEAw4VG9Ym/3xIndbr9Jk16TYrJkyRRp0zxQ+YUK5ec2LOQ9ga95D2W0bNrXqNFM9o995YXd3/MAOrCGwHBqdL7yx3Y4Vp0QntizQL/AoDNCJ3Nm9IvIgwP9Avz3RsHkAa8xGNEf4Mywdu1G2Vsz5eEscuHC+d0EKOI6dmwpE5/ZPzfpY+KqfIpA0cnbQHzavHm7OBZ57uPDUpEv3xPRHr/r1n3iNnYxlps1ayAVheVg8ODedPz417Rhw1JWussSzicaZxWsmDCv/PXXyUg/HJdKly6trLIwHzoJDnfY0wtEZ89GToOxkjFj+kBZ4zQeq05YznCee968RbKo8XTYQ4Wwaof1xhteX3wRsRBB27zNB96wMI00cwkUFiddv37N+Rhn9y4hGsgK6CUewJUrV1ImSkyWTpNqwYJ5RaBAS3HSunVbxMnDGWbug82D1RqclCAQt27dYWumKAcdGSbUY8fc34s4hGFCji2C4wyEGUwUToKHMu8VOoPkHhvy0LDhkQjtFdrc22+PE3MRNFtfhM6DycZJ69Zt4g8I5LAVB0xW6FSeHc2ZJ7buq1d/Rkw+cHuHidWYcvE+OH/xfoXEm/fDBMv7JrZjmAk312Dz4D1r1myQL51gdeE05WTKlFEUPk/lA0oXyJcAN3UI5ap8IjGve/LWH58wPqF8HT/+gxvkUIzgOGKUdLfIGHrAdhI8ybFyhGVrwoSRbGEqY58oKFgwn5h0b9y4KUqhmcyxxWMWDBUrlibe27eFJtrSu7fL8chfVffyVofTwxzbOxgrefPmtrPhqAmcHeOTsI2HuWb27AV8PGw5O0J5PzKI+RCrfjhsAivz27//IBkTOtrmOR8AA2Dhi2DhARmTMO5hhTtx4kfchkZe5JtbQX7iXUI0iVuWyA8+4jEg2AlAPEPr169l5ytfvrSYyHC8AvtT0M5gtsTECg9HbxRsHpgy4f2Kfc88eZ5w27966KEHxYwHDfKdd+YJE7GnAA86vLtFi0beXh0jYdjrwz4bPGXx1Q60eejQMfTGG9Pc9tPMy8B4HKvB4XKsnmFyxjksrNKNpzE+GgG3b+fkf//990uepUtXSWcE/h99tEK8XU3ZJUsWk2Md2POL6y+cgD9Y9cNEDU3UaZrGyg/t7tTpRTnyAiUCR59A3vZVEB5sHpiMYeWAK3zDhrVlTxL5QXjG5MPORzJo4Q0Jxa916y5itgNe0aGFCz9ib8li4l1tylE+eeetPz6VLVtSfBOaN+8k1gys4LCPXb9+K+nP8KmILYIZt0KFusTOQqKkw9MW5kosFEDoh1B8Td/F+I74qEs7rlvEqmjixFGyrVCwYFn27m3Afauo9ENYqQxhLGNMI6+TMG7QHyGU8V68ByZivNdQyZJPsrf4KkmDhUR8EQQnO0rJyQCn34GzPhUqlGHzeyFeXLWXuRfHB6dPn8OKST06eDBitd6pUysxoXfs2FPajLYDAxxH9EVPPPE4xz8gFgIsJnDyoXPnPoyzDyHlqyBneKCsfuJdQtRZYBTuse8Ewp6gcy8AxwoWLpzJHzjIJJMkzlRBiE2bNk60O2+viEoerHpxRMG5+jVlzpw5kd3Mn5V9Ddjjcd4LK5TZs6eI045JF9NXrIDnz58u+ytwjcdAwbmzWbMmiXD1fB+0auzbrlq1jgVNac5XglexB9lUvdDey8NGPAYLzs4ZwkY9jsP06zdczs1iv2/YsH62UxfSFS5cQNqKM7vx8eWipk3rSXWdq1AEoM2LFr0rpqCqVRuxsG0uq5UPP5zNn2f0fqA62DzQdGE69tYvCvARF3y5Ci71tWq1YOWrlJz/hDl9/fpP7BW8VDqEP5cvX2UhfZVX/i6TkvLJO2/98QlzwKZNy5k/uXg/sgdfS8p5aGALE2Du3I+HwJ3gsuALSVCCGzVqK2c8sQCAYte9e8SRM8xlmNOggLHHuYxvOBuhP5sVMpS4L7/8jI++TBPHKPhfzJz5hmw9od0gjGVYX/7++2+3isEhsXLlivL+ihXrsvL7g8xZTie3rl3bi+DCWXGs4OKLsKWG+Q7WM+e2mbM+EfP5O2zWfYzPqnflI24VeN6awvPyIG5jbUmKYzqYl0+cOMVyoa60HZZGWAB8EZSN999/i/P8IPMH8pUq9aQ4kvrKE6vhvK9ou+riPqrEmpKVJk0ui4WFz6xwfebJy2e8t4hQ8ngrB8cneE/CW1SshqH+cOcOloAjr9C8JmfN1Q6HmzwLAHmGGz2vXu04bzdIw6Ywb1F+w4z7tt9EfiLZ+mClSJHNYoHmMxXay2fvfMZ7iwglj2c5fIbMYjOThaNBMUnKJxeaMcEn4Ak+sVnTVXAc3GHs4viZP8LxCudRF5MWx9w2bfrSPMoVRzZwJINPL9jhzr6CQBzneP75lySetwEsPg1gp/V24zxC5i3eV1h0x7WvcgOFG0wxH/kizJdoe1QI818o81tU3uErrcHS5XkTRVGN/R7sIeDrGfiaCJyMfBE0FRw+jgqFksdb+cYF3VtcbIah/sF45Jk64KiLL/L0DDXpoNkGciRCGuOhavLF5hUHw+HaDpMqtNWMGR/z+TqYO6NKoeTxfAc0Wad5zTM+1Gflkwu5mOAT8IwNPrlq6f0OY9ebo4wzNcyJ3ggmXmwd9ez5PH/RqJh8RGDhwo9lpQrHJEO++griscJ7+OFUJqnXK1Z5CYmCwTQq86Vpe6D5z6SLzWvIQhTnJvH1Dpzpwdc9AJJS7COAThObJq3otgDn+QYMeEWcevAVqMRKyqfEyXns8eELYnAkxDYLhDGclEaMeFk+PeoLFRxRS5PGdVbSVzoNDz8EkmCpeuzYSbYnZw2/2mmN4g0B7RPxBn2UXqx8ihJciT6x9peY6wIGy2g7FsVclbQkRUARUAQUAUUgYSHgEqJ+zsFIkwLFJ6x2a20VAUVAEVAEFIEIBALJNz/xLiHq5xyMvCVQvDJDEVAEFAFFQBFIiAgEkm9+4l1CNCE2XOusCCgCioAioAjEIwIqROMRfH21IqAIKAKKQMJGQIVowuaf1l4RUAQUAUUgHhFQIRqP4OurFQFFQBFQBBI2AipEEzb/tPaKgCKgCCgC8YiACtF4BF9frQgoAoqAIpCwEXAJUT/nYKSJgeITNg5ae0VAEVAEFIHEikAg+eYn3iVE/ZyDEVwDxSdW8LXdioAioAgoAgkbgUDyzU+8S4gmbAi09oqAIqAIKAKKQJwjoEI0ziHXFyoCioAioAjcLgioEL1dOKntUAQUAUVAEYhzBOx/hRbnb9YXKgKKgCKgCCgCCRgB/AtR+z9p6/8TTcCcjIWqm/+VFwtFa5ExiIDyKQbBTARFaX+JOSYDS5Cac2MOUy1JEVAEFAFFIJEh4BKifs7BCCaB4hMZcNpcRUARUAQUgdsEgUDyzU+8S4j6OQcjMAWKv02w1GYoAoqAIqAIJDIEAsk3P/EuIZrIMNPmKgKKgCKgCCgC0UVAhWh0EdT8ioAioAgoAokWARWiiZb12nBFQBFQBBSB6CKgQjS6CGp+RUARUAQUgUSLgArRRMt6bbgioAgoAopAdBFQIRpdBDW/IqAIKAKKQKJFwCVE/ZyDEXQCxSdaCLXhioAioAgoAgkagUDyzU+8S4j6OQcj4ASKT9AIauUVAUVAEVAEEi0CgeSbn3iXEE206GnDFQFFQBFQBBSB0BBQIRoabppLEVAEFAFFQBHQD9BrH1AEFAFFQBFQBEJFQFeioSKn+RQBRUARUAQSPQLxLkT/97+P6cCBw7HGiAsXfqcrV65EKv+vv/6m2bM/IMTHBB0+fIzmzfswJopK9GXENG88Ab1+/QadO/ezZ7A8Kx+9wuI1MLb5ZFmW8OnGjRuR3q98igSJBsQTAvEuRAcPfo3Wr98c482fM+cDevzxpyhbtiKUPn0+Kl68Cu3d+639np9//pVefHEgnT59xg6Lzs22bTupb9/h0SkiqLzff3+SPvvs86DSJtREMc0bg8Mvv1ygOnWepXTpclOuXMUpQ4b81K/fCLp586ZJQjHFRwiYZctWE663K8UWnyA0X3ppsPAHfEqXLg/Vr9+afvvNpfDGFJ/ChTc7d+4m/MKVSpeuLvNluNYvPuvlEqJ+zsFIBQPFx2crPN69ZMly6tlzIDVuXJc75ue0Zs1iSpMmNVWr1pTOnj3vkTphPa5c+Tm1b98zYVU6TGpbo0ZTOnnyR1q48B1WqDbS8OEv05w5C2jQoFExXsMTJ36gli07E65KUUOgb99htGDBEho1apDwad68aXTkyDGqW7dl1ApKQKnHjZtK+CnFEwKB5Juf+KR2lf2cg5E0geLtguL/ZtmyVVSq1FMyCE1tFiyYQVmyFKYvvthErVs3NcF6TSQIfPfdUTp69HtavvwDKl++lLQ6W7YsdOrUaVqyZBmNGTM0kSAR3s2ECRcr+B49nqO2bZvbfLrjjjuoUaN2rASdoqxZM4d3I7R2CQ+BQPLNT7xrJRrFZjdr1oleeWVcpFxVqzamGTPmSvi//15jbX8slS1bk7JnL8qDojvt2LErUh5ngL88f/75Fz31VGVavXqdMwsdO3aCihWrRHv27Jfw69ev06OPpnFL8+CDD9ADD9xP2A8Lha5duy7tRVsyZy4k5iXzPm/lwSQ1YsTrVKRIRTFL1arVnPbtO+gtqYTt23dA2oC9ns6de1OmTAUFt4kTp9l52rXrTpMmTaerV69K2latuthx4XBj+IPVspMgqMCfXbv2SvCPP56hF17oT/nylaGCBcuLmSiQhcBfng0btkj5v/76m/O1hP128At9yvDds1/gGbzC5B0MBcOnqVNn8So0gje4ou3gWbhQOPMJpvWbN29R2rTu49c8Gz5GFctFiz6hcuVqs2k4r/SJxYuXuhVx+vRPYr3KnbsklSxZTcYuxryTwHvMYRj/mIdWrfpC5reuXfs6k7ndIw5zINJiSwl527d/wfYDwTvQP7Zs2SE/3GOMJ0RCv+rWrR/lyVNKFiz16rUizGeG3n13AdWu3YI2b94uvMiRo5hEYexhFY6xinnv+ed7Sz5gAcwNBcMjkzYuryEL0UKF8tH8+YvdJh80ePv2r3kVWFzaAEDhbFO3bg167bXBdPHiJdEmjxw57rON/vKkSJFczLIw1zpp+fI1svdUoEBeCW7evCGtXbuBtm79Sp5v3brFHXOG7H3Vrl3VmTXo++7dXxZHpNq1q0lbbt2yxDx88KB3p6ghQ0ZL2wcMeJHmzp1KyZMnoypVGhE6mje6cuWqrJQ6depFSZIkoTfeeJVKly7Og3kcvfnmO5KldetmVKlSebr77rtowIBePBhbeCsq3sJc/HGfoMCf33//g9Bn/v77ovQBKCC9enXhQdeB+8wuatq0g1cHMDQmUJ4SJYrRmTPnIu0VL1r0Ke+JZ6F77rmbChTIQ/nz52beTaR//vlXMIJgnjVrPqG/APNgKBg+VahQhnnzrBSHK3h11113BVN8nKQJZz4lTZqUmjSpRzNnvic8BSBQQMaMmURFixZkP4fsUcYIPgRduvSlBg1q0ocfvkvPPFOeOnToyb4YW6QsOB42adJBlNyBA3txf2hA77+/iPr0cVkn4IjWuHF7+uGH06xM96d27ZqzcHxd5pkzZ876rBPiVq9eT5gP2rRpxnn6yThHf//jjz8padI7pX/kzJmV8ENfwRhPiISFFfaqe/fuxvPWyzJuq1VrYiuQ2NPes+db9kMYTlWrVqSRIwdIM0ePnkT4YdxMnDhK5jcIUliOMN5AwfBIEsbHH9YCrKNHT+ASJTp+/IT10EOZra+++sbON3LkeIs1NHlmzUriN27cZsfzCtGqUKGOxZ3RDuMVqjV58oyg88ydu9BihxCLNTi7DJTJDiL2M27WrFlvPfxwDoudi6z06fNavOKxeEVkp2FBLvXbvXufHebrhoWxpGVTsJ0E769evYnFk7KE8WRspU2b244vXLiCxXtt9vPVq/9YrHRYrE3ZYc6bL7/cKe9gIeoMtoBpqlTZLe5MEg6snO9xSxyDD6H0Cbwe/GFHEIsFlV0bVh4sdhSRZ+CVNWthi51S7PjTp89ajz2Wz5oyZaaEefImmDw8KVoNG7a1y2SHHuE/C3A7jJU4q0GDNhKeN29pK1myLBZrwBYrWXYaTz7aEf/dBMsn9CuMj2D6l+c7ovJ8O/IJ/Bg16g3hD/iEcdysWUfr8uXLNjSB+GQn5JsePQZYvAp1BlnoF2wZkbCxY6fIPMFCzU6DeQv8YyVZwgYMGClpWBm007Bp2Xr00TwWr67sMM8bxKVOndPi7QQ76vz5XyzeWrLYkmeHsanawi+2KdT+UqpUNatnzwE+q4fxzgsmC5gYAnbAkFeeEgSc8cwOniaJhXGKcfjGG2/bYbjBfIG0GG+gYHgkCePwj8Ey5JVo9uxZ2VRZkPeY1tiyf8WKtbzKqCPP8IR95JGH7f0nBELLrFevhpuXrJ2Zb4LJU7duddFstm7dLllhBty9ez9rknXtorDKefHFQazZZWeza01556VLl1gb7UOXLl220zlvYE6ZOfN9tx/MhCCeCCl16lSsIZazs9x1V1Je+SxizfFFO8x5kytXDnZg+UgcJLAKu/fee+jZZxuxaTe9M1mk+2bN6ruFwTkKJqzvvjviFh6uD+DPtWvXaNOmbVJFmFhZ0RInLwTs3XuATTmlxKJg2pAhQzrCahJaqjcKJg/4j3ca/sIScd999/Hqv6Jd5NCho0VTrlWrqvSLsmVLsOY7jVcnn9ppgr1RPkVGKqb4BAsXTOIVKpTm1WMtqlGjMq8at/LqZnzkl/4XAh56jl9jSsRY/PbbQ7yancwryR8lR61aVWRliwdYzzAusTLEnit+6JMgY07E3FSxYhlKmTKFhONPliz/b+9MwKQqrj1eEU1ccBeQXSDIzgguAcMgiAgKgqAoCioqItFn5EmMezS4oxiXqEFFTIwaN+KGBnAEFaNiUNyj4C5gjCaSIBrR1Du/w6s7t3t6m55mpnvmnO/ruffWdqv+p6pOLf+600aWdXtHz+luysq6u86dO0bezZo10X4x0/ZOFLhEbljtGT9+jGJCGwRD+gFk1arVUSmwCeARBAzE7rlDDjkoOOmV1Yi45KKjePjavK8kFuXxVjouKi7TcliIb7zxlrv77ls0JZZsUxEAcJORmE71t9lm64S35hKHpajBgweo8R44sNyx/0aaLPUgKIR9qN69e+oyKoYb4Z2DBo1yZ599kbv22kvVLf6HPQv20OIyYsRQaTjluqzAsmB15Prrp+uRF47RnHTSem1sU6ZMdsOGDc6YTPv2iaQJGirCvi+DlmKXuH4wYCyltWzZXPaDdteso+NRow6sUgx0+OyzS6q445BLnH33LXeNGzfW5TU6XgZ3GHSWvhG2FWbPvstVVMxJwHHGjBt0Hwcj3rZtaw2byx/TU1WUCqEn6jltZtq0s3SpP7wFLgV8iz32KIsGZMGP68yZv9WOO+62zTaN1XhNnjxBtxMIw3I+bZnlWMhLLONXVDyl0difTxbKhKxe/am8u1eyt+zdNpG+JfWZ4xA4Vd/Rrl0bN2fO3BCkXlzZZps+/Vptr/TD8FCSZfPNN09wCtg1abJTgju4xiUXHcXD1+Z93jNRMklnxcgO40mnteeevaKOqE2bVimPk6xe/Ymjo002oKSXaxxGKRhPFPXII/MSZqE0QjagYfYFA0raEEiYgQRl4BYX9mzffffFhN/VV1+iQTBkmfY94umE+x122N7NmnWNsD+XCftzttt668buyCMn6UwohEl1Xbky8QhOqGStWrVMFbwo3Zg9YzzZi6ZejBkzItpzbNuWelG106FeoP9UkkscdM2eF/UBItH8+Yt0by2kx1nkXr16JBhQ/CZOHC8j5vXR/nkIn+1qeqqKUCH0BOkEYlHyfj+DnO7dO6dtvxUVf0xou7TlsWNHayZh9p577lS3YsULbuHCB2UwXS57k9OjIyX7CFub/mLNmveq/DgGhfBu+rlkef31N5OdqjzHZ2LBkzbQunXmVakQthSuzNghTA0Zsq+s3D0hg5YV0memXlmKl6dbt876mLzSlvwBnlx0FE+3Nu8rjWg2cmIKfwxT//59taOks4wvqZaVdVPDw+ZwXCoqnlaSR9wt3OcaZ+jQQUpSwiAuXvxcwsi0efNmQuLYVGZuie/lHbjR0KsrEGJYNn7llTcSosK6kz3ABDce6MQZObM8tOWWW+rMGUID7OAlS5ZWCR93ePzxRfFHOZKzYZRMI0YwFuvXf6Mdf0LAIno44ID9ZMn9az1OxBIrRjUI5C/Z51D/4MbyzwsvvCT1YgMxLLiHa65xeM+8eQvl94QM0hq7fv02ENxIp02b1jrgS/76DYOuDf7VqxfZ9LTJJo003bVr1+m1GP8Uo55onwy+Vqx4PwEy2tQHH3wcDdITPLM8sBQLQ7xRo0a6YjVjxoW6NEsbRcrKuuuS7rfffqeDvUAyY4snsMYhvXA8bsGCRRqHP3zx7NVXsxtRlrnjzHHaBm2gW7cuUVoQjGTPN3outZvnn39R+12IWWz10U8tXfpy1mKw1N6ixc4yyLkk6tP4QAl9a1xy0VE8fLXvU9i3hDQy+ctsLi9iEfEQYbHpBjCbwHGyCBvNgwcfokQj6dR0gx6izfbbd/DCitsQWf7GiUW5xiHypEmneUgH/foNi9IKN3IUxDdt2snLUrOXZWbZyH7NT516nuaTzW/krWoQiyARyUF9D1lIln21LMK20/TCpnmc6AAxokePci2/GF4vjFx/8823a/hAZrjzzvu07DK61fywgQ6GnTv38TfeeKvo5B1PGIgLECOCBMKK7O94yF0bS8Kmeb7pQ5CiPELrT0hCVi6UWDRu3IleDKeXvQ4lBEEAW7lytYZN1k0ucYgI7kKv13oBESQusveidUK+WOSfeeZ5JXjJeUTfpUsfJZ1BekPieuQ5Xz1RZyDAyTEkv3TpMi9HN0iu4FLf9EQfEHQ4d+580dMqD7EPEl/Tpp19aC/JesoErBwZUyLPwoWLvTC9tf+RoxRe9sM1GmQYiD7HHHOy1kkIMXIES+sLdQ+hbsnHM7RO9+07xPfs2d/LEQzVbyAWUYeo7/H2ip8c5fBDh45Rgg3tn7oP+Y42HgTCIH3Wgw8+5oUJHJwLfs23vkAskq9Gaf9HHxj/Ubdpx7R3yFJgJis/vrx8uLrJNpmWA3IQuk0W2keTJrsqARSbAQ4XXTRD49IvIrnoKDndjf0csGRJtEZGFHYV4I0YMb5Knj/77HMv1HGtMDCwqGAB0BA4bkRxyyUO4WDK8t7A6MQtCJX5zDOnacMgDD85k+jlbFgIUi0jSiRYeUcccYIqmvTo9OXsWZRecqOWEaoyAik34eXzZQnhMaoYSBklaxrBiNLQYRISh4YG65SOJS5CkFJDlMw4jIep6X2oIPmmE/Rz5ZXXV0lCPm/m99tvtLKOYV7KXpcOdELAZCOKe7Y4Ie7551+m2Am5LDhFV9z69TtQB3LgC8sZnQr1PgqTrMea6OmGG2bpwIt3xZml0csKcFMf9SSzNmXwYzTBjoE3dZ0BaZBkPQX3VFf0y2CGukZ6MMFl5uPDwIk4GAHhTER1AwNJW4wL4RmAyXEMHWzJsQtPW2RghtBOGdhPmHByFA0jeuKJp3nZe1fjwPv79BmiRigKJDcMFmCOU+Y4qz8ephD3+dYXjCh5T/Xj5AHCwD7ojMEpWBE+9PnpjChxGTgwIYOJz+CaUwzERS9BctFRCFsb14BljY0oFZSRQ9ygJBeAyhenhif7p3rOJ06qdKiczAQLJeSLRp6r0HkyMEglsrQYOQcjGo7hEIfZTDphZCxLXOm8a+weKki+CQk71m+3XXsvZzHTJgE2dETVkXziJKfPcSFGtrnODmuiJ94dOpnkfBTiuT7rCdzRU6Hwo+1mm+UJi9/Hj7oEHQnT1z/wwKM+XhdonwyOzzij8nhd3J+4wYhyT/h0fQH+CGGS09jgU5i/Na0v2XJB3mUJPOHYWKY49GPgGlYYQlgGr9tu2y6l3UinoxC3tq4By7zZuaJsPZLC1zX4mggko3TC+nicGp4uXNw9nzjx+OE+UNXDc02v5IvjLrkKe6L8Ugl7NOlkxx0zv4N9m8A8TZdGXbizD8xRFVjQEMBat05PiEqHS6Z85xMnOb0ttthcqfjJ7umea6In0uR4U7FJKegJ3AM7vRD40XaTv1iVnO5WW1VllBKGLynJcq98cWfD8agvv1znpPMX3sOahD3/THUFrka2dk2YUhbKDy8lV6EfmzPnESfncuUjDKfIfuouyieBTQ/WqexGOh3l+s5Ch6skFlUzZRlRSSd5vLCwvtCvgFBBTfJHgIrBV3WK6cs2+ZSG83x8tpCvA11xxQX5JFHUcUxPRa2ejZa5rl07Canofj2HzABx+vTrdHA0f/690fG6VC/nKFQ61nmq8A3RbebMq+QLUuP0XP3kyT9TpvzEiUfpEcVSwON7TH2XL39PPzlVChm2PNYOAlYnagfnmr7F9FRTBBtWfKsvhdN3wDLvmWjhsmIpGQKGgCFgCBgCpYlApRHNdA6GsmXzL83yW64NAUPAEDAEGjoC2exbBv9KI5rtn1hk82/oSrDyGwKGgCFgCJQmAtnsWwb/SiNamkW3XBsChoAhYAgYAnWGgBnROoPeXmwIGAKGgCFQ6giYES11DVr+DQFDwBAwBOoMATOidQa9vdgQMAQMAUOg1BEwI1rqGrT8GwKGgCFgCNQZAmZE6wx6e7EhYAgYAoZAqSNQaUQznIPRQmbzL3UkLP+GgCFgCBgCDROBbPYtg3+lEc1wDkZRzebfMKG3UhsChoAhYAiUOgLZ7FsG/0ojWuogWP4NAUPAEDAEDIFaRsCMaC0Dbq8zBAwBQ8AQqD8ImBGtP7q0khgChoAhYAjUMgLRv0Kr5ffa6wwBQ8AQMAQMgZJGoGPHdi76T9o8mBgCAYHwv/LCs12LEwHTU3HqpVhzZfWlcJoBS8SWcwuHqaVkCBgChoAh0MAQqDSiGc7BKCbZ/BsYcFZcQ8AQMAQMgXqCQDb7lsG/0ohmOAejMGXzrydYWjEMAUPAEDAEGhgC2exbBv9KI9rAMLPiGgKGgCFgCBgCNUXAjGhNEbT4hoAhYAgYAg0WATOiDVb1VnBDwBAwBAyBmiJgRrSmCFp8Q8AQMAQMgQaLgBnRBqt6K7ghYAgYAoZATREwI1pTBC2+IWAIGAKGQINFoNKIZjgHo+hk82+wEFrBDQFDwBAwBEoagWz2LYN/pRHNcA5GwcnmX9IIWuYNAUPAEDAEGiwC2exbBv9KI9pg0bOCGwKGgCFgCBgC+SFgRjQ/3CyWIWAIGAKGgCFgH6C3OmAIGAKGgCFgCOSLgM1E80XO4hkChoAhYAg0eATq3Ij+4Q9z3Guv/XWjKeKzz/7h1q1bt9HST5fwX/+63N1++z3pvM09AwJr1vzL3XrrnQ7dbQxZv/5bt3r13zZG0g0qzY2tJ++96unbb79tULhaYUsLgTo3oueee4l74omnCo7a7Nl3ul133cu1b9/btWjR3f3oR/u7ZcteLfh70iX4zDNL3OmnX5DOu2DudGQPPfQnx7W+yN/+9nc3ZcrZ7qOPPi5okT799DM3YsQ417x5F9ep049cq1Y93M9//kv33XffFfQ96RJ79NEF7p133kvnXXLuG0tPGM3TTjtX9YOemjfv6kaNOtp9/vnGGVQVI/BLlrzo+BWL/PjHB2ibTJWfF154yW2zzS7ulVfeSOVd790qjWiGczCKQjb/IoLqvvsedqeeerYbM2akVMQFbt68e13Tpju5oUMPd6tWfVJEOa15Vt599303fvxkx9UkMwIHHni4e++9D91dd90sA6pF7oILznCzZ9/hzjnn4swRC+R73HGnurlzFxQotfqbzOmnn+/uuOM+d/HF56iebr/9RvfWW8vdyJHj62+hk0p2xRW/dvxMagmBbPYtg/+mURYznIPRMNn8o4Tq/uahhx5ze++9lzbCkJs77pjpdtmll3v88Sfd0UcfHpzt2kAQePPNt93bb7/jHn74TrfPPntrqdu338V98MFH7r77HnKXXfaLBoJEcReTJVxWVn7600luwoQjIj1tsskm7tBDj5VB0AeuXbu2xV0Iy13pIZDNvmXwr5yJVrPYY8ee4KZNu6JKrCFDxriZM29T9//85xsZ7V/uysuHuQ4ddpdG8T/uuef+UiVO3CFTnC++WOP22muw+9OfKuJR3PLl77o99hjkXnrpFXVfv36923nnpglhGjfeym211ZaO/TDkrLMudMxMvvlmfRTullt+7wYMGJnT0ijxKD9la9t2N11uCu+PEozdsET1y19Od717D9RlquHDj3Avv/x6LETi7csvv6ZlYm918uSprk2bMn3Xr351YxTw17++RWahP9FnrmDw1VdfRf61fRP0kzzbwlCRt7/8ZZlm6cMPP3annHKm6969nysr20eXibKtEGSKs3Dh05r+3//+eUKR2W9HP9SpoPfkesEzuqHzRqcHHXSkO+OMaQnp/OQnP3MTJ05JcIs/sFXw8MPz3JVXXu86d+7junbd2/3sZ+dH9ejZZ1+IdHP11b/R+6effi6eRK3eF7OeWFr/7rv/umbNEttveEaP+eopDvLdd//R9e9/kCwVd9M6cu+9D8a9ZSthpa5mdenS1/XtO1TbbryvIDBtlD6N9k+/9Nhjj2t/d9JJpyekFX/Ajz6RsNQb4h533CkRL4R30FaoH/y4p86Ukixa9ExU3+P5PuaYkxNm1//4xz912Z72Qrth5k07Ape4LF78vDvqqJ/oJGjYsLHud7+7O+5d9/fSefi3336XS7Xk0kuv9h077un/+9//RvFkz9FvvXVbL2vj6nb88ad62ZP0Ao6XDs2PHn2Mb9myuxfDEMUR4+qvuWZm9JwtjoDoCROXGTNu8D/84R5eOkN1fvDBx7zso3iphPosDdMTBjfZx1G3jz9e5Vu06KZ5w+GTTz7V55tvvl39s/054YT/9dIA/OWXX+t///t7/YgR433Tpp39a6+9qVHFIPtmzbpEyZx55jRPWe+55wG/YMEif+SRkzT8P//5RRQmfvPnPy9RLPv1G+bFiPp7733In3HGL/2227bz1157kwZ99dU3vXTcGo6rLGN7GUDEk8n7Pp86wcvQz4QJJye897rrbvbt2vXSvMnerd9zz/287LF4MJo587deOiDfr9+B/ssvv9R4b721Qsv04osv63O2OEIcU6xvu+2uhPcefPBR/uijT4rc9t57qD5/9dXX6ibG3e+22wB/3nmXRmHmzp3vZX/Hi+FTt3nznvA77NDBg3U62W679pL/YX7o0DFeliFVJ9T7ww47XtsHdQvd7LRTRy/GWO9l0JAuuWq510c9CZdA68hHH61SLNDv2LET/YABIyJs8tFTiEzc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"}}},{"cell_type":"code","source":"model = YOLO(\"yolov8m.pt\")","metadata":{"execution":{"iopub.status.busy":"2024-01-27T15:55:05.719964Z","iopub.execute_input":"2024-01-27T15:55:05.720527Z","iopub.status.idle":"2024-01-27T15:55:06.580697Z","shell.execute_reply.started":"2024-01-27T15:55:05.720493Z","shell.execute_reply":"2024-01-27T15:55:06.579552Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"![](https://storage.googleapis.com/kagglesdsdata/datasets/4348994/7472080/Group5.png?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=databundle-worker-v2%40kaggle-161607.iam.gserviceaccount.com%2F20240124%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20240124T164518Z&X-Goog-Expires=345600&X-Goog-SignedHeaders=host&X-Goog-Signature=a94440ad449d65faa85308f51720702ded233d37f2228daa83dbb38ad434eb1e7a85739fc0be97e5799abeab5721a430fe8c3116cb6face24710c34582ecb65a762571761a01f24c37ab54cf1413b8a72d695b8864320df63976c510e0af9295e2ee5e4803199626a3e4ddf5ef98e711e2b29636ed3f2e846bd516a07561caf7ca3ce1e571794546652c8bdae2a0ac889a2867c2928816e6c79d90b9034b23bdce62d418ad53818f3955553fdea9ae3be3846f3437f51809bfcab3309095f9e878577d76b346c98f1123a3609b30bce452593198e75cb9fd16dc6f0c26c4261de5a3cb4bad5f3837f33362f5f8035be4a23ee3f088b40c0ca78d3da0a1d7a17c)","metadata":{}},{"cell_type":"code","source":"import cv2\nimport matplotlib.pyplot as plt\n\n# Read the image using OpenCV\nimage_path = '/kaggle/input/cat-dog-image/cat_dog.jpg'\nimage = cv2.imread(image_path)\n\nheight , width , _ = image.shape\nprint((height,width))\n# OpenCV reads images in BGR format, convert it to RGB\nimage_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n\n# Create a Matplotlib figure and axes\nfig, ax = plt.subplots()\n\n# Display the image with axes\nax.imshow(image_rgb)\n\n# Customize the plot (optional)\nax.set_title('Cat Dog Image')\nax.set_xlabel('X-axis Label')\nax.set_ylabel('Y-axis Label')\n\n# Show the plot\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2024-01-24T19:53:49.606144Z","iopub.execute_input":"2024-01-24T19:53:49.606556Z","iopub.status.idle":"2024-01-24T19:53:49.986300Z","shell.execute_reply.started":"2024-01-24T19:53:49.606525Z","shell.execute_reply":"2024-01-24T19:53:49.985343Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**The predict method accepts many different input types, including a path to a single image, an array of paths to images**","metadata":{}},{"cell_type":"code","source":"results = model.predict(\"/kaggle/input/cat-dog-image/cat_dog.jpg\")\nresults","metadata":{"execution":{"iopub.status.busy":"2024-01-27T15:58:24.265990Z","iopub.execute_input":"2024-01-27T15:58:24.266874Z","iopub.status.idle":"2024-01-27T15:58:26.066387Z","shell.execute_reply.started":"2024-01-27T15:58:24.266841Z","shell.execute_reply":"2024-01-27T15:58:26.065362Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"type(results)","metadata":{"execution":{"iopub.status.busy":"2024-01-27T15:58:26.068385Z","iopub.execute_input":"2024-01-27T15:58:26.069155Z","iopub.status.idle":"2024-01-27T15:58:26.075628Z","shell.execute_reply.started":"2024-01-27T15:58:26.069112Z","shell.execute_reply":"2024-01-27T15:58:26.074468Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(results)","metadata":{"execution":{"iopub.status.busy":"2024-01-27T15:58:26.256362Z","iopub.execute_input":"2024-01-27T15:58:26.257011Z","iopub.status.idle":"2024-01-27T15:58:26.263383Z","shell.execute_reply.started":"2024-01-27T15:58:26.256978Z","shell.execute_reply":"2024-01-27T15:58:26.262279Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**An array of results for each input image. As we provided only a single image, it returns an array with a single item** ","metadata":{}},{"cell_type":"code","source":"result = results[0]","metadata":{"execution":{"iopub.status.busy":"2024-01-27T15:58:28.986863Z","iopub.execute_input":"2024-01-27T15:58:28.987818Z","iopub.status.idle":"2024-01-27T15:58:28.992430Z","shell.execute_reply.started":"2024-01-27T15:58:28.987780Z","shell.execute_reply":"2024-01-27T15:58:28.991365Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"result","metadata":{"execution":{"iopub.status.busy":"2024-01-27T15:58:29.457358Z","iopub.execute_input":"2024-01-27T15:58:29.457777Z","iopub.status.idle":"2024-01-27T15:58:29.466009Z","shell.execute_reply.started":"2024-01-27T15:58:29.457747Z","shell.execute_reply":"2024-01-27T15:58:29.464908Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"type(result)","metadata":{"execution":{"iopub.status.busy":"2024-01-24T16:29:23.644370Z","iopub.execute_input":"2024-01-24T16:29:23.644741Z","iopub.status.idle":"2024-01-24T16:29:23.650454Z","shell.execute_reply.started":"2024-01-24T16:29:23.644711Z","shell.execute_reply":"2024-01-24T16:29:23.649587Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Boxes array with information about detected bounding boxes on the image","metadata":{"execution":{"iopub.status.busy":"2024-01-24T16:32:00.930386Z","iopub.execute_input":"2024-01-24T16:32:00.931271Z","iopub.status.idle":"2024-01-24T16:32:00.937278Z","shell.execute_reply.started":"2024-01-24T16:32:00.931228Z","shell.execute_reply":"2024-01-24T16:32:00.936125Z"}}},{"cell_type":"code","source":"result.boxes","metadata":{"execution":{"iopub.status.busy":"2024-01-24T16:32:16.422302Z","iopub.execute_input":"2024-01-24T16:32:16.422674Z","iopub.status.idle":"2024-01-24T16:32:16.501746Z","shell.execute_reply.started":"2024-01-24T16:32:16.422642Z","shell.execute_reply":"2024-01-24T16:32:16.500837Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Got 2 objects, which means that there are two boxes detected: one for the dog and one for the cat.","metadata":{}},{"cell_type":"code","source":"len(result.boxes)","metadata":{"execution":{"iopub.status.busy":"2024-01-24T16:47:56.255090Z","iopub.execute_input":"2024-01-24T16:47:56.255441Z","iopub.status.idle":"2024-01-24T16:47:56.262633Z","shell.execute_reply.started":"2024-01-24T16:47:56.255415Z","shell.execute_reply":"2024-01-24T16:47:56.261638Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"box = result.boxes[1]","metadata":{"execution":{"iopub.status.busy":"2024-01-24T16:47:57.040605Z","iopub.execute_input":"2024-01-24T16:47:57.040942Z","iopub.status.idle":"2024-01-24T16:47:57.046993Z","shell.execute_reply.started":"2024-01-24T16:47:57.040914Z","shell.execute_reply":"2024-01-24T16:47:57.045935Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"![](https://storage.googleapis.com/kagglesdsdata/datasets/4348994/7472080/Group6.png?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=databundle-worker-v2%40kaggle-161607.iam.gserviceaccount.com%2F20240124%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20240124T164622Z&X-Goog-Expires=345600&X-Goog-SignedHeaders=host&X-Goog-Signature=4c6b9cee8809eb9f8a0ab4f6348dd2d0dc77cd82296234c920518187396aad7f9f7ca198c8745b3f99fc6df8cb0537cc7899de7dbf34c19b5a36a1898fb9b9eae5c5087b568efebc11c4c3aabc906aafd68c33c5e6d5502b083f602c5e74de64cb3893cce15353fb4c986d93718c22f86ed00a9488ae0d60cd5ed54550abe6466b7085d1b99776e9e9f314238c7ac27ac8d8bedcbcca55a615cb19c1a42976fdef97c6e716aa7e60ec0b11249086db5529cd34ce2240034650f21d03afcd30f80123d24c1a890787cdf94c37ce480ddab1b983b1c49d4edbce2a7e4a109c81104a9217b55dada5cdbbb87a184f302ddd2b5d62ce60820cc998699b858f80f0e0)","metadata":{}},{"cell_type":"markdown","source":"The `box` object contains the properties of the bounding box, including:\n\n- `xyxy` – the coordinates of the box as an array `[x1, y1, x2, y2]`\n- `cls` – the ID of the object type\n- `conf` – the confidence level of the model about this object. If it's very low, like `< 0.5`, then you can just ignore the box.\n","metadata":{}},{"cell_type":"code","source":"print(\"Object type:\", box.cls)\nprint(\"Coordinates:\", box.xyxy)\nprint(\"Probability:\", box.conf)","metadata":{"execution":{"iopub.status.busy":"2024-01-24T16:47:59.706614Z","iopub.execute_input":"2024-01-24T16:47:59.707331Z","iopub.status.idle":"2024-01-24T16:47:59.715358Z","shell.execute_reply.started":"2024-01-24T16:47:59.707301Z","shell.execute_reply":"2024-01-24T16:47:59.714394Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The outputs from the PyTorch models are encoded as an array of PyTorch Tensor objects, so you need to extract the first item from each of these arrays:","metadata":{}},{"cell_type":"code","source":"print(\"Object type:\",box.cls[0])\nprint(\"Coordinates:\",box.xyxy[0])\nprint(\"Probability:\",box.conf[0])","metadata":{"execution":{"iopub.status.busy":"2024-01-24T12:57:16.232231Z","iopub.execute_input":"2024-01-24T12:57:16.232919Z","iopub.status.idle":"2024-01-24T12:57:16.240970Z","shell.execute_reply.started":"2024-01-24T12:57:16.232886Z","shell.execute_reply":"2024-01-24T12:57:16.239918Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**To unpack actual values from Tensor, you need to use the .tolist() method for tensors with array inside, as well as the .item() method for tensors with scalar values**","metadata":{}},{"cell_type":"code","source":"cords = box.xyxy[0].tolist()\nclass_id = box.cls[0].item()\nconf = box.conf[0].item()\nprint(\"Object type:\", class_id)\nprint(\"Coordinates:\", cords)\nprint(\"Probability:\", conf)","metadata":{"execution":{"iopub.status.busy":"2024-01-24T12:57:32.966465Z","iopub.execute_input":"2024-01-24T12:57:32.966821Z","iopub.status.idle":"2024-01-24T12:57:32.972993Z","shell.execute_reply.started":"2024-01-24T12:57:32.966796Z","shell.execute_reply":"2024-01-24T12:57:32.972101Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"In case of a YOLOv8 pretrained model, there are 80 object types with IDs from 0 to 79","metadata":{}},{"cell_type":"code","source":"print(result.names)","metadata":{"execution":{"iopub.status.busy":"2024-01-24T12:57:50.042215Z","iopub.execute_input":"2024-01-24T12:57:50.043050Z","iopub.status.idle":"2024-01-24T12:57:50.047592Z","shell.execute_reply.started":"2024-01-24T12:57:50.043012Z","shell.execute_reply":"2024-01-24T12:57:50.046633Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Print one object","metadata":{}},{"cell_type":"code","source":"cords = box.xyxy[0].tolist()\ncords = [round(x) for x in cords]\nclass_id = result.names[box.cls[0].item()]\nconf = round(box.conf[0].item(), 2)\nprint(\"Object type:\", class_id)\nprint(\"Coordinates:\", cords)\nprint(\"Probability:\", conf)","metadata":{"execution":{"iopub.status.busy":"2024-01-24T16:51:27.065694Z","iopub.execute_input":"2024-01-24T16:51:27.066433Z","iopub.status.idle":"2024-01-24T16:51:27.073351Z","shell.execute_reply.started":"2024-01-24T16:51:27.066400Z","shell.execute_reply":"2024-01-24T16:51:27.072371Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Print All Objects","metadata":{}},{"cell_type":"code","source":"for box in result.boxes:\n  class_id = result.names[box.cls[0].item()]\n  cords = box.xyxy[0].tolist()\n  cords = [round(x) for x in cords]\n  conf = round(box.conf[0].item(), 2)\n  print(\"Object type:\", class_id)\n  print(\"Coordinates:\", cords)\n  print(\"Probability:\", conf)\n  print(\"---\")","metadata":{"execution":{"iopub.status.busy":"2024-01-24T16:51:30.785936Z","iopub.execute_input":"2024-01-24T16:51:30.786314Z","iopub.status.idle":"2024-01-24T16:51:30.798403Z","shell.execute_reply.started":"2024-01-24T16:51:30.786282Z","shell.execute_reply":"2024-01-24T16:51:30.797511Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Visualize All Objects","metadata":{}},{"cell_type":"code","source":"import cv2\n\n# Read the image using OpenCV\nimage_path = '/kaggle/input/cat-dog-image/cat_dog.jpg'\nimage = cv2.imread(image_path)\nimage = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\nfor result in results:\n    boxes = result.boxes.cpu().numpy()\n    xyxys = boxes.xyxy\n    \n    for xyxy in xyxys:\n        x1 = int(xyxy[0])\n        y1 = int(xyxy[1])\n        x2 = int(xyxy[2])\n        y2 = int(xyxy[3])\n\n        cv2.rectangle(image,(x1,y1),(x2,y2),(0,255,0),2)\n\nplt.imshow(image)\nplt.axis('off')  # Turn off axis labels\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2024-01-24T17:42:05.232967Z","iopub.execute_input":"2024-01-24T17:42:05.233885Z","iopub.status.idle":"2024-01-24T17:42:05.536048Z","shell.execute_reply.started":"2024-01-24T17:42:05.233851Z","shell.execute_reply":"2024-01-24T17:42:05.534965Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## X_Center Y_Center Width Height\n![](https://www.freecodecamp.org/news/content/images/2023/04/bounding_box.png)","metadata":{}},{"cell_type":"code","source":"for box in result.boxes:\n  class_id = result.names[box.cls[0].item()]\n  cords = box.xywh[0].tolist()\n  cords = [round(x) for x in cords]\n  conf = round(box.conf[0].item(), 2)\n  print(\"Object type:\", class_id)\n  print(\"Coordinates:\", cords)\n  print(\"Probability:\", conf)\n  print(\"---\")","metadata":{"execution":{"iopub.status.busy":"2024-01-24T17:48:04.922223Z","iopub.execute_input":"2024-01-24T17:48:04.922906Z","iopub.status.idle":"2024-01-24T17:48:04.933056Z","shell.execute_reply.started":"2024-01-24T17:48:04.922869Z","shell.execute_reply":"2024-01-24T17:48:04.932051Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import cv2\n\n# Read the image using OpenCV\nimage_path = '/kaggle/input/cat-dog-image/cat_dog.jpg'\nimage = cv2.imread(image_path)\nimage = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\nfor result in results:\n    boxes = result.boxes.cpu().numpy()\n    xyxys = boxes.xywh\n    \n    for xyxy in xyxys:\n        x_center = xyxy[0]\n        y_center = xyxy[1]\n        width = xyxy[2]\n        height = xyxy[3]\n        \n        x1 = int(x_center - width / 2)\n        y1 = int(y_center - height /2)\n        x2 = int(x_center + width / 2)\n        y2 = int(y_center + height / 2)\n        \n        cv2.rectangle(image,(x1,y1),(x2,y2),(0,255,0),2)\n\nplt.imshow(image)\nplt.axis('off')  # Turn off axis labels\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-01-24T18:14:03.352115Z","iopub.execute_input":"2024-01-24T18:14:03.352986Z","iopub.status.idle":"2024-01-24T18:14:03.570567Z","shell.execute_reply.started":"2024-01-24T18:14:03.352955Z","shell.execute_reply":"2024-01-24T18:14:03.569701Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Splitting into Train and Val","metadata":{}},{"cell_type":"code","source":"import os\nimport shutil\nfrom sklearn.model_selection import train_test_split\nfrom tqdm import tqdm\n\ndef copy_data(images_path, labels_path, destination_path, train_ratio=0.8, random_seed=42):\n    # Create new directories for train and val in the destination path\n    train_dir = os.path.join(destination_path, 'train')\n    val_dir = os.path.join(destination_path, 'val')\n    os.makedirs(train_dir, exist_ok=True)\n    os.makedirs(val_dir, exist_ok=True)\n\n    # Create subdirectories for 'images' and 'labels' within 'train' and 'val'\n    train_images_dir = os.path.join(train_dir, 'images')\n    train_labels_dir = os.path.join(train_dir, 'labels')\n    val_images_dir = os.path.join(val_dir, 'images')\n    val_labels_dir = os.path.join(val_dir, 'labels')\n    os.makedirs(train_images_dir, exist_ok=True)\n    os.makedirs(train_labels_dir, exist_ok=True)\n    os.makedirs(val_images_dir, exist_ok=True)\n    os.makedirs(val_labels_dir, exist_ok=True)\n\n    # List all image and label files\n    image_files = os.listdir(os.path.join(images_path, 'train'))\n    label_files = os.listdir(os.path.join(labels_path, 'train'))\n\n    # Split files into train and val\n    image_train, image_val, label_train, label_val = train_test_split(\n        image_files, label_files, test_size=(1 - train_ratio), random_state=random_seed\n    )\n\n    # Copy images and labels to 'images' and 'labels' folders in train\n    for image_file in tqdm(image_train, desc='Copying train images'):\n        shutil.copy2(os.path.join(images_path, 'train', image_file), os.path.join(train_images_dir, image_file))\n    for label_file in tqdm(label_train, desc='Copying train labels'):\n        shutil.copy2(os.path.join(labels_path, 'train', label_file), os.path.join(train_labels_dir, label_file))\n\n    # Copy remaining images and labels to 'images' and 'labels' folders in val\n    for image_file in tqdm(image_val, desc='Copying val images'):\n        shutil.copy2(os.path.join(images_path, 'train', image_file), os.path.join(val_images_dir, image_file))\n    for label_file in tqdm(label_val, desc='Copying val labels'):\n        shutil.copy2(os.path.join(labels_path, 'train', label_file), os.path.join(val_labels_dir, label_file))\n\nif __name__ == \"__main__\":\n    # Replace 'path/to/your/images', 'path/to/your/labels', and 'path/to/your/destination' with the actual paths\n    images_folder = '/kaggle/input/dl-enigma-10-sust-cse-carnival-2024/dlenigma1/BadODD/images'\n    labels_folder = '/kaggle/input/dl-enigma-10-sust-cse-carnival-2024/dlenigma1/BadODD/labels'\n    destination_folder = '/kaggle/working/'\n\n    copy_data(images_folder, labels_folder, destination_folder)\n","metadata":{"execution":{"iopub.status.busy":"2024-01-28T07:41:12.543544Z","iopub.execute_input":"2024-01-28T07:41:12.543905Z","iopub.status.idle":"2024-01-28T07:41:30.248165Z","shell.execute_reply.started":"2024-01-28T07:41:12.543878Z","shell.execute_reply":"2024-01-28T07:41:30.247202Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport matplotlib.pyplot as plt\n\n# Define the paths to the image folders\ntrain_path = \"/kaggle/working/train/images\"\nval_path = \"/kaggle/working/val/images\"\n\n# Function to count the number of images in a folder\ndef count_images(folder_path):\n    return len([f for f in os.listdir(folder_path) if os.path.isfile(os.path.join(folder_path, f))])\n\n# Count the number of images in each folder\ntrain_images_count = count_images(train_path)\nval_images_count = count_images(val_path)\n\n# Bar plot\nfolders = ['Train', 'Validation']\nimage_counts = [train_images_count, val_images_count]\n\nplt.bar(folders, image_counts, color=['blue', 'orange'])\nplt.xlabel('Folders')\nplt.ylabel('Number of Images')\nplt.title('Number of Images in Train and Validation Folders')\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2024-01-28T07:44:05.060962Z","iopub.execute_input":"2024-01-28T07:44:05.061299Z","iopub.status.idle":"2024-01-28T07:44:05.282282Z","shell.execute_reply.started":"2024-01-28T07:44:05.061274Z","shell.execute_reply":"2024-01-28T07:44:05.281199Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport random\nimport cv2\nimport matplotlib.pyplot as plt\nfrom matplotlib.patches import Rectangle\n\ndef read_labels(label_file_path):\n    with open(label_file_path, 'r') as file:\n        lines = file.readlines()\n\n    annotations = []\n    for line in lines:\n        parts = line.strip().split()\n        class_id = int(parts[0])\n        confidence_score = float(parts[1])\n        center_x, center_y, center_width, center_height = map(float, parts[1:])\n        annotations.append({'class_id': class_id,\n                            'center_x': center_x, 'center_y': center_y,\n                            'center_width': center_width, 'center_height': center_height})\n\n    return annotations\n\ndef get_bounding_box_coordinates(image_width, image_height, x_center, y_center, width, height):\n    # Calculate the coordinates of the bounding box\n    x_center_pixel = x_center * image_width\n    y_center_pixel = y_center * image_height\n    half_width = width * image_width / 2\n    half_height = height * image_height / 2\n\n    # Calculate the coordinates of the bounding box\n    xmin = int(x_center_pixel - half_width)\n    ymin = int(y_center_pixel - half_height)\n    xmax = int(x_center_pixel + half_width)\n    ymax = int(y_center_pixel + half_height)\n\n    return xmin, ymin, xmax, ymax\n\ndef plot_image_with_boxes(image_path, labels):\n    image = cv2.imread(image_path)\n    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n\n    fig, ax = plt.subplots(1)\n    ax.imshow(image)\n\n    for label in labels:\n        class_id = label['class_id']\n        center_x, center_y, center_width, center_height = label['center_x'], label['center_y'], label['center_width'], label['center_height']\n\n        # Calculate bounding box using center coordinates\n        xmin, ymin, xmax, ymax = get_bounding_box_coordinates(image.shape[1], image.shape[0], center_x, center_y, center_width, center_height)\n\n        rect = Rectangle((xmin, ymin), xmax - xmin, ymax - ymin, linewidth=1, edgecolor='r', facecolor='none')\n        ax.add_patch(rect)\n        ax.text(xmin, ymin, f'Class: {class_id}', color='r', verticalalignment='bottom')\n\n    plt.show()\n\n# Example usage to choose a random image and its label\nlabel_folder = \"/kaggle/input/dl-enigma-10-sust-cse-carnival-2024/dlenigma1/BadODD/labels/train\"\nimage_folder = \"/kaggle/input/dl-enigma-10-sust-cse-carnival-2024/dlenigma1/BadODD/images/train\"\n\n# Get a list of all label files\nlabel_files = [file for file in os.listdir(label_folder) if file.endswith('.txt')]\n\n# Choose a random label file\nrandom_label_file = random.choice(label_files)\n\n# Form the paths for the image and label\nimage_file = random_label_file.replace('.txt', '.jpg')\nimage_path = os.path.join(image_folder, image_file)\nlabel_path = os.path.join(label_folder, random_label_file)\n\n# Read labels and plot the image with bounding boxes\nlabels = read_labels(label_path)\nprint(labels)\nplot_image_with_boxes(image_path, labels)\n\n\n\n","metadata":{"execution":{"iopub.status.busy":"2024-01-28T09:26:39.096433Z","iopub.execute_input":"2024-01-28T09:26:39.096798Z","iopub.status.idle":"2024-01-28T09:26:39.632178Z","shell.execute_reply.started":"2024-01-28T09:26:39.096768Z","shell.execute_reply":"2024-01-28T09:26:39.631521Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def read_labels(label_file_path):\n    with open(label_file_path, 'r') as file:\n        lines = file.readlines()\n\n    annotations = []\n    for line in lines:\n        parts = line.strip().split()\n#         return parts\n        if len(parts) < 5:\n            # Handle cases where there might be fewer values in a line\n            print(f\"Skipping line with insufficient values: {line}\")\n            continue\n\n        class_id = int(parts[0])\n#         return class_id\n        x1 = float(parts[1])\n        y1 = float(parts[2])\n        width=float(parts[3])\n        height=float(parts[4])\n        annotations.append({'class_id': class_id,\n                            'x1': x1, 'y1': y1, 'width': width, 'height': height})\n\n    return annotations\n","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_path=\"/kaggle/input/dl-enigma-10-sust-cse-carnival-2024/dlenigma1/BadODD/images/train/chittagong_bohoddarhat1_10030.jpg\"\nimage=cv2.imread(image_path)\nheight,width,_=image.shape\nprint((height,width))\nimage_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n\n# Create a Matplotlib figure and axes\nfig, ax = plt.subplots()\n\n# Display the image with axes\nax.imshow(image_rgb)\n\n# Customize the plot (optional)\nax.set_title('BadODD Image')\nax.set_xlabel('X-axis Label')\nax.set_ylabel('Y-axis Label')\n\n# Show the plot\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-01-28T09:06:19.158113Z","iopub.execute_input":"2024-01-28T09:06:19.158528Z","iopub.status.idle":"2024-01-28T09:06:19.677795Z","shell.execute_reply.started":"2024-01-28T09:06:19.158493Z","shell.execute_reply":"2024-01-28T09:06:19.676388Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\n\n# Define the class ID to name mapping\nclass_id_to_name = {\n    0: 'auto_rickshaw',\n    1: 'bicycle',\n    2: 'bus',\n    3: 'car',\n    4: 'cart_vehicle',\n    5: 'construction_vehicle',\n    6: 'motorbike',\n    7: 'person',\n    8: 'priority_vehicle',\n    9: 'three_wheeler',\n    10: 'train',\n    11: 'truck',\n    12: 'wheelchair'\n}\n\n# Define the label folder path\nlabel_folder = \"/kaggle/input/dl-enigma-10-sust-cse-carnival-2024/dlenigma1/BadODD/labels/train\"\n\n# Initialize a dictionary to store class counts\nclass_counts = {class_id: 0 for class_id in class_id_to_name}\n\n# Iterate through each text file in the label folder\nfor filename in os.listdir(label_folder):\n    if filename.endswith(\".txt\"):\n        file_path = os.path.join(label_folder, filename)\n        \n        # Read the content of the label file and count class occurrences\n        with open(file_path, 'r') as file:\n            lines = file.readlines()\n\n        for line in lines:\n            parts = line.strip().split()\n            if parts:  # Check if the line is not empty\n                class_id = int(parts[0])\n                if class_id in class_counts:\n                    class_counts[class_id] += 1\n\n# Print the class counts\nfor class_id, count in class_counts.items():\n    class_name = class_id_to_name[class_id]\n    print(f'Class {class_id} ({class_name}): {count} instances')\n","metadata":{"execution":{"iopub.status.busy":"2024-01-28T08:41:59.808131Z","iopub.execute_input":"2024-01-28T08:41:59.808512Z","iopub.status.idle":"2024-01-28T08:42:23.728205Z","shell.execute_reply.started":"2024-01-28T08:41:59.808484Z","shell.execute_reply":"2024-01-28T08:42:23.727286Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\n# Create a bar plot\nclass_ids = list(class_counts.keys())\n# print(class_ids)\nclass_names = [class_id_to_name[class_id] for class_id in class_ids]\ncounts = list(class_counts.values())\ncolors = plt.cm.viridis(np.linspace(0, 1, len(class_ids)))\n\nplt.bar(class_names, counts, color=colors)\nplt.xlabel('Class')\nplt.ylabel('Number of Instances')\nplt.title('Number of Instances in Each Class')\nplt.xticks(rotation=45, ha=\"right\")  # Rotate x-axis labels for better visibility\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-01-28T08:48:27.606409Z","iopub.execute_input":"2024-01-28T08:48:27.606889Z","iopub.status.idle":"2024-01-28T08:48:28.071165Z","shell.execute_reply.started":"2024-01-28T08:48:27.606848Z","shell.execute_reply":"2024-01-28T08:48:28.069856Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import cv2\n#Load the predicted test image\n# Example usage to choose a random image and its label\nlabel_folder = \"/kaggle/input/dl-enigma-10-sust-cse-carnival-2024/dlenigma1/BadODD/labels/train\"\nimage_folder = \"/kaggle/input/dl-enigma-10-sust-cse-carnival-2024/dlenigma1/BadODD/images/train\"\n\n# Get a list of all label files\nlabel_files = [file for file in os.listdir(label_folder) if file.endswith('.txt')]\n\n# Choose a random label file\nrandom_label_file = random.choice(label_files)\n\n# Form the paths for the image and label\nimage_file = random_label_file.replace('.txt', '.jpg')\nimage_path = os.path.join(image_folder, image_file)\nlabel_path = os.path.join(label_folder, random_label_file)\nprint(image_path,label_path)\n\n\nimage_path = image_path\nimage = cv2.imread(image_path)\n# Specify the path to the text file prediction ([label, x_center, y_center, width, height])\ntxt_file_path = label_path\nwith open(txt_file_path, 'r') as file:\n    lines=file.readlines()\nfor i, line in enumerate(lines):\n#Split the line into its components\n    parts=line.split()\n    if len(parts) == 5:\n        class_id, center_x, center_y, width, height = map(float, parts)\n        #yolov7 was training with image size of 640x640\n#         print(width,height)\n        img_width = 640\n        img_height = 640\n        xmin, ymin, xmax, ymax = get_bounding_box_coordinates(img_width, img_height,center_x, center_y, width, height) #function call\n        #Crop the image to extract the bounding box region\n        image = cv2.resize(image, (640, 640))\n        cropped_region = image [ymin:ymax, xmin:xmax]\n        # Display the cropped region\n        plt.imshow(cropped_region)\n#         cv2.waitKey(0) # Wait for a key press (in milliseconds) to close the window\n# cv2.destroyAllWindows()","metadata":{"execution":{"iopub.status.busy":"2024-01-28T09:41:35.615595Z","iopub.execute_input":"2024-01-28T09:41:35.616002Z","iopub.status.idle":"2024-01-28T09:41:35.846112Z","shell.execute_reply.started":"2024-01-28T09:41:35.615968Z","shell.execute_reply":"2024-01-28T09:41:35.845342Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!rm -r /kaggle/working/train\n!rm -r /kaggle/working/val","metadata":{"execution":{"iopub.status.busy":"2024-01-28T07:40:57.417249Z","iopub.execute_input":"2024-01-28T07:40:57.417635Z","iopub.status.idle":"2024-01-28T07:40:58.582193Z","shell.execute_reply.started":"2024-01-28T07:40:57.417607Z","shell.execute_reply":"2024-01-28T07:40:58.580665Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Training with BadODD","metadata":{}},{"cell_type":"code","source":"%%writefile data.yaml\ntrain: ./train/images\nval: ./val/images\nnames:\n    0: auto_rickshaw\n    1: bicycle\n    2: bus\n    3: car\n    4: cart_vehicle\n    5: construction_vehicle\n    6: motorbike\n    7: person\n    8: priority_vehicle\n    9: three_wheeler\n    10: train\n    11: truck\n    12: wheelchair","metadata":{"execution":{"iopub.status.busy":"2024-01-24T19:07:20.376694Z","iopub.execute_input":"2024-01-24T19:07:20.377412Z","iopub.status.idle":"2024-01-24T19:07:20.383075Z","shell.execute_reply.started":"2024-01-24T19:07:20.377379Z","shell.execute_reply":"2024-01-24T19:07:20.382158Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Weights & Biases ...\n\nimport wandb\nwandb.init(mode=\"disabled\")","metadata":{"execution":{"iopub.status.busy":"2024-01-24T19:24:41.557924Z","iopub.execute_input":"2024-01-24T19:24:41.558703Z","iopub.status.idle":"2024-01-24T19:24:41.581098Z","shell.execute_reply.started":"2024-01-24T19:24:41.558665Z","shell.execute_reply":"2024-01-24T19:24:41.580183Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.train(data=\"/kaggle/working/data.yaml\", epochs=3)","metadata":{"execution":{"iopub.status.busy":"2024-01-24T19:08:31.550559Z","iopub.execute_input":"2024-01-24T19:08:31.551313Z","iopub.status.idle":"2024-01-24T19:19:09.006150Z","shell.execute_reply.started":"2024-01-24T19:08:31.551278Z","shell.execute_reply":"2024-01-24T19:19:09.004931Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"- `box_loss` shows the amount of error in detected bounding boxes\n- `cls_loss` shows the amount of error in detected object classes.","metadata":{}},{"cell_type":"markdown","source":"`/runs/detect/train/weights/last.pt` file and the model with the highest precision to the `/runs/detect/train/weights/best.pt`","metadata":{}},{"cell_type":"markdown","source":"## Model Parameters","metadata":{}},{"cell_type":"code","source":"model.train(\n    # Project\n    project=\"BadODD\",\n    name=\"yolov8n\",\n\n    # Random Seed parameters\n    deterministic=True,\n    seed=43,\n\n    # Data & model parameters\n    data=\"/kaggle/working/data.yaml\", \n    save=True,\n    save_period=5,\n    pretrained=True,\n    imgsz=512,\n    \n    # Augmentation\n    perspective=0.3,\n    mosaic=0.8,\n    scale=0.3,\n    translate=0.4,\n\n    # Training parameters\n    epochs=3,\n    batch=8,\n    workers=2,\n    val=True,\n    device=0,\n\n    # Optimization parameters\n    lr0=0.018,\n    patience=3,\n    optimizer=\"SGD\",\n    momentum=0.947,\n    weight_decay=0.0005,\n)","metadata":{"execution":{"iopub.status.busy":"2024-01-24T19:24:49.869905Z","iopub.execute_input":"2024-01-24T19:24:49.870305Z","iopub.status.idle":"2024-01-24T19:33:19.521975Z","shell.execute_reply.started":"2024-01-24T19:24:49.870273Z","shell.execute_reply":"2024-01-24T19:33:19.520940Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Directory path ...\ntest_directory = \"/kaggle/input/dl-enigma-10-sust-cse-carnival-2024/dlenigma1/BadODD/images/test\"\n\n# Load the model ...\nmodel = YOLO('/kaggle/working/runs/detect/train/weights/best.pt')","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_prediction_string(boxes, scores, classes):\n    pred_strs = []\n    for i, score in enumerate(scores):\n        single_pred_str = \"\"\n        single_pred_str += str(float(classes[i])) + \" \" + str(float(score)) + \" \"\n        \n        x_center , y_center, width,height = boxes[i]\n        x1 = float(x_center) - (float(width) / 2)\n        y1 = float(y_center) - (float(height) / 2)\n        width = float(width)\n        height = float(height)\n        #single_pred_str += \" \".join(str(float(x)) for x in boxes[i])\n        single_pred_str +=  f\"{x1} {y1} {width} {height}\"\n        \n        pred_strs.append(single_pred_str)\n    ans = ','.join(map(str, pred_strs))\n    if len(ans):\n        return ans\n#     the solution metrics faield in case of a NaN, '' (empty). So, return \"0 0 0 0 0 0\" for NaN, '' (empty) string\n    return \"0 0 0 0 0 0\"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_prediction_entry(i, filename, boxes, scores, classes):\n    return{\n        'id':i,\n        'ImageID':filename.split('.')[0],\n        'PredictionString_pred':get_prediction_string(boxes, scores, classes)}","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def predict_all_files(test_directory):\n    predictions = []\n    for i,filename in tqdm(enumerate(os.listdir(test_directory))):\n        if filename.endswith(\".jpg\"):\n            filepath = os.path.join(test_directory, filename)\n            results = model.predict(source=filepath, conf=0.50, verbose=False)\n            boxes = results[0].boxes.xywhn\n            scores = results[0].boxes.conf\n            classes = results[0].boxes.cls\n            prediction = get_prediction_entry(i, filename, boxes, scores, classes)\n            predictions.append(prediction)\n#             to csv format ...\n    predictions_df = pd.DataFrame(predictions)\n    predictions_df.to_csv(\"submission.csv\", index=False)\n","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# call the inference function ...\npredict_all_files(test_directory)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_df = pd.read_csv('/kaggle/working/submission.csv')","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_df.tail()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_df.shape","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_df.isnull().sum()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_df.to_csv('acceptable_submission_format.csv',index=False)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Intersection Over Unior(IoU)","metadata":{}},{"cell_type":"markdown","source":"![](https://storage.googleapis.com/kagglesdsdata/datasets/4348994/7472080/Group14.png?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=databundle-worker-v2%40kaggle-161607.iam.gserviceaccount.com%2F20240124%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20240124T193808Z&X-Goog-Expires=345600&X-Goog-SignedHeaders=host&X-Goog-Signature=3ca187d26d8ba3972f4045fb5c6fc5ae92b86c835bd8f386d1b515a877aaf26573f8518092f6bbb86d141798cfae4a0f0747b8dd387a04a5b26331ebb9bb5389c756ca2494f268114214f735c8459dbeee02aa8a6c27a45634cd37e74098525aa7e5eaabb53ae0d1b05b22f79d813b516e70b91d1cbd892f1f4b531000b5e6568fa9a30abd2d92031dd3eae411c9c34080e0737b0851cf6a618b36686b8240b5cdeb63da85224488af53608769597cedb3b3f7276795406b88d9b6392ab64e7cbe5e2d8dd6aedf955cd6cc28cd1d7dddb04662ec80cad55b6271fc8e1c8dfbc2903740dea63a01d267f003cd362ccf77af3e5dd58c7b63aa078a3025a5b79c31)","metadata":{}},{"cell_type":"markdown","source":"![](https://storage.googleapis.com/kagglesdsdata/datasets/4348994/7472080/Group11.png?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=databundle-worker-v2%40kaggle-161607.iam.gserviceaccount.com%2F20240124%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20240124T193802Z&X-Goog-Expires=345600&X-Goog-SignedHeaders=host&X-Goog-Signature=4316be9d822286942c3df084d4446a60630867a79a7e148fb443c36a3b2db38a2a11da02cb86d54eb9e7df4243e8c95e9d1e0be0c1b78b102aa7673ca26df36f245e8cce7afd3a9a1fec7a8ff70d0c7184e4a5baa5f4241db57edc319e0085fc42f7f2e6e94644714d92a6552f091186f84c60a944fd3c0e5de0780cfee3de4b57cdca5ce4cb7776c3342fe9096031d9a67d2858b10535041bed1f82294b084ebd9533472a63b47135457517062231ae7967fd3e419db0b6877d11cc5b541f8c0506dda3b9ca11b4862d103d01e70c8814b642e1eacbe124926a107181e1880defa586b5a91ed16cca82a86b2bdbe377339a3287f8b3a8c3f70ed03604c0ea9e)","metadata":{}},{"cell_type":"markdown","source":"![](https://storage.googleapis.com/kagglesdsdata/datasets/4348994/7472080/Group12.png?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=databundle-worker-v2%40kaggle-161607.iam.gserviceaccount.com%2F20240124%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20240124T193714Z&X-Goog-Expires=345600&X-Goog-SignedHeaders=host&X-Goog-Signature=85798d6607cc8079fecb235dfe4509ba6da85302702df09c8497a6e0e2f2733a311b282789ef2f7ad28cdc2f3a56f1b7d585eb982e51c15afb9016d51817a4f8d944536e2a23cb115b756fa19d8192ad5f287aea7fc514d8e0fe44004d382794ea7a145ae70001863551ba32b23ca0aff9dcf0fb158f8fb75b193fae5093f01f50f088b714d61963514090bedc3f6b576fe888b60e017cac43aa887f67eb48a833af5f806766859bf8e5a1bcfa3f2caa86feff70cd73b05b61ff38f72ccec7f7cd8436cfc06d5bc610af50f8be4774128f83f8074326ed01a6e0602fbcae9e1dc11194a2446c663d2a2ac0ce33dfe4463e8156c63cea3fc364efee0edc9aa106)","metadata":{}},{"cell_type":"code","source":"def calculate_iou(boxA, boxB):\n    # Determine the coordinates of the intersection rectangle\n    xA = max(boxA[0], boxB[0])\n    yA = max(boxA[1], boxB[1])\n    xB = min(boxA[2], boxB[2])\n    yB = min(boxA[3], boxB[3])\n\n    # Compute the area of intersection\n    intersection_area = max(0, xB - xA) * max(0, yB - yA)\n\n    # Compute the area of both bounding boxes\n    boxA_area = (boxA[2] - boxA[0]) * (boxA[3] - boxA[1])\n    boxB_area = (boxB[2] - boxB[0]) * (boxB[3] - boxB[1])\n\n    # Compute the area of union\n    union_area = boxA_area + boxB_area - intersection_area\n\n    # Compute the IoU\n    iou = intersection_area / union_area\n\n    return iou\n\n# Example case 1\nbox1 = (10, 10, 50, 50)  # Coordinates (x1, y1, x2, y2) for the first box\nbox2 = (30, 30, 70, 70)  # Coordinates for the second box\niou1 = calculate_iou(box1, box2)\nprint(\"IoU for case 1:\", iou1)\n\n# Example case 2\nbox3 = (20, 20, 40, 40)  # Coordinates for the third box\nbox4 = (50, 50, 100, 100) # Coordinates for the fourth box\niou2 = calculate_iou(box3, box4)\nprint(\"IoU for case 2:\", iou2)\n","metadata":{"execution":{"iopub.status.busy":"2024-01-27T15:05:52.190594Z","iopub.execute_input":"2024-01-27T15:05:52.191415Z","iopub.status.idle":"2024-01-27T15:05:52.236076Z","shell.execute_reply.started":"2024-01-27T15:05:52.191375Z","shell.execute_reply":"2024-01-27T15:05:52.234893Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import cv2\nimport numpy as np\nimport matplotlib.pyplot as plt\n\n# Create a blank image\nimage = np.zeros((120, 120, 3), dtype=np.uint8)\n\n# Define bounding boxes\nbox1 = (10, 10, 50, 50)\nbox2 = (30, 30, 70, 70)\n\n\n# Draw the bounding boxes on the image\n# Box1 in red, Box2 in blue, Box3 in green, Box4 in yellow\ncv2.rectangle(image, box1[:2], box1[2:], (255, 0, 0), 2)\ncv2.rectangle(image, box2[:2], box2[2:], (0, 0, 255), 2)\n\n\n# Show the image using Matplotlib\nplt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))\nplt.title(\"Bounding Boxes\")\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2024-01-27T16:34:51.014986Z","iopub.execute_input":"2024-01-27T16:34:51.015397Z","iopub.status.idle":"2024-01-27T16:34:51.305055Z","shell.execute_reply.started":"2024-01-27T16:34:51.015365Z","shell.execute_reply":"2024-01-27T16:34:51.304071Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import cv2\nimport numpy as np\nimport matplotlib.pyplot as plt\n\n# Create a blank image\nimage = np.zeros((120, 120, 3), dtype=np.uint8)\n\nbox3 = (20, 20, 40, 40)\nbox4 = (50, 50, 100, 100)\n\ncv2.rectangle(image, box3[:2], box3[2:], (0, 255, 0), 2)\ncv2.rectangle(image, box4[:2], box4[2:], (0, 255, 255), 2)\n\n# Show the image using Matplotlib\nplt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))\nplt.title(\"Bounding Boxes\")\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-01-27T16:34:39.188614Z","iopub.execute_input":"2024-01-27T16:34:39.189602Z","iopub.status.idle":"2024-01-27T16:34:39.415604Z","shell.execute_reply.started":"2024-01-27T16:34:39.189567Z","shell.execute_reply":"2024-01-27T16:34:39.414586Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# import cv2\n# import matplotlib.pyplot as plt\n# # Read the image using OpenCV\n# image_path = '/kaggle/input/cat-dog-image/cat_dog.jpg'\n# image = cv2.imread(image_path)\n# image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n# pred_box = (10, 10, 50, 50)\n# box2 = (30, 30, 70, 70)\n# pred_x1 , pred_y1, pred_x2, pred_y2 = box2\n\n# cv2.rectangle(image,(pred_x1,pred_y1),(pred_x2,pred_y2),(0,0,255),2)\n\n# boxes = result.boxes.cpu().numpy()\n\n# xyxy = boxes[0].xyxy.squeeze()\n\n# print(xyxy.squeeze())\n\n# x1 = int(xyxy[0])\n# y1 = int(xyxy[1])\n# x2 = int(xyxy[2])\n# y2 = int(xyxy[3])\n\n# cv2.rectangle(image,(x1,y1),(x2,y2),(0,255,0),2)\n\n# plt.imshow(image)\n# plt.axis('off')  # Turn off axis labels\n# plt.show()\n","metadata":{"execution":{"iopub.status.busy":"2024-01-27T16:45:44.760926Z","iopub.execute_input":"2024-01-27T16:45:44.761746Z","iopub.status.idle":"2024-01-27T16:45:44.767268Z","shell.execute_reply.started":"2024-01-27T16:45:44.761710Z","shell.execute_reply":"2024-01-27T16:45:44.766195Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}