diff --git a/.ipynb_checkpoints/openCV_scanner-checkpoint.ipynb b/.ipynb_checkpoints/openCV_scanner-checkpoint.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..bd154fb26b8e208c3292ca4c933e6a6d5a462e2b
--- /dev/null
+++ b/.ipynb_checkpoints/openCV_scanner-checkpoint.ipynb
@@ -0,0 +1,438 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 54,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "import numpy as np\n",
+    "import cv2\n",
+    "import glob\n",
+    "from matplotlib import pyplot as plt"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 55,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def findMaxArea(contours):  \n",
+    "    max_area = -1\n",
+    "    max_index = -1\n",
+    "    for i,contour in enumerate(contours):\n",
+    "        area = cv2.contourArea(contour)\n",
+    "        x,y,w,h = cv2.boundingRect(contour)\n",
+    "        if (w*h)*0.4 > area:\n",
+    "            continue\n",
+    "        if w > h:\n",
+    "            continue\n",
+    "        if area > max_area:\n",
+    "            max_area = area\n",
+    "            max_index = i\n",
+    "    if max_area < 10000:\n",
+    "        max_index = -1\n",
+    "    return max_index"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 56,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def transform(img_input, points):\n",
+    "    # 다음 순서롤 갖도록 꼭지점을 정렬한다.\n",
+    "    # top left, top right, bottom right, bottom left\n",
+    "    points = sort_points(points)\n",
+    "    topLeft, topRight, bottomRight, bottomLeft = points\n",
+    "    print(topLeft, topRight, bottomRight, bottomLeft)\n",
+    "    print(topLeft[0] + topLeft[1], topRight[0]+topRight[1],\n",
+    "     bottomRight[0]+bottomRight[1], bottomLeft[0]+bottomLeft[1])\n",
+    " \n",
+    "    # 변환 후 책의 너비와 높이를 결정한다.\n",
+    "    topWidth = distance(bottomLeft, bottomRight)\n",
+    "    bottomWidth = distance(topLeft, topRight)\n",
+    "    maxWidth = max(int(topWidth), int(bottomWidth))\n",
+    " \n",
+    "    leftHeight = distance(topLeft, bottomLeft)\n",
+    "    rightHeight = distance(topRight, bottomRight)\n",
+    "    maxHeight = max(int(leftHeight), int(rightHeight))\n",
+    " \n",
+    "    # 정면에서 바라본 책의 좌표를 결정한다.\n",
+    "    dst = np.array([[0, 0],[maxWidth - 1, 0],\n",
+    "        [maxWidth - 1, maxHeight - 1],[0, maxHeight - 1]], dtype = \"float32\")\n",
+    " \n",
+    "    H = cv2.getPerspectiveTransform(points, dst)\n",
+    "    img_warped = cv2.warpPerspective(img_input, H, (maxWidth, maxHeight))\n",
+    " \n",
+    "    return img_warped\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 57,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def sort_points(points):\n",
+    "\n",
+    "    points = points.astype(np.float32)\n",
+    "\n",
+    "    new_points = np.zeros((4, 2), dtype = \"float32\")\n",
+    " \n",
+    "\n",
+    "    s = points.sum(axis = 1)\n",
+    "    min_index = np.argmin(s)\n",
+    "    new_points[0] = points[min_index]\n",
+    "    points = np.delete(points, min_index, axis = 0)\n",
+    "\n",
+    "    s = points.sum(axis = 1)\n",
+    "    max_index = np.argmax(s)\n",
+    "    new_points[2] = points[max_index]\n",
+    "    points = np.delete(points, max_index, axis = 0)\n",
+    "\n",
+    "    v0 = points[0] - new_points[0]\n",
+    "    v1 = points[1] - new_points[0]\n",
+    "\n",
+    "    angle = angle_between(v0, v1)\n",
+    "\n",
+    "    if angle < 0:\n",
+    "        new_points[1] = points[1]\n",
+    "        new_points[3] = points[0]\n",
+    "    else:\n",
+    "        new_points[1] = points[0]\n",
+    "        new_points[3] = points[1]\n",
+    " \n",
+    "    return new_points"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 58,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def angle_between(A, B):\n",
+    "\n",
+    "    x1 = A[0]\n",
+    "    y1 = A[1]\n",
+    "    x2 = B[0]\n",
+    "    y2 = B[1]\n",
+    "\n",
+    "    dot = x1*x2 + y1*y2      \n",
+    "    det = x1*y2 - y1*x2     \n",
+    "    angle = np.arctan2(det, dot) * 180/np.pi  \n",
+    "\n",
+    "    return angle"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 59,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# 마우스를 이용하여 책의 꼭지점을 조정한다.\n",
+    "def mouse_callback(event,x,y,flags,param):\n",
+    "    \n",
+    "    global mouse_is_pressing,points\n",
+    "\n",
+    "    if step != 1:\n",
+    "        return\n",
+    "\n",
+    "    if event == cv2.EVENT_MOUSEMOVE: \n",
+    "        if mouse_is_pressing == True:  ## 마우스가 움직이고, 눌린상태일때\n",
+    "\n",
+    "            for i,point in enumerate(points):\n",
+    "                if distance((x,y), point) < 15:  ##마우스의  좌표와, 포인트(꼭지점) 의 거리가 가깝다면\n",
+    "                    points[i][0] = x             ##꼭지점을 이동한다\n",
+    "                    points[i][1] = y\n",
+    "                    break    \n",
+    "          \n",
+    "    elif event == cv2.EVENT_LBUTTONDOWN:         ##마우스버튼이 눌린상태에서, 꼭짓점과의 거리가 가깝다면\n",
+    "                                                  ##press 를 Ture로 바꾼다.\n",
+    "        for point in points:\n",
+    "            if distance((x,y), point) < 10:\n",
+    "                mouse_is_pressing = True\n",
+    "                break\n",
+    "\n",
+    "    elif event == cv2.EVENT_LBUTTONUP:           ## 마우스가 안눌려있으면, press 를 false로 바꿈\n",
+    "\n",
+    "        mouse_is_pressing = False"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 60,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def distance(point1, point2):\n",
+    "    \n",
+    "    x1,y1 = point1\n",
+    "    x2,y2 = point2\n",
+    " \n",
+    "    return int(np.sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2)))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 67,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def scanning(image):\n",
+    "    #grabcut , 배경 제거\n",
+    "    points = []\n",
+    "    height,width =image.shape[:2]\n",
+    "    image_mask = np.zeros(image.shape[:2], np.uint8)\n",
+    "\n",
+    "    bgdModel = np.zeros((1,65),np.float64)\n",
+    "    fgdModel = np.zeros((1,65),np.float64)\n",
+    "\n",
+    "    rect = (10,10,width-30,height-30)\n",
+    "    cv2.grabCut(image, image_mask, rect, bgdModel,fgdModel, 3, cv2.GC_INIT_WITH_RECT)\n",
+    "\n",
+    "    image_mask = np.where((image_mask==2)|(image_mask==0), 0, 1).astype('uint8')\n",
+    "    image_grabcut = image*image_mask[:,:,np.newaxis]\n",
+    "\n",
+    "    #cv2.imshow('grabCut', image_grabcut)\n",
+    "    #cv2.waitKey(0)\n",
+    "    \n",
+    "    #케니에지 디텍션을 이용하여 에지 검출\n",
+    "    image_gray = cv2.cvtColor(image_grabcut, cv2.COLOR_BGR2GRAY);\n",
+    "    image_canny = cv2.Canny(image_gray, 30, 90);\n",
+    "\n",
+    "\n",
+    "    #cv2.imshow('Canny', image_canny)\n",
+    "    #cv2.waitKey(0)\n",
+    "\n",
+    "    #모폴로지 클로즈 연산\n",
+    "\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",
+    "\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",
+    "    if max_index < 0:\n",
+    "        print(\"max_index < 0 \" +i)\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",
+    "\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",
+    "    size = len(max_contour) \n",
+    "    print(size)\n",
+    "    if size == 4: # 책의 꼭지점을 구한다.\n",
+    "        for c in hull:\n",
+    "            points.append(c[0])\n",
+    "        points = np.array(points)\n",
+    "        print(points)\n",
+    "\n",
+    "    else: # 꼭지점이 5개 이상인 경우 경계 박스를 이용한다.\n",
+    "\n",
+    "        rect = cv2.minAreaRect(hull)\n",
+    "        box = cv2.boxPoints(rect)\n",
+    "        points = np.int0(box.tolist())\n",
+    "\n",
+    "        # 검출된 꼭지점이 이미지 범위를 벗어난 경우 책 꼭지점 처리\n",
+    "    found = False\n",
+    "    for p in points:\n",
+    "        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",
+    "    if found:\n",
+    "        points = np.array([[10,10], [width-11, 10], [width-11, height-11], [10, height-11]])\n",
+    "    return points\n",
+    "\n",
+    "   "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 68,
+   "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",
+      "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"
+     ]
+    }
+   ],
+   "source": [
+    "######################################################################\n",
+    "#이미지파일 한번에 여러개 받는 방법??\n",
+    "#\n",
+    "#\n",
+    "import os\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",
+    "    points = scanning(image)\n",
+    "    \n",
+    "    size = len(points)\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",
+    "\n",
+    "        step = 1\n",
+    "\n",
+    "      # 마우스를 이용하여 꼭지점을 조정한다.\n",
+    "        while True:\n",
+    "\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",
+    "\n",
+    "      # 꼭지점을 이용하여 정면에서 본 책으로 변환한다.\n",
+    "        image_final = transform(image, points )\n",
+    "        cv2.imwrite('./modified/' +i, image_final)\n",
+    "        print(i + \"save image_final!\")\n",
+    "\n",
+    "        cv2.imshow('input', image_result)\n",
+    "        cv2.imshow('result', image_final )\n",
+    "\n",
+    "    else:\n",
+    "        cv2.imshow('input', image)\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",
+    "\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.waitKey(0)\n",
+    "    #cv2.imwrite('./modified/' +i, modified) \n",
+    "\n",
+    "    #cv2.imshow( \"image\", image)\n",
+    "    #cv2.waitKey(0)\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 231,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#이미지 저장\n",
+    "def save(image):\n",
+    "    cv2.imwrite('./modified/modified.jpg', image) \n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "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.5"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/images/receipt.jpg b/images/receipt.jpg
deleted file mode 100644
index 6a1fea89295717a2dc66f273876b1f6e79f98053..0000000000000000000000000000000000000000
Binary files a/images/receipt.jpg and /dev/null differ
diff --git a/modified/book.jpg b/modified/book.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..4a59aeb1fcd68e9ff12973ade5669be3060fad3b
Binary files /dev/null and b/modified/book.jpg differ
diff --git a/modified/book2.jpg b/modified/book2.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..7670c878737ae5168a9ee21fb81893da51829485
Binary files /dev/null and b/modified/book2.jpg differ
diff --git a/modified/modified.jpg b/modified/modified.jpg
deleted file mode 100644
index 6380610691871f1e8cac343bc0c0ce2e38c198bf..0000000000000000000000000000000000000000
Binary files a/modified/modified.jpg and /dev/null differ
diff --git a/modified/receipt2.jpg b/modified/receipt2.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..e9a428cc4f6f8b851b4d9567d46a9178ebb8cc60
Binary files /dev/null and b/modified/receipt2.jpg differ
diff --git a/openCV_scanner.ipynb b/openCV_scanner.ipynb
index ad83d382691c5e317746743f63454d40bc7ec7fb..bd154fb26b8e208c3292ca4c933e6a6d5a462e2b 100644
--- a/openCV_scanner.ipynb
+++ b/openCV_scanner.ipynb
@@ -2,7 +2,7 @@
  "cells": [
   {
    "cell_type": "code",
-   "execution_count": 78,
+   "execution_count": 54,
    "metadata": {
     "scrolled": true
    },
@@ -16,7 +16,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 79,
+   "execution_count": 55,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -40,7 +40,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 80,
+   "execution_count": 56,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -74,7 +74,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 81,
+   "execution_count": 57,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -112,7 +112,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 82,
+   "execution_count": 58,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -132,7 +132,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 83,
+   "execution_count": 59,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -167,7 +167,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 84,
+   "execution_count": 60,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -181,247 +181,93 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 96,
+   "execution_count": 67,
    "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "\"\\ncv2.imshow('images',image)\\ncv2.waitKey(0)\\n\""
-      ]
-     },
-     "execution_count": 96,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
+   "outputs": [],
    "source": [
-    "image = cv2.imread('./images/receipt.jpg')  \n",
+    "def scanning(image):\n",
+    "    #grabcut , 배경 제거\n",
+    "    points = []\n",
+    "    height,width =image.shape[:2]\n",
+    "    image_mask = np.zeros(image.shape[:2], np.uint8)\n",
     "\n",
-    "# rgb 이미지 보기\n",
-    "\"\"\"\n",
-    "cv2.imshow('images',image)\n",
-    "cv2.waitKey(0)\n",
-    "\"\"\""
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 97,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "\"\\npath = 'C:/Users/User/Desktop/opencv/images' # 폴더 경로\\nos.chdir(path) # 해당 폴더로 이동\\n\\nfiles = os.listdir(path) # 해당 폴더에 있는 파일 이름을 리스트 형태로 받음\\npng_img = []\\njpg_img = []\\nfor file in files:\\n    if '.png' in file: \\n        f = cv2.imread(file)\\n        png_img.append(f)\\n    if '.jpg' in file: \\n        f = cv2.imread(file)\\n        jpg_img.append(f)\\n\""
-      ]
-     },
-     "execution_count": 97,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "######################################################################\n",
-    "#이미지파일 한번에 여러개 받는 방법??\n",
-    "#\n",
-    "#\n",
-    "\"\"\"\n",
-    "path = 'C:/Users/User/Desktop/opencv/images' # 폴더 경로\n",
-    "os.chdir(path) # 해당 폴더로 이동\n",
-    "\n",
-    "files = os.listdir(path) # 해당 폴더에 있는 파일 이름을 리스트 형태로 받음\n",
-    "png_img = []\n",
-    "jpg_img = []\n",
-    "for file in files:\n",
-    "    if '.png' in file: \n",
-    "        f = cv2.imread(file)\n",
-    "        png_img.append(f)\n",
-    "    if '.jpg' in file: \n",
-    "        f = cv2.imread(file)\n",
-    "        jpg_img.append(f)\n",
-    "\"\"\""
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 98,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "\"\\ncv2.imshow('grabCut', image_grabcut)\\ncv2.waitKey(0)\\n\""
-      ]
-     },
-     "execution_count": 98,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "#grabcut , 배경 제거\n",
-    "points = []\n",
-    "height,width =image.shape[:2]\n",
-    "image_mask = np.zeros(image.shape[:2], np.uint8)\n",
-    "\n",
-    "bgdModel = np.zeros((1,65),np.float64)\n",
-    "fgdModel = np.zeros((1,65),np.float64)\n",
-    "\n",
-    "rect = (10,10,width-30,height-30)\n",
-    "cv2.grabCut(image, image_mask, rect, bgdModel,fgdModel, 3, cv2.GC_INIT_WITH_RECT)\n",
-    "\n",
-    "image_mask = np.where((image_mask==2)|(image_mask==0), 0, 1).astype('uint8')\n",
-    "image_grabcut = image*image_mask[:,:,np.newaxis]\n",
-    "\"\"\"\n",
-    "cv2.imshow('grabCut', image_grabcut)\n",
-    "cv2.waitKey(0)\n",
-    "\"\"\""
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 109,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "-1"
-      ]
-     },
-     "execution_count": 109,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "#케니에지 디텍션을 이용하여 에지 검출\n",
-    "image_gray = cv2.cvtColor(image_grabcut, cv2.COLOR_BGR2GRAY);\n",
-    "image_canny = cv2.Canny(image_gray, 30, 90);\n",
-    "\n",
-    "\"\"\"\n",
-    "cv2.imshow('Canny', image_canny)\n",
-    "cv2.waitKey(0)\n",
-    "\"\"\""
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 110,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "-1"
-      ]
-     },
-     "execution_count": 110,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "#모폴로지 클로즈 연산\n",
+    "    bgdModel = np.zeros((1,65),np.float64)\n",
+    "    fgdModel = np.zeros((1,65),np.float64)\n",
     "\n",
-    "kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))\n",
-    "image_canny = cv2.morphologyEx(image_canny, cv2.MORPH_CLOSE, kernel, 1)\n",
+    "    rect = (10,10,width-30,height-30)\n",
+    "    cv2.grabCut(image, image_mask, rect, bgdModel,fgdModel, 3, cv2.GC_INIT_WITH_RECT)\n",
     "\n",
-    "\"\"\"\n",
-    "cv2.imshow('morphology', image_canny)\n",
-    "cv2.waitKey(0)\n",
-    "\"\"\""
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 101,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "\"\\nimage_contour = image.copy()\\ncv2.drawContours(image_contour, [max_contour], 0, (0, 0, 255), 3)\\ncv2.imshow('Contour', image_contour)\\ncv2.waitKey(0)\\n\""
-      ]
-     },
-     "execution_count": 101,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "# 캐니 에지 결과에서 컨투어를 검출하여 가장 큰 영역을 차지하는 컨투어를 찾는다.\n",
-    "contours, hierarchy = cv2.findContours(image_canny, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)\n",
-    "max_index = findMaxArea(contours) \n",
-    "\"\"\"\n",
-    "if max_index < 0:\n",
-    "    return points\n",
-    "\"\"\"\n",
-    "if max_index < 0:\n",
-    "    print(points)\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.imshow('Contour', image_contour)\n",
-    "cv2.waitKey(0)\n",
-    "\"\"\""
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 111,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "-1"
-      ]
-     },
-     "execution_count": 111,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "# 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",
-    "img_convexhull = image.copy()\n",
-    "cv2.drawContours(img_convexhull, [hull], 0, (255,255,0), 5)\n",
-    "cv2.imshow('convexHull', img_convexhull)\n",
-    "cv2.waitKey(0)\n",
-    "\"\"\""
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 103,
-   "metadata": {
-    "scrolled": true
-   },
-   "outputs": [],
-   "source": [
-    "size = len(max_contour) \n",
+    "    image_mask = np.where((image_mask==2)|(image_mask==0), 0, 1).astype('uint8')\n",
+    "    image_grabcut = image*image_mask[:,:,np.newaxis]\n",
     "\n",
-    "if size == 4: # 책의 꼭지점을 구한다.\n",
-    "    for c in hull:\n",
-    "        points.append(c[0])\n",
-    "    points = np.array(points)\n",
-    "    print(points)\n",
+    "    #cv2.imshow('grabCut', image_grabcut)\n",
+    "    #cv2.waitKey(0)\n",
+    "    \n",
+    "    #케니에지 디텍션을 이용하여 에지 검출\n",
+    "    image_gray = cv2.cvtColor(image_grabcut, cv2.COLOR_BGR2GRAY);\n",
+    "    image_canny = cv2.Canny(image_gray, 30, 90);\n",
+    "\n",
+    "\n",
+    "    #cv2.imshow('Canny', image_canny)\n",
+    "    #cv2.waitKey(0)\n",
+    "\n",
+    "    #모폴로지 클로즈 연산\n",
+    "\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",
+    "\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",
+    "    if max_index < 0:\n",
+    "        print(\"max_index < 0 \" +i)\n",
+    "        return points\n",
+    "    \"\"\"\n",
     "\n",
-    "else: # 꼭지점이 5개 이상인 경우 경계 박스를 이용한다.\n",
-    "      \n",
-    "    rect = cv2.minAreaRect(hull)\n",
-    "    box = cv2.boxPoints(rect)\n",
-    "    points = np.int0(box.tolist())\n",
+    "    max_contour = contours[max_index]\n",
     "\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",
+    "\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",
+    "    size = len(max_contour) \n",
+    "    print(size)\n",
+    "    if size == 4: # 책의 꼭지점을 구한다.\n",
+    "        for c in hull:\n",
+    "            points.append(c[0])\n",
+    "        points = np.array(points)\n",
+    "        print(points)\n",
+    "\n",
+    "    else: # 꼭지점이 5개 이상인 경우 경계 박스를 이용한다.\n",
+    "\n",
+    "        rect = cv2.minAreaRect(hull)\n",
+    "        box = cv2.boxPoints(rect)\n",
+    "        points = np.int0(box.tolist())\n",
+    "\n",
+    "        # 검출된 꼭지점이 이미지 범위를 벗어난 경우 책 꼭지점 처리\n",
     "    found = False\n",
     "    for p in points:\n",
     "        if p[0] < 0 or p[0] > width-1 or p[1] < 0 or p[1] > height -1:\n",
@@ -430,159 +276,134 @@
     "\n",
     "    if found:\n",
     "        points = np.array([[10,10], [width-11, 10], [width-11, height-11], [10, height-11]])\n",
-    "    \"\"\"\n",
     "    return points\n",
-    "    \"\"\""
+    "\n",
+    "   "
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 104,
+   "execution_count": 68,
    "metadata": {},
    "outputs": [
     {
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "[66. 24.] [1428.   10.] [1428. 1041.] [  10. 1041.]\n",
-      "90.0 1438.0 2469.0 1051.0\n",
-      "END\n"
+      "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",
+      "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"
      ]
     }
    ],
    "source": [
-    "size = len(points)\n",
-    "if size == 4:\n",
-    "\n",
-    "##############################################################\n",
-    "#    여기에 사용자가 마우스 사용할지 안할지에대한 GUI 넣기?\n",
-    "#    \n",
+    "######################################################################\n",
+    "#이미지파일 한번에 여러개 받는 방법??\n",
     "#\n",
     "#\n",
-    "####################################################################\n",
-    "    # 마우스 콜백 함수를 등록하고\n",
-    "    cv2.namedWindow('input')\n",
-    "    cv2.setMouseCallback(\"input\", mouse_callback, 0);  \n",
+    "import os\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",
+    "    points = scanning(image)\n",
+    "    \n",
+    "    size = len(points)\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",
-    "    step = 1\n",
     "\n",
-    "  # 마우스를 이용하여 꼭지점을 조정한다.\n",
-    "    while True:\n",
+    "        step = 1\n",
     "\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",
+    "      # 마우스를 이용하여 꼭지점을 조정한다.\n",
+    "        while True:\n",
     "\n",
-    "  # 꼭지점을 이용하여 정면에서 본 책으로 변환한다.\n",
-    "    image_final = transform(image, points )\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",
     "\n",
-    "    cv2.imshow('input', image_result)\n",
-    "    cv2.imshow('result', image_final )\n",
-    "    \n",
-    "    print(\"END\")\n",
+    "      # 꼭지점을 이용하여 정면에서 본 책으로 변환한다.\n",
+    "        image_final = transform(image, points )\n",
+    "        cv2.imwrite('./modified/' +i, image_final)\n",
+    "        print(i + \"save image_final!\")\n",
     "\n",
-    "else:\n",
-    "    cv2.imshow('input', image)\n",
+    "        cv2.imshow('input', image_result)\n",
+    "        cv2.imshow('result', image_final )\n",
     "\n",
-    "cv2.waitKey(0)\n",
-    "cv2.destroyAllWindows()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 105,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "-1"
-      ]
-     },
-     "execution_count": 105,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "################################################################\n",
-    "############영수증의 경우 이것을 사용하면 글씨가 돋보임 ( 흑백대비)\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.imshow('grayscale?', thresh)\n",
-    "cv2.waitKey(0)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 106,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "True"
-      ]
-     },
-     "execution_count": 106,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "cv2.imwrite('C:/Users/User/Desktop/opencv/modified/modified.jpg', image_final) \n",
-    "#이미지 저장"
+    "    else:\n",
+    "        cv2.imshow('input', image)\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",
+    "\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.waitKey(0)\n",
+    "    #cv2.imwrite('./modified/' +i, modified) \n",
+    "\n",
+    "    #cv2.imshow( \"image\", image)\n",
+    "    #cv2.waitKey(0)\n"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 107,
+   "execution_count": 231,
    "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "\"\\nimport cv2\\nimage = cv2.imread('./images/book.jpg')  \\n\\n# rgb 이미지 보기\\ncv2.imshow('images',image)                                   \\ncv2.resizeWindow('images', 600, 600)\\ncv2.waitKey(0)\\ndef onMouse(event, x, y, flags, param): # 아무스 콜백 함수 구현 ---①\\n    print(event, x, y, )                # 파라미터 출력\\n    if event == cv2.EVENT_LBUTTONDOWN:  # 왼쪽 버튼 누름인 경우 ---②\\n        cv2.circle(image, (x,y), 30, (0,0,0), -1) # 지름 30 크기의 검은색 원을 해당 좌표에 그림\\n        cv2.imshow(images, image)          # 그려진 이미지를 다시 표시 ---③\\ncv2.setMouseCallback(images, onMouse)    # 마우스 콜백 함수를 GUI 윈도우에 등록 ---④\\n\""
-      ]
-     },
-     "execution_count": 107,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
+   "outputs": [],
    "source": [
-    "\"\"\"\n",
-    "import cv2\n",
-    "image = cv2.imread('./images/book.jpg')  \n",
-    "\n",
-    "# rgb 이미지 보기\n",
-    "cv2.imshow('images',image)                                   \n",
-    "cv2.resizeWindow('images', 600, 600)\n",
-    "cv2.waitKey(0)\n",
-    "def onMouse(event, x, y, flags, param): # 아무스 콜백 함수 구현 ---①\n",
-    "    print(event, x, y, )                # 파라미터 출력\n",
-    "    if event == cv2.EVENT_LBUTTONDOWN:  # 왼쪽 버튼 누름인 경우 ---②\n",
-    "        cv2.circle(image, (x,y), 30, (0,0,0), -1) # 지름 30 크기의 검은색 원을 해당 좌표에 그림\n",
-    "        cv2.imshow(images, image)          # 그려진 이미지를 다시 표시 ---③\n",
-    "cv2.setMouseCallback(images, onMouse)    # 마우스 콜백 함수를 GUI 윈도우에 등록 ---④\n",
-    "\"\"\"\n",
-    "\n",
-    "######################################################################################################\n",
-    "# 추가로 해야할것 :\n",
-    "# 1. 마우스 입력을 받을때와 안받을때 구분짓기\n",
-    "# 2. 폴더채로 이미지파일 받아와서 한번에 처리하기.\n",
-    "# 3. 흑백 색 강조하여 이미지 깔끔하게 만들기\n",
-    "# 4. 파일 저장형식을 사용자가 원하는대로 만들기"
+    "#이미지 저장\n",
+    "def save(image):\n",
+    "    cv2.imwrite('./modified/modified.jpg', image) \n"
    ]
   },
   {