diff --git a/.ipynb_checkpoints/openCV_scanner-checkpoint.ipynb b/.ipynb_checkpoints/openCV_scanner-checkpoint.ipynb index bd154fb26b8e208c3292ca4c933e6a6d5a462e2b..aa6048d7a9c3c5a47ab94da4532646a732f5d6da 100644 --- a/.ipynb_checkpoints/openCV_scanner-checkpoint.ipynb +++ b/.ipynb_checkpoints/openCV_scanner-checkpoint.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 54, + "execution_count": 267, "metadata": { "scrolled": true }, @@ -11,12 +11,16 @@ "import numpy as np\n", "import cv2\n", "import glob\n", - "from matplotlib import pyplot as plt" + "from matplotlib import pyplot as plt\n", + "import tkinter as tk\n", + "from PIL import Image\n", + "from PIL import ImageTk\n", + "import os" ] }, { "cell_type": "code", - "execution_count": 55, + "execution_count": 268, "metadata": {}, "outputs": [], "source": [ @@ -40,7 +44,7 @@ }, { "cell_type": "code", - "execution_count": 56, + "execution_count": 269, "metadata": {}, "outputs": [], "source": [ @@ -74,7 +78,7 @@ }, { "cell_type": "code", - "execution_count": 57, + "execution_count": 270, "metadata": {}, "outputs": [], "source": [ @@ -112,7 +116,7 @@ }, { "cell_type": "code", - "execution_count": 58, + "execution_count": 271, "metadata": {}, "outputs": [], "source": [ @@ -132,14 +136,14 @@ }, { "cell_type": "code", - "execution_count": 59, + "execution_count": 272, "metadata": {}, "outputs": [], "source": [ "# 마우스를 이용하여 책의 꼭지점을 조정한다.\n", "def mouse_callback(event,x,y,flags,param):\n", " \n", - " global mouse_is_pressing,points\n", + " global mouse_is_pressing, points\n", "\n", " if step != 1:\n", " return\n", @@ -167,7 +171,7 @@ }, { "cell_type": "code", - "execution_count": 60, + "execution_count": 273, "metadata": {}, "outputs": [], "source": [ @@ -181,7 +185,26 @@ }, { "cell_type": "code", - "execution_count": 67, + "execution_count": 274, + "metadata": {}, + "outputs": [], + "source": [ + "def convert_to_tkimage():\n", + " global src\n", + " \n", + " gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)\n", + " _, binary = cv2.threshold(gray, 100, 255, cv2.THRESH_BINARY)\n", + "\n", + " img = Image.fromarray(binary)\n", + " imgtk = ImageTk.PhotoImage(image=img)\n", + "\n", + " label.config(image=imgtk)\n", + " label.image = imgtk" + ] + }, + { + "cell_type": "code", + "execution_count": 275, "metadata": {}, "outputs": [], "source": [ @@ -215,51 +238,52 @@ "\n", " kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))\n", " image_canny = cv2.morphologyEx(image_canny, cv2.MORPH_CLOSE, kernel, 1)\n", - " cv2.imwrite('./modified/' +i, image_canny)\n", - " print(i + \"save image_canny!\")\n", + " #cv2.imwrite('./modified/' +i, image_canny)\n", + " #print(i + \"save image_canny!\")\n", "\n", - " cv2.imshow('morphology', image_canny)\n", - " cv2.waitKey(0)\n", + " #cv2.imshow('morphology', image_canny)\n", + " #cv2.waitKey(0)\n", " # 캐니 에지 결과에서 컨투어를 검출하여 가장 큰 영역을 차지하는 컨투어를 찾는다.\n", " contours, hierarchy = cv2.findContours(image_canny, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)\n", " max_index = findMaxArea(contours) \n", " \n", - " \"\"\"\n", " #################이부분이 잘 이해가 안감.\n", + " #print(\"contours \", contours)\n", + " #print(\"max_index = \",max_index)\n", + " image_fixed = image.copy()\n", " if max_index < 0:\n", " print(\"max_index < 0 \" +i)\n", + " #print(points)\n", " return points\n", - " \"\"\"\n", "\n", " max_contour = contours[max_index]\n", "\n", "\n", - " image_contour = image.copy()\n", - " cv2.drawContours(image_contour, [max_contour], 0, (0, 0, 255), 3)\n", - " cv2.imwrite('./modified/' +i, image_contour)\n", - " print(i + \"save image_contour!\")\n", - " cv2.imshow('Contour', image_contour)\n", - " cv2.waitKey(0)\n", + " #image_contour = image.copy()\n", + " #cv2.drawContours(image_contour, [max_contour], 0, (0, 0, 255), 3)\n", + " #cv2.imwrite('./modified/' +i, image_contour)\n", + " #print(i + \"save image_contour!\")\n", + " #cv2.imshow('Contour', image_contour)\n", + " #cv2.waitKey(0)\n", "\n", " # approxPolyDP 함수를 사용하여 컨투어를 근사화하고 convex hull을 구한다.\n", " max_contour = cv2.approxPolyDP(max_contour,0.02*cv2.arcLength(max_contour,True),True)\n", " hull = cv2.convexHull(max_contour)\n", "\n", "\n", - " image_convexhull = image.copy()\n", - " cv2.drawContours(image_convexhull, [hull], 0, (255,255,0), 5)\n", - " cv2.imwrite('./modified/' +i, image_convexhull) \n", - " print(i + \"save image_convexhull!\")\n", - " cv2.imshow('convexHull', image_convexhull)\n", - " cv2.waitKey(0)\n", - " \n", + " #image_convexhull = image.copy()\n", + " #cv2.drawContours(image_convexhull, [hull], 0, (255,255,0), 5)\n", + " #cv2.imwrite('./modified/' +i, image_convexhull) \n", + " #print(i + \"save image_convexhull!\")\n", + " #cv2.imshow('convexHull', image_convexhull)\n", + " #cv2.waitKey(0)\n", " size = len(max_contour) \n", - " print(size)\n", + " print(\"len of max_contour\" ,size)\n", " if size == 4: # 책의 꼭지점을 구한다.\n", " for c in hull:\n", " points.append(c[0])\n", " points = np.array(points)\n", - " print(points)\n", + " #print(points)\n", "\n", " else: # 꼭지점이 5개 이상인 경우 경계 박스를 이용한다.\n", "\n", @@ -273,6 +297,7 @@ " if p[0] < 0 or p[0] > width-1 or p[1] < 0 or p[1] > height -1:\n", " found = True \n", " break\n", + " \n", "\n", " if found:\n", " points = np.array([[10,10], [width-11, 10], [width-11, height-11], [10, height-11]])\n", @@ -283,69 +308,132 @@ }, { "cell_type": "code", - "execution_count": 68, + "execution_count": 276, + "metadata": {}, + "outputs": [], + "source": [ + "def b1event():\n", + " print(sizes)\n", + " if sizes == 4:\n", + " cv2.namedWindow('input')\n", + " cv2.setMouseCallback(\"input\", mouse_callback, 0);\n", + " \n", + " step = 1\n", + " \n", + " while True:\n", + " image_result = image.copy()\n", + " for point in points:\n", + " cv2.circle(image_result, tuple(point), 10, (255,0,0), 3)\n", + " cv2.imshow('input', image_result)\n", + " \n", + " key = cv2.waitKey(1)\n", + " if key == 32:\n", + " break\n", + " image_final = transform(image, points)\n", + " \n", + " cv2.imshow('input', image_result)\n", + " cv2.imshow('result', image_final)\n", + " cv2.imwrite('./modified/' +i, image_final)\n", + " print(i + \" save final image!\")\n", + " \n", + " else:\n", + " cv2.imshow('input', image)\n", + " cv2.imwrite('./modified/' +i, image)\n", + " print(i + \" not yet..!\")\n", + " cv2.waitKey(0)\n", + " cv2.destroyAllWindows()\n", + " win.destroy()" + ] + }, + { + "cell_type": "code", + "execution_count": 277, + "metadata": {}, + "outputs": [], + "source": [ + "def b2event():\n", + " if sizes == 4:\n", + " image_final = transform(image, points)\n", + " cv2.imshow('result', image_final)\n", + " cv2.imwrite('./modified/' +i, image_final)\n", + " print(i + \" save thresh!\")\n", + " else:\n", + " cv2.imshow('input', image)\n", + " cv2.imwrite('./modified/' +i, image)\n", + " print(i + \" not yet..!\")\n", + " cv2.waitKey(0)\n", + " cv2.destroyAllWindows()\n", + " win.destroy()" + ] + }, + { + "cell_type": "code", + "execution_count": 278, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "book.jpgsave image_canny!\n", - "book.jpgsave image_contour!\n", - "book.jpgsave image_convexhull!\n", - "7\n", - "[10. 10.] [489. 10.] [489. 489.] [ 10. 489.]\n", - "20.0 499.0 978.0 499.0\n", - "book.jpgsave image_final!\n", - "book.jpg save thresh!\n", - "book2.jpgsave image_canny!\n", - "book2.jpgsave image_contour!\n", - "book2.jpgsave image_convexhull!\n", - "6\n", - "[10. 10.] [489. 10.] [489. 489.] [ 10. 489.]\n", - "20.0 499.0 978.0 499.0\n", - "book2.jpgsave image_final!\n", - "book2.jpg save thresh!\n", - "receipt2.jpgsave image_canny!\n", - "receipt2.jpgsave image_contour!\n", - "receipt2.jpgsave image_convexhull!\n", + "max_index < 0 document.jpg\n", + "size 0\n", + "0\n", + "document.jpg not yet..!\n", + "max_index < 0 receipt2.jpg\n", + "size 0\n", + "0\n", + "receipt2.jpg not yet..!\n", + "len of max_contour 8\n", + "size 4\n", "4\n", - "[[465 362]\n", - " [203 463]\n", - " [ 34 125]\n", - " [254 34]]\n", - "[ 34. 125.] [254. 34.] [465. 362.] [203. 463.]\n", - "159.0 288.0 827.0 666.0\n", - "receipt2.jpgsave image_final!\n", - "receipt2.jpg save thresh!\n" + "[13. 48.] [149. 27.] [170. 218.] [ 36. 238.]\n", + "61.0 176.0 388.0 274.0\n", + "tilted receipt.jpg save final image!\n" ] } ], "source": [ - "######################################################################\n", - "#이미지파일 한번에 여러개 받는 방법??\n", - "#\n", - "#\n", - "import os\n", + "mouse_is_pressing = False\n", "for i in os.listdir('./images/'): \n", " path = './images/'+i \n", " count = len(os.listdir('./images/'))\n", " \n", " \n", " image = cv2.imread(path, cv2.IMREAD_COLOR)\n", - " image=cv2.resize(image,(500,500))\n", + " #image=cv2.resize(image,(500,500))\n", " points = scanning(image)\n", + " sizes = len(points)\n", + " print(\"size\",sizes)\n", + " \n", + " win = tk.Tk()\n", + " win.title(\"Ask\")\n", + " win.geometry(\"500x500+50+50\")\n", + " win.resizable(False, False)\n", + "\n", + " lbl = tk.Label(win, text=\"마우스 입력 O/X?\")\n", + " #lbl.grid(row=1, column=1)\n", + " lbl.pack()\n", + "\n", + " cv2.imwrite('./contours/' +i, image) \n", + "\n", + " imgtk = ImageTk.PhotoImage(file = './contours/' +i, master=win)\n", + " label = tk.Label(win, image=imgtk)\n", + " label.pack()\n", + "\n", + " b1 = tk.Button(win, text='마우스 입력O', command = b1event)\n", + " b2 = tk.Button(win, text='마우스 입력X', command = b2event)\n", + " #b1.grid(row=3, column=1)\n", + " #b2.grid(row=3, column=2)\n", + " b1.pack()\n", + " b2.pack()\n", + "\n", + " win.mainloop()\n", " \n", + " \"\"\"\n", " size = len(points)\n", + " print(\"size\" ,size)\n", " if size == 4:\n", "\n", - " ##############################################################\n", - " # 여기에 사용자가 마우스 사용할지 안할지에대한 GUI 넣기?\n", - " # \n", - " #\n", - " #\n", - " ####################################################################\n", - " # 마우스 콜백 함수를 등록하고\n", " cv2.namedWindow('input')\n", " cv2.setMouseCallback(\"input\", mouse_callback, 0); \n", "\n", @@ -371,39 +459,83 @@ "\n", " cv2.imshow('input', image_result)\n", " cv2.imshow('result', image_final )\n", - "\n", " else:\n", " cv2.imshow('input', image)\n", - " \n", + " \n", " cv2.waitKey(0)\n", " cv2.destroyAllWindows()\n", - " #cv2.imwrite('./modified/' +i, image_final) \n", - " ################################################################\n", - " ############영수증의 경우 이것을 사용하면 글씨가 돋보임 ( 흑백대비)\n", - " gray = cv2.cvtColor(image_final, cv2.COLOR_BGR2GRAY)\n", + " win.destroy()\n", + " gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)\n", "\n", " sharpen = cv2.GaussianBlur(gray, (0,0), 3)\n", " sharpen = cv2.addWeighted(gray, 1.5, sharpen, -0.5, 0)\n", " thresh = cv2.adaptiveThreshold(sharpen, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 21, 15)\n", " cv2.imwrite('./modified/' +i, thresh)\n", " print(i + \" save thresh!\")\n", - " cv2.imshow('grayscale?', thresh)\n", + " cv2.imshow('final_image', thresh)\n", " cv2.waitKey(0)\n", " #cv2.imwrite('./modified/' +i, modified) \n", "\n", " #cv2.imshow( \"image\", image)\n", - " #cv2.waitKey(0)\n" + " #cv2.waitKey(0)\n", + "\n", + "\"\"\"" ] }, { "cell_type": "code", - "execution_count": 231, + "execution_count": 266, "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'fpdf'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m<ipython-input-266-d25ce1a2f34d>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;31m#이미지 저장\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0mfpdf\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mFPDF\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 3\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mPIL\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mImage\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mos\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'fpdf'" + ] + } + ], "source": [ "#이미지 저장\n", - "def save(image):\n", - " cv2.imwrite('./modified/modified.jpg', image) \n" + "##################아직 안합침################################\n", + "from fpdf import FPDF\n", + "from PIL import Image\n", + "import os\n", + "\n", + "pdf = FPDF()\n", + "imagelist = [] # Contains the list of all images to be converted to PDF.\n", + "\n", + "\n", + "# --------------- USER INPUT -------------------- #\n", + " \n", + "folder = \"\" # Folder containing all the images.\n", + "name = \"\" # Name of the output PDF file.\n", + "\n", + "# ------------- ADD ALL THE IMAGES IN A LIST ------------- #\n", + "\n", + "folder = input('Enter the path of the folder containing the images : ')\n", + "for dirpath, dirnames, filenames in os.walk(folder):\n", + " for filename in [f for f in filenames if f.endswith(\".jpg\")]:\n", + " full_path = os.path.join(dirpath, filename)\n", + " imagelist.append(full_path)\n", + "\n", + "imagelist.sort() # Sort the images by name.\n", + "for i in range(0, len(imagelist)):\n", + " print(imagelist[i])\n", + "\n", + "# -------------- CONVERT TO PDF ------------ #\n", + "\n", + "name = input('Enter the PDF file name : ')\n", + "for image in imagelist:\n", + " pdf.add_page()\n", + " pdf.image(image, 0, 0, 210, 297) # 210 and 297 are the dimensions of an A4 size sheet.\n", + "pdf.output(folder + name + '.pdf', \"F\")\n", + " \n", + "print(\"PDF generated successfully!\")" ] }, { diff --git a/book.jpg b/book.jpg deleted file mode 100644 index 37ccd87dc68071799782ebe0d42435f5e4dbba37..0000000000000000000000000000000000000000 Binary files a/book.jpg and /dev/null differ diff --git a/book2.jpg b/book2.jpg deleted file mode 100644 index 6140f846c0e87fa2850a738ae7b736dd028f1b26..0000000000000000000000000000000000000000 Binary files a/book2.jpg and /dev/null differ diff --git a/contours/document.jpg b/contours/document.jpg new file mode 100644 index 0000000000000000000000000000000000000000..062132f436d67f87ce93ba88c8515743dc6f864b Binary files /dev/null and b/contours/document.jpg differ diff --git a/contours/receipt2.jpg b/contours/receipt2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..fae3687cc7f737191e7f9251389ce46a77b869e4 Binary files /dev/null and b/contours/receipt2.jpg differ diff --git a/contours/tilted receipt.jpg b/contours/tilted receipt.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e953c15edceab39692ef99c00df46df7b656a4a3 Binary files /dev/null and b/contours/tilted receipt.jpg differ diff --git a/images/book.jpg b/images/book.jpg deleted file mode 100644 index 37ccd87dc68071799782ebe0d42435f5e4dbba37..0000000000000000000000000000000000000000 Binary files a/images/book.jpg and /dev/null differ diff --git a/images/book2.jpg b/images/book2.jpg deleted file mode 100644 index 6140f846c0e87fa2850a738ae7b736dd028f1b26..0000000000000000000000000000000000000000 Binary files a/images/book2.jpg and /dev/null differ diff --git a/images/document.jpg b/images/document.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2f482058f6353cbc9b80d3df3affa79a05cc8030 Binary files /dev/null and b/images/document.jpg differ diff --git a/receipt.jpg b/images/receipt.jpg similarity index 100% rename from receipt.jpg rename to images/receipt.jpg diff --git a/images/tilted receipt.jpg b/images/tilted receipt.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b10b102d128b88d7252b1d0f3c1f44db26118fcc Binary files /dev/null and b/images/tilted receipt.jpg differ diff --git a/modified/book.jpg b/modified/book.jpg deleted file mode 100644 index 4a59aeb1fcd68e9ff12973ade5669be3060fad3b..0000000000000000000000000000000000000000 Binary files a/modified/book.jpg and /dev/null differ diff --git a/modified/book2.jpg b/modified/book2.jpg deleted file mode 100644 index 7670c878737ae5168a9ee21fb81893da51829485..0000000000000000000000000000000000000000 Binary files a/modified/book2.jpg and /dev/null differ diff --git a/modified/document.jpg b/modified/document.jpg new file mode 100644 index 0000000000000000000000000000000000000000..062132f436d67f87ce93ba88c8515743dc6f864b Binary files /dev/null and b/modified/document.jpg differ diff --git a/modified/receipt2.jpg b/modified/receipt2.jpg index e9a428cc4f6f8b851b4d9567d46a9178ebb8cc60..fae3687cc7f737191e7f9251389ce46a77b869e4 100644 Binary files a/modified/receipt2.jpg and b/modified/receipt2.jpg differ diff --git a/modified/tilted receipt.jpg b/modified/tilted receipt.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b736745a4852da42d9148b5174298aec54292ab1 Binary files /dev/null and b/modified/tilted receipt.jpg differ diff --git a/openCV_scanner.ipynb b/openCV_scanner.ipynb index bd154fb26b8e208c3292ca4c933e6a6d5a462e2b..aa6048d7a9c3c5a47ab94da4532646a732f5d6da 100644 --- a/openCV_scanner.ipynb +++ b/openCV_scanner.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 54, + "execution_count": 267, "metadata": { "scrolled": true }, @@ -11,12 +11,16 @@ "import numpy as np\n", "import cv2\n", "import glob\n", - "from matplotlib import pyplot as plt" + "from matplotlib import pyplot as plt\n", + "import tkinter as tk\n", + "from PIL import Image\n", + "from PIL import ImageTk\n", + "import os" ] }, { "cell_type": "code", - "execution_count": 55, + "execution_count": 268, "metadata": {}, "outputs": [], "source": [ @@ -40,7 +44,7 @@ }, { "cell_type": "code", - "execution_count": 56, + "execution_count": 269, "metadata": {}, "outputs": [], "source": [ @@ -74,7 +78,7 @@ }, { "cell_type": "code", - "execution_count": 57, + "execution_count": 270, "metadata": {}, "outputs": [], "source": [ @@ -112,7 +116,7 @@ }, { "cell_type": "code", - "execution_count": 58, + "execution_count": 271, "metadata": {}, "outputs": [], "source": [ @@ -132,14 +136,14 @@ }, { "cell_type": "code", - "execution_count": 59, + "execution_count": 272, "metadata": {}, "outputs": [], "source": [ "# 마우스를 이용하여 책의 꼭지점을 조정한다.\n", "def mouse_callback(event,x,y,flags,param):\n", " \n", - " global mouse_is_pressing,points\n", + " global mouse_is_pressing, points\n", "\n", " if step != 1:\n", " return\n", @@ -167,7 +171,7 @@ }, { "cell_type": "code", - "execution_count": 60, + "execution_count": 273, "metadata": {}, "outputs": [], "source": [ @@ -181,7 +185,26 @@ }, { "cell_type": "code", - "execution_count": 67, + "execution_count": 274, + "metadata": {}, + "outputs": [], + "source": [ + "def convert_to_tkimage():\n", + " global src\n", + " \n", + " gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)\n", + " _, binary = cv2.threshold(gray, 100, 255, cv2.THRESH_BINARY)\n", + "\n", + " img = Image.fromarray(binary)\n", + " imgtk = ImageTk.PhotoImage(image=img)\n", + "\n", + " label.config(image=imgtk)\n", + " label.image = imgtk" + ] + }, + { + "cell_type": "code", + "execution_count": 275, "metadata": {}, "outputs": [], "source": [ @@ -215,51 +238,52 @@ "\n", " kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))\n", " image_canny = cv2.morphologyEx(image_canny, cv2.MORPH_CLOSE, kernel, 1)\n", - " cv2.imwrite('./modified/' +i, image_canny)\n", - " print(i + \"save image_canny!\")\n", + " #cv2.imwrite('./modified/' +i, image_canny)\n", + " #print(i + \"save image_canny!\")\n", "\n", - " cv2.imshow('morphology', image_canny)\n", - " cv2.waitKey(0)\n", + " #cv2.imshow('morphology', image_canny)\n", + " #cv2.waitKey(0)\n", " # 캐니 에지 결과에서 컨투어를 검출하여 가장 큰 영역을 차지하는 컨투어를 찾는다.\n", " contours, hierarchy = cv2.findContours(image_canny, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)\n", " max_index = findMaxArea(contours) \n", " \n", - " \"\"\"\n", " #################이부분이 잘 이해가 안감.\n", + " #print(\"contours \", contours)\n", + " #print(\"max_index = \",max_index)\n", + " image_fixed = image.copy()\n", " if max_index < 0:\n", " print(\"max_index < 0 \" +i)\n", + " #print(points)\n", " return points\n", - " \"\"\"\n", "\n", " max_contour = contours[max_index]\n", "\n", "\n", - " image_contour = image.copy()\n", - " cv2.drawContours(image_contour, [max_contour], 0, (0, 0, 255), 3)\n", - " cv2.imwrite('./modified/' +i, image_contour)\n", - " print(i + \"save image_contour!\")\n", - " cv2.imshow('Contour', image_contour)\n", - " cv2.waitKey(0)\n", + " #image_contour = image.copy()\n", + " #cv2.drawContours(image_contour, [max_contour], 0, (0, 0, 255), 3)\n", + " #cv2.imwrite('./modified/' +i, image_contour)\n", + " #print(i + \"save image_contour!\")\n", + " #cv2.imshow('Contour', image_contour)\n", + " #cv2.waitKey(0)\n", "\n", " # approxPolyDP 함수를 사용하여 컨투어를 근사화하고 convex hull을 구한다.\n", " max_contour = cv2.approxPolyDP(max_contour,0.02*cv2.arcLength(max_contour,True),True)\n", " hull = cv2.convexHull(max_contour)\n", "\n", "\n", - " image_convexhull = image.copy()\n", - " cv2.drawContours(image_convexhull, [hull], 0, (255,255,0), 5)\n", - " cv2.imwrite('./modified/' +i, image_convexhull) \n", - " print(i + \"save image_convexhull!\")\n", - " cv2.imshow('convexHull', image_convexhull)\n", - " cv2.waitKey(0)\n", - " \n", + " #image_convexhull = image.copy()\n", + " #cv2.drawContours(image_convexhull, [hull], 0, (255,255,0), 5)\n", + " #cv2.imwrite('./modified/' +i, image_convexhull) \n", + " #print(i + \"save image_convexhull!\")\n", + " #cv2.imshow('convexHull', image_convexhull)\n", + " #cv2.waitKey(0)\n", " size = len(max_contour) \n", - " print(size)\n", + " print(\"len of max_contour\" ,size)\n", " if size == 4: # 책의 꼭지점을 구한다.\n", " for c in hull:\n", " points.append(c[0])\n", " points = np.array(points)\n", - " print(points)\n", + " #print(points)\n", "\n", " else: # 꼭지점이 5개 이상인 경우 경계 박스를 이용한다.\n", "\n", @@ -273,6 +297,7 @@ " if p[0] < 0 or p[0] > width-1 or p[1] < 0 or p[1] > height -1:\n", " found = True \n", " break\n", + " \n", "\n", " if found:\n", " points = np.array([[10,10], [width-11, 10], [width-11, height-11], [10, height-11]])\n", @@ -283,69 +308,132 @@ }, { "cell_type": "code", - "execution_count": 68, + "execution_count": 276, + "metadata": {}, + "outputs": [], + "source": [ + "def b1event():\n", + " print(sizes)\n", + " if sizes == 4:\n", + " cv2.namedWindow('input')\n", + " cv2.setMouseCallback(\"input\", mouse_callback, 0);\n", + " \n", + " step = 1\n", + " \n", + " while True:\n", + " image_result = image.copy()\n", + " for point in points:\n", + " cv2.circle(image_result, tuple(point), 10, (255,0,0), 3)\n", + " cv2.imshow('input', image_result)\n", + " \n", + " key = cv2.waitKey(1)\n", + " if key == 32:\n", + " break\n", + " image_final = transform(image, points)\n", + " \n", + " cv2.imshow('input', image_result)\n", + " cv2.imshow('result', image_final)\n", + " cv2.imwrite('./modified/' +i, image_final)\n", + " print(i + \" save final image!\")\n", + " \n", + " else:\n", + " cv2.imshow('input', image)\n", + " cv2.imwrite('./modified/' +i, image)\n", + " print(i + \" not yet..!\")\n", + " cv2.waitKey(0)\n", + " cv2.destroyAllWindows()\n", + " win.destroy()" + ] + }, + { + "cell_type": "code", + "execution_count": 277, + "metadata": {}, + "outputs": [], + "source": [ + "def b2event():\n", + " if sizes == 4:\n", + " image_final = transform(image, points)\n", + " cv2.imshow('result', image_final)\n", + " cv2.imwrite('./modified/' +i, image_final)\n", + " print(i + \" save thresh!\")\n", + " else:\n", + " cv2.imshow('input', image)\n", + " cv2.imwrite('./modified/' +i, image)\n", + " print(i + \" not yet..!\")\n", + " cv2.waitKey(0)\n", + " cv2.destroyAllWindows()\n", + " win.destroy()" + ] + }, + { + "cell_type": "code", + "execution_count": 278, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "book.jpgsave image_canny!\n", - "book.jpgsave image_contour!\n", - "book.jpgsave image_convexhull!\n", - "7\n", - "[10. 10.] [489. 10.] [489. 489.] [ 10. 489.]\n", - "20.0 499.0 978.0 499.0\n", - "book.jpgsave image_final!\n", - "book.jpg save thresh!\n", - "book2.jpgsave image_canny!\n", - "book2.jpgsave image_contour!\n", - "book2.jpgsave image_convexhull!\n", - "6\n", - "[10. 10.] [489. 10.] [489. 489.] [ 10. 489.]\n", - "20.0 499.0 978.0 499.0\n", - "book2.jpgsave image_final!\n", - "book2.jpg save thresh!\n", - "receipt2.jpgsave image_canny!\n", - "receipt2.jpgsave image_contour!\n", - "receipt2.jpgsave image_convexhull!\n", + "max_index < 0 document.jpg\n", + "size 0\n", + "0\n", + "document.jpg not yet..!\n", + "max_index < 0 receipt2.jpg\n", + "size 0\n", + "0\n", + "receipt2.jpg not yet..!\n", + "len of max_contour 8\n", + "size 4\n", "4\n", - "[[465 362]\n", - " [203 463]\n", - " [ 34 125]\n", - " [254 34]]\n", - "[ 34. 125.] [254. 34.] [465. 362.] [203. 463.]\n", - "159.0 288.0 827.0 666.0\n", - "receipt2.jpgsave image_final!\n", - "receipt2.jpg save thresh!\n" + "[13. 48.] [149. 27.] [170. 218.] [ 36. 238.]\n", + "61.0 176.0 388.0 274.0\n", + "tilted receipt.jpg save final image!\n" ] } ], "source": [ - "######################################################################\n", - "#이미지파일 한번에 여러개 받는 방법??\n", - "#\n", - "#\n", - "import os\n", + "mouse_is_pressing = False\n", "for i in os.listdir('./images/'): \n", " path = './images/'+i \n", " count = len(os.listdir('./images/'))\n", " \n", " \n", " image = cv2.imread(path, cv2.IMREAD_COLOR)\n", - " image=cv2.resize(image,(500,500))\n", + " #image=cv2.resize(image,(500,500))\n", " points = scanning(image)\n", + " sizes = len(points)\n", + " print(\"size\",sizes)\n", + " \n", + " win = tk.Tk()\n", + " win.title(\"Ask\")\n", + " win.geometry(\"500x500+50+50\")\n", + " win.resizable(False, False)\n", + "\n", + " lbl = tk.Label(win, text=\"마우스 입력 O/X?\")\n", + " #lbl.grid(row=1, column=1)\n", + " lbl.pack()\n", + "\n", + " cv2.imwrite('./contours/' +i, image) \n", + "\n", + " imgtk = ImageTk.PhotoImage(file = './contours/' +i, master=win)\n", + " label = tk.Label(win, image=imgtk)\n", + " label.pack()\n", + "\n", + " b1 = tk.Button(win, text='마우스 입력O', command = b1event)\n", + " b2 = tk.Button(win, text='마우스 입력X', command = b2event)\n", + " #b1.grid(row=3, column=1)\n", + " #b2.grid(row=3, column=2)\n", + " b1.pack()\n", + " b2.pack()\n", + "\n", + " win.mainloop()\n", " \n", + " \"\"\"\n", " size = len(points)\n", + " print(\"size\" ,size)\n", " if size == 4:\n", "\n", - " ##############################################################\n", - " # 여기에 사용자가 마우스 사용할지 안할지에대한 GUI 넣기?\n", - " # \n", - " #\n", - " #\n", - " ####################################################################\n", - " # 마우스 콜백 함수를 등록하고\n", " cv2.namedWindow('input')\n", " cv2.setMouseCallback(\"input\", mouse_callback, 0); \n", "\n", @@ -371,39 +459,83 @@ "\n", " cv2.imshow('input', image_result)\n", " cv2.imshow('result', image_final )\n", - "\n", " else:\n", " cv2.imshow('input', image)\n", - " \n", + " \n", " cv2.waitKey(0)\n", " cv2.destroyAllWindows()\n", - " #cv2.imwrite('./modified/' +i, image_final) \n", - " ################################################################\n", - " ############영수증의 경우 이것을 사용하면 글씨가 돋보임 ( 흑백대비)\n", - " gray = cv2.cvtColor(image_final, cv2.COLOR_BGR2GRAY)\n", + " win.destroy()\n", + " gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)\n", "\n", " sharpen = cv2.GaussianBlur(gray, (0,0), 3)\n", " sharpen = cv2.addWeighted(gray, 1.5, sharpen, -0.5, 0)\n", " thresh = cv2.adaptiveThreshold(sharpen, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 21, 15)\n", " cv2.imwrite('./modified/' +i, thresh)\n", " print(i + \" save thresh!\")\n", - " cv2.imshow('grayscale?', thresh)\n", + " cv2.imshow('final_image', thresh)\n", " cv2.waitKey(0)\n", " #cv2.imwrite('./modified/' +i, modified) \n", "\n", " #cv2.imshow( \"image\", image)\n", - " #cv2.waitKey(0)\n" + " #cv2.waitKey(0)\n", + "\n", + "\"\"\"" ] }, { "cell_type": "code", - "execution_count": 231, + "execution_count": 266, "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'fpdf'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m<ipython-input-266-d25ce1a2f34d>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;31m#이미지 저장\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0mfpdf\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mFPDF\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 3\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mPIL\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mImage\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mos\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'fpdf'" + ] + } + ], "source": [ "#이미지 저장\n", - "def save(image):\n", - " cv2.imwrite('./modified/modified.jpg', image) \n" + "##################아직 안합침################################\n", + "from fpdf import FPDF\n", + "from PIL import Image\n", + "import os\n", + "\n", + "pdf = FPDF()\n", + "imagelist = [] # Contains the list of all images to be converted to PDF.\n", + "\n", + "\n", + "# --------------- USER INPUT -------------------- #\n", + " \n", + "folder = \"\" # Folder containing all the images.\n", + "name = \"\" # Name of the output PDF file.\n", + "\n", + "# ------------- ADD ALL THE IMAGES IN A LIST ------------- #\n", + "\n", + "folder = input('Enter the path of the folder containing the images : ')\n", + "for dirpath, dirnames, filenames in os.walk(folder):\n", + " for filename in [f for f in filenames if f.endswith(\".jpg\")]:\n", + " full_path = os.path.join(dirpath, filename)\n", + " imagelist.append(full_path)\n", + "\n", + "imagelist.sort() # Sort the images by name.\n", + "for i in range(0, len(imagelist)):\n", + " print(imagelist[i])\n", + "\n", + "# -------------- CONVERT TO PDF ------------ #\n", + "\n", + "name = input('Enter the PDF file name : ')\n", + "for image in imagelist:\n", + " pdf.add_page()\n", + " pdf.image(image, 0, 0, 210, 297) # 210 and 297 are the dimensions of an A4 size sheet.\n", + "pdf.output(folder + name + '.pdf', \"F\")\n", + " \n", + "print(\"PDF generated successfully!\")" ] }, { diff --git a/receipt2.jpg b/receipt2.jpg deleted file mode 100644 index 03929d831c03842d6375aa051dd91b1362379008..0000000000000000000000000000000000000000 Binary files a/receipt2.jpg and /dev/null differ