diff --git a/phase1solution/.ipynb_checkpoints/DocScanner_Notebook_Representation-checkpoint.ipynb b/phase1solution/.ipynb_checkpoints/DocScanner_Notebook_Representation-checkpoint.ipynb new file mode 100644 index 0000000..aefe15b --- /dev/null +++ b/phase1solution/.ipynb_checkpoints/DocScanner_Notebook_Representation-checkpoint.ipynb @@ -0,0 +1,371 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Step by step DocScanner Algorithm Execution" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# By Abhinav Chauhan\n", + "# Refrence : Murtaza's Workshop (Youtube Channel)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Importing Libraries" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [], + "source": [ + "import cv2\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "%matplotlib inline" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [], + "source": [ + "# Resizing image ( This step is optional)\n", + "widthImg = 500\n", + "heightImg = 540" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "-1" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "path = \"1.jpg\"\n", + "img = cv2.imread(path)\n", + "img = cv2.resize(img, (widthImg, heightImg))\n", + "cv2.imshow('Real Image', img)\n", + "cv2.waitKey(0)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Image Preprocessing" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "-1" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Converting Image to Gray\n", + "\n", + "imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)\n", + "cv2.imwrite('Gray.jpg', imgGray)\n", + "cv2.imshow('Gray Image', imgGray)\n", + "cv2.waitKey(0)" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "-1" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Blurring Image\n", + "\n", + "imgBlur = cv2.GaussianBlur(imgGray,(5,5),1)\n", + "cv2.imwrite('Blur.jpg', imgBlur)\n", + "cv2.imshow('Blur Image', imgBlur)\n", + "cv2.waitKey(0)" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "-1" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Detecting edges using canny edge detector\n", + "\n", + "imgCanny = cv2.Canny(imgBlur,200,200)\n", + "cv2.imwrite('Canny.jpg', imgCanny)\n", + "cv2.imshow('Canny Image', imgCanny)\n", + "cv2.waitKey(0)" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "-1" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Dialation image\n", + "\n", + "kernel = np.ones((5,5))\n", + "imgDial = cv2.dilate(imgCanny,kernel, iterations = 2)\n", + "cv2.imwrite('Dilated.jpg', imgDial)\n", + "cv2.imshow('Dialated Image', imgDial)\n", + "cv2.waitKey(0)" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "-1" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Eroded Image (Final image after Perprocessing)\n", + "\n", + "kernel = np.ones((5,5))\n", + "imgThres = cv2.erode(imgDial, kernel, iterations = 1)\n", + "cv2.imwrite('Threshold.jpg', imgThres)\n", + "cv2.imshow('Threshold Image', imgThres)\n", + "cv2.waitKey(0)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Function to get the desired countour and draw corner points around it" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[[350 38]]\n", + "\n", + " [[105 50]]\n", + "\n", + " [[135 473]]\n", + "\n", + " [[410 433]]]\n" + ] + } + ], + "source": [ + "imgContour = img.copy()\n", + "def getContours(img):\n", + " biggest = np.array([])\n", + " maxArea = 0\n", + " #_, contours, _= cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)\n", + " contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)\n", + " for cnt in contours:\n", + " area = cv2.contourArea(cnt)\n", + " if area> 5000:\n", + " #cv2.drawContours(imgContour, cnt, -1, (255,0,0), 3)\n", + " peri = cv2.arcLength(cnt, True)\n", + " approx = cv2.approxPolyDP(cnt, 0.03*peri, True)\n", + " if area > maxArea and len(approx) == 4:\n", + " biggest = approx\n", + " maxArea = area\n", + "\n", + " cv2.drawContours(imgContour, biggest, -1, (255,0,0), 20)\n", + " cv2.imwrite('Conttour.jpg', imgContour)\n", + " cv2.imshow('Corner', imgContour)\n", + " cv2.waitKey(0)\n", + " return biggest\n", + "\n", + "biggest = getContours(imgThres)\n", + "print(biggest)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "# Now, the above printed biggest variable has the coordinates of the biggest contour detected\n", + "# But they are not in the correct order taken by the Wraping function.\n", + "# So we create another function to reorder them correctly according to the order required by Wraping function \n", + "# i.e (0,0) (width, 0) (0, height) and (width, height)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Function to get correct order of the corner points of the biggest contour detected." + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [], + "source": [ + "def reorder(myPoints):\n", + " myPoints = myPoints.reshape((4,2))\n", + " myPointsNew = np.zeros((4,1,2), np.int32)\n", + " add = myPoints.sum(1)\n", + " myPointsNew[0] = myPoints[np.argmin(add)]\n", + " myPointsNew[3] = myPoints[np.argmax(add)]\n", + " diff = np.diff(myPoints, axis=1)\n", + " myPointsNew[1] = myPoints[np.argmin(diff)]\n", + " myPointsNew[2] = myPoints[np.argmax(diff)]\n", + " return myPointsNew\n", + "\n", + "# We call this fucntion inside the Wraping fucntion which is in the very nect cell" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Function to wrap the image with the ordered points i.e. (0,0) (width, 0) (0, height) and (width, height)" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "-1" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def getWarp(img, biggest):\n", + " biggest = reorder(biggest)\n", + " pts1 = np.float32(biggest)\n", + " pts2 = np.float32([[0,0],[widthImg,0],[0,heightImg],[widthImg,heightImg]])\n", + " matrix = cv2.getPerspectiveTransform(pts1,pts2)\n", + " imgOutput = cv2.warpPerspective(img,matrix,(widthImg,heightImg))\n", + "\n", + " return imgOutput\n", + "\n", + "imgWarped = getWarp(img,biggest)\n", + "cv2.imwrite('Scanned.jpg', imgWarped)\n", + "cv2.imshow('Scanned Image',imgWarped)\n", + "cv2.waitKey(0)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# All the output images at every step are saved and placed in the folder.\n", + "# Also the image will be saved at runtime!" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.3" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/phase1solution/.ipynb_checkpoints/Untitled-checkpoint.ipynb b/phase1solution/.ipynb_checkpoints/Untitled-checkpoint.ipynb new file mode 100644 index 0000000..7fec515 --- /dev/null +++ b/phase1solution/.ipynb_checkpoints/Untitled-checkpoint.ipynb @@ -0,0 +1,6 @@ +{ + "cells": [], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/phase1solution/1.jpg b/phase1solution/1.jpg new file mode 100644 index 0000000..e221f03 Binary files /dev/null and b/phase1solution/1.jpg differ diff --git a/phase1solution/Blur.jpg b/phase1solution/Blur.jpg new file mode 100644 index 0000000..2694259 Binary files /dev/null and b/phase1solution/Blur.jpg differ diff --git a/phase1solution/Canny.jpg b/phase1solution/Canny.jpg new file mode 100644 index 0000000..8ab47b4 Binary files /dev/null and b/phase1solution/Canny.jpg differ diff --git a/phase1solution/Conttour.jpg b/phase1solution/Conttour.jpg new file mode 100644 index 0000000..65289d1 Binary files /dev/null and b/phase1solution/Conttour.jpg differ diff --git a/phase1solution/Dilated.jpg b/phase1solution/Dilated.jpg new file mode 100644 index 0000000..a4c3462 Binary files /dev/null and b/phase1solution/Dilated.jpg differ diff --git a/phase1solution/DocScanner_Notebook_Representation.ipynb b/phase1solution/DocScanner_Notebook_Representation.ipynb new file mode 100644 index 0000000..aefe15b --- /dev/null +++ b/phase1solution/DocScanner_Notebook_Representation.ipynb @@ -0,0 +1,371 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Step by step DocScanner Algorithm Execution" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# By Abhinav Chauhan\n", + "# Refrence : Murtaza's Workshop (Youtube Channel)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Importing Libraries" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [], + "source": [ + "import cv2\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "%matplotlib inline" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [], + "source": [ + "# Resizing image ( This step is optional)\n", + "widthImg = 500\n", + "heightImg = 540" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "-1" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "path = \"1.jpg\"\n", + "img = cv2.imread(path)\n", + "img = cv2.resize(img, (widthImg, heightImg))\n", + "cv2.imshow('Real Image', img)\n", + "cv2.waitKey(0)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Image Preprocessing" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "-1" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Converting Image to Gray\n", + "\n", + "imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)\n", + "cv2.imwrite('Gray.jpg', imgGray)\n", + "cv2.imshow('Gray Image', imgGray)\n", + "cv2.waitKey(0)" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "-1" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Blurring Image\n", + "\n", + "imgBlur = cv2.GaussianBlur(imgGray,(5,5),1)\n", + "cv2.imwrite('Blur.jpg', imgBlur)\n", + "cv2.imshow('Blur Image', imgBlur)\n", + "cv2.waitKey(0)" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "-1" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Detecting edges using canny edge detector\n", + "\n", + "imgCanny = cv2.Canny(imgBlur,200,200)\n", + "cv2.imwrite('Canny.jpg', imgCanny)\n", + "cv2.imshow('Canny Image', imgCanny)\n", + "cv2.waitKey(0)" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "-1" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Dialation image\n", + "\n", + "kernel = np.ones((5,5))\n", + "imgDial = cv2.dilate(imgCanny,kernel, iterations = 2)\n", + "cv2.imwrite('Dilated.jpg', imgDial)\n", + "cv2.imshow('Dialated Image', imgDial)\n", + "cv2.waitKey(0)" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "-1" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Eroded Image (Final image after Perprocessing)\n", + "\n", + "kernel = np.ones((5,5))\n", + "imgThres = cv2.erode(imgDial, kernel, iterations = 1)\n", + "cv2.imwrite('Threshold.jpg', imgThres)\n", + "cv2.imshow('Threshold Image', imgThres)\n", + "cv2.waitKey(0)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Function to get the desired countour and draw corner points around it" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[[350 38]]\n", + "\n", + " [[105 50]]\n", + "\n", + " [[135 473]]\n", + "\n", + " [[410 433]]]\n" + ] + } + ], + "source": [ + "imgContour = img.copy()\n", + "def getContours(img):\n", + " biggest = np.array([])\n", + " maxArea = 0\n", + " #_, contours, _= cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)\n", + " contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)\n", + " for cnt in contours:\n", + " area = cv2.contourArea(cnt)\n", + " if area> 5000:\n", + " #cv2.drawContours(imgContour, cnt, -1, (255,0,0), 3)\n", + " peri = cv2.arcLength(cnt, True)\n", + " approx = cv2.approxPolyDP(cnt, 0.03*peri, True)\n", + " if area > maxArea and len(approx) == 4:\n", + " biggest = approx\n", + " maxArea = area\n", + "\n", + " cv2.drawContours(imgContour, biggest, -1, (255,0,0), 20)\n", + " cv2.imwrite('Conttour.jpg', imgContour)\n", + " cv2.imshow('Corner', imgContour)\n", + " cv2.waitKey(0)\n", + " return biggest\n", + "\n", + "biggest = getContours(imgThres)\n", + "print(biggest)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "# Now, the above printed biggest variable has the coordinates of the biggest contour detected\n", + "# But they are not in the correct order taken by the Wraping function.\n", + "# So we create another function to reorder them correctly according to the order required by Wraping function \n", + "# i.e (0,0) (width, 0) (0, height) and (width, height)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Function to get correct order of the corner points of the biggest contour detected." + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [], + "source": [ + "def reorder(myPoints):\n", + " myPoints = myPoints.reshape((4,2))\n", + " myPointsNew = np.zeros((4,1,2), np.int32)\n", + " add = myPoints.sum(1)\n", + " myPointsNew[0] = myPoints[np.argmin(add)]\n", + " myPointsNew[3] = myPoints[np.argmax(add)]\n", + " diff = np.diff(myPoints, axis=1)\n", + " myPointsNew[1] = myPoints[np.argmin(diff)]\n", + " myPointsNew[2] = myPoints[np.argmax(diff)]\n", + " return myPointsNew\n", + "\n", + "# We call this fucntion inside the Wraping fucntion which is in the very nect cell" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Function to wrap the image with the ordered points i.e. (0,0) (width, 0) (0, height) and (width, height)" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "-1" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def getWarp(img, biggest):\n", + " biggest = reorder(biggest)\n", + " pts1 = np.float32(biggest)\n", + " pts2 = np.float32([[0,0],[widthImg,0],[0,heightImg],[widthImg,heightImg]])\n", + " matrix = cv2.getPerspectiveTransform(pts1,pts2)\n", + " imgOutput = cv2.warpPerspective(img,matrix,(widthImg,heightImg))\n", + "\n", + " return imgOutput\n", + "\n", + "imgWarped = getWarp(img,biggest)\n", + "cv2.imwrite('Scanned.jpg', imgWarped)\n", + "cv2.imshow('Scanned Image',imgWarped)\n", + "cv2.waitKey(0)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# All the output images at every step are saved and placed in the folder.\n", + "# Also the image will be saved at runtime!" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.3" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/phase1solution/Gray.jpg b/phase1solution/Gray.jpg new file mode 100644 index 0000000..5468b2a Binary files /dev/null and b/phase1solution/Gray.jpg differ diff --git a/phase1solution/Scanned.jpg b/phase1solution/Scanned.jpg new file mode 100644 index 0000000..8f5233a Binary files /dev/null and b/phase1solution/Scanned.jpg differ diff --git a/phase1solution/Threshold.jpg b/phase1solution/Threshold.jpg new file mode 100644 index 0000000..2280706 Binary files /dev/null and b/phase1solution/Threshold.jpg differ diff --git a/phase1solution/debug.log b/phase1solution/debug.log new file mode 100644 index 0000000..dc8c6cf --- /dev/null +++ b/phase1solution/debug.log @@ -0,0 +1,2 @@ +[1223/111136.742:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) +[1223/131718.829:ERROR:directory_reader_win.cc(43)] FindFirstFile: The system cannot find the path specified. (0x3) diff --git a/phase1solution/phase1.py b/phase1solution/phase1.py new file mode 100644 index 0000000..95fd1b9 --- /dev/null +++ b/phase1solution/phase1.py @@ -0,0 +1,86 @@ +# Abhinav Chauhan + + +# Importing Libraries + +import cv2 +import numpy as np + + + +# Resizing image ( This step is optional) +widthImg = 500 +heightImg = 540 + + + +# Function to pre-process the image. + +def preProcessing(img): + imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) + imgBlur = cv2.GaussianBlur(imgGray,(5,5),1) + imgCanny = cv2.Canny(imgBlur,200,200) + kernel = np.ones((5,5)) + imgDial = cv2.dilate(imgCanny,kernel, iterations = 2) + imgThres = cv2.erode(imgDial, kernel, iterations = 1) + + return imgThres + +# Function to get the desired countours and draw corner points around them + +def getContours(img): + biggest = np.array([]) + maxArea = 0 + #_, contours, _= cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) + contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) + for cnt in contours: + area = cv2.contourArea(cnt) + if area> 5000: + #cv2.drawContours(imgContour, cnt, -1, (255,0,0), 3) + peri = cv2.arcLength(cnt, True) + approx = cv2.approxPolyDP(cnt, 0.03*peri, True) + if area > maxArea and len(approx) == 4: + biggest = approx + maxArea = area + + cv2.drawContours(imgContour, biggest, -1, (255,0,0), 20) + cv2.imshow('Corner', imgContour) + return biggest + +# This is the main function that resolves the issue posted in the repo. i.e to get corret order of the corner points of the contour detected. + +def reorder(myPoints): + myPoints = myPoints.reshape((4,2)) + myPointsNew = np.zeros((4,1,2), np.int32) + add = myPoints.sum(1) + myPointsNew[0] = myPoints[np.argmin(add)] + myPointsNew[3] = myPoints[np.argmax(add)] + diff = np.diff(myPoints, axis=1) + myPointsNew[1] = myPoints[np.argmin(diff)] + myPointsNew[2] = myPoints[np.argmax(diff)] + return myPointsNew + +# Function to wrap the image with the ordered points i.e. (0,0) (width, 0) (0, height) and (width, height) + +def getWarp(img, biggest): + biggest = reorder(biggest) + pts1 = np.float32(biggest) + pts2 = np.float32([[0,0],[widthImg,0],[0,heightImg],[widthImg,heightImg]]) + matrix = cv2.getPerspectiveTransform(pts1,pts2) + imgOutput = cv2.warpPerspective(img,matrix,(widthImg,heightImg)) + + return imgOutput + + + +# code to read the image and display the desired results. +path = "1.jpg" +img = cv2.imread(path) +img = cv2.resize(img, (widthImg, heightImg)) +imgContour = img.copy() +imgThres = preProcessing(img) +biggest = getContours(imgThres) + +imgWarped = getWarp(img,biggest) +cv2.imshow('Result',imgWarped) +cv2.waitKey(0) diff --git a/phase1solution/test.jpeg b/phase1solution/test.jpeg new file mode 100644 index 0000000..70526c2 Binary files /dev/null and b/phase1solution/test.jpeg differ