diff --git a/environment.yml b/environment.yml deleted file mode 100644 index 1bb48ec..0000000 Binary files a/environment.yml and /dev/null differ diff --git a/img2xlsx.ipynb b/img2xlsx.ipynb index e105970..93cb411 100644 --- a/img2xlsx.ipynb +++ b/img2xlsx.ipynb @@ -2,48 +2,36 @@ "cells": [ { "cell_type": "code", - "execution_count": null, - "metadata": {}, + "execution_count": 1, + "metadata": { + "metadata": {} + }, "outputs": [], "source": [ - "from paddleocr import PaddleOCR\n", "import os\n", "import cv2\n", "import xlsxwriter\n", + "import numpy as np\n", "\n", "\n", - "def ocr_image(image_path, ocr):\n", - " result = ocr.ocr(image_path, cls=True)\n", - " return result[0][0][1][0]\n", + "def shear_img(image):\n", + " rows, cols, _ = image.shape\n", + " M = np.float32([[1, -0.22, 0], [0, 1, 0], [0, 0, 1]])\n", + " sheared_img = cv2.warpPerspective(image, M, (int(cols * 1.5), int(rows * 1.5)))\n", + " return cv2.flip(sheared_img, 1)\n", "\n", "\n", - "def cropUI(image_path):\n", - " # small opencv window to crop the image\n", - " image = cv2.imread(image_path)\n", - " r = cv2.selectROI(image)\n", - " cv2.destroyAllWindows()\n", - "\n", - " return r\n", - "\n", - "\n", - "def cropImage(image_path, r, flip, cropped_folder):\n", - " # crop the image and save it\n", - " image = cv2.imread(image_path)\n", - " cropped = image[int(r[1]) : int(r[1] + r[3]), int(r[0]) : int(r[0] + r[2])]\n", - "\n", - " # save with new name\n", - " if flip == \"y\":\n", - " cropped = cv2.flip(cropped, 1)\n", - "\n", - " # save in subfolder cropped\n", - " new_name = os.path.join(cropped_folder, image_path.split(\"/\")[-1])\n", - " cv2.imwrite(new_name, cropped)\n" + "def crop_image(sheared_image, r, target_path):\n", + " cropped = sheared_image[int(r[1]) : int(r[1] + r[3]), int(r[0]) : int(r[0] + r[2])]\n", + " return cropped" ] }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, + "execution_count": 2, + "metadata": { + "metadata": {} + }, "outputs": [], "source": [ "from datetime import datetime\n", @@ -76,52 +64,139 @@ " pass\n", " row += 1\n", "\n", - " workbook.close()\n" + " workbook.close()" ] }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, + "execution_count": 3, + "metadata": { + "metadata": {} + }, "outputs": [], "source": [ - "FOLDER = \"data/\"\n", - "# ocr settings\n", - "os.environ[\"KMP_DUPLICATE_LIB_OK\"] = \"TRUE\"\n", - "ocr = PaddleOCR(use_angle_cls=True, lang=\"en\")\n", + "def peaks(data, boxes=2):\n", + " # split data in boxes\n", + " data = np.array_split(data, boxes)\n", "\n", - "# *** start GUIs ***\n", - "images = [f for f in os.listdir(FOLDER) if f.endswith(\".jpg\")]\n", - "region = cropUI(os.path.join(FOLDER, images[0]))\n", + " # get the maximum value in each box\n", + " data = [np.max(d) for d in data]\n", + " data = [d > 150 for d in data]\n", + " return np.array(data).astype(int).tolist()\n", "\n", - "flip = input(\"Do you want to flip the images horizontaly? (y/n): \")\n", "\n", - "cropped_folder = os.path.join(FOLDER, \"cropped\")\n", - "if not os.path.exists(cropped_folder):\n", - " os.makedirs(cropped_folder)\n", + "digits = {\n", + " 0: [[1, 0, 1], [1, 1], [1, 1]],\n", + " 1: [[0, 0, 0], [0, 1], [0, 1]],\n", + " 2: [[1, 1, 1], [0, 1], [1, 0]],\n", + " 3: [[1, 1, 1], [0, 1], [0, 1]],\n", + " 4: [[0, 1, 0], [1, 1], [0, 1]],\n", + " 5: [[1, 1, 1], [1, 0], [0, 1]],\n", + " 6: [[1, 1, 1], [1, 0], [1, 1]],\n", + " 7: [[1, 0, 0], [0, 1], [0, 1]],\n", + " 8: [[1, 1, 1], [1, 1], [1, 1]],\n", + " 9: [[1, 1, 1], [1, 1], [0, 1]],\n", + "}\n", "\n", - "# *** start cropping ***\n", - "for image in images:\n", - " cropImage(os.path.join(FOLDER, image), region, flip, cropped_folder)\n", "\n", - "# *** start OCR ***\n", - "cropped_images = [f for f in os.listdir(cropped_folder) if f.endswith(\".jpg\")]\n", - "data = {}\n", - "for image in cropped_images:\n", - " try:\n", - " path = os.path.join(cropped_folder, image)\n", - " text = ocr_image(path, ocr)\n", - " except Exception as _:\n", - " print(\"Error in cropped image\")\n", - " continue\n", + "def ownOCR(image):\n", + " # get vertical pixel line in the middle of the image\n", + " vertical = image[:, image.shape[1] // 2, 0]\n", "\n", - " data[image] = text\n" + " # get two horizontal lines at 1/3 and 2/3 of the image\n", + " horizontal1 = image[image.shape[0] // 3, :, 0]\n", + " horizontal2 = image[2 * image.shape[0] // 3, :, 0]\n", + "\n", + " # get times it goes above 150, remove subsequent values\n", + " digit = [peaks(vertical, 3), peaks(horizontal1), peaks(horizontal2)]\n", + " digit = [key for key, value in digits.items() if value == digit]\n", + " return digit[0]" ] }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, + "execution_count": 4, + "metadata": { + "metadata": {} + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "list index out of range\n", + "list index out of range\n", + "list index out of range\n", + "list index out of range\n", + "list index out of range\n", + "list index out of range\n", + "list index out of range\n", + "list index out of range\n", + "list index out of range\n", + "list index out of range\n", + "list index out of range\n", + "list index out of range\n", + "list index out of range\n", + "list index out of range\n", + "list index out of range\n", + "list index out of range\n", + "list index out of range\n", + "list index out of range\n", + "list index out of range\n", + "list index out of range\n", + "list index out of range\n", + "list index out of range\n", + "list index out of range\n", + "list index out of range\n" + ] + } + ], + "source": [ + "folder = \"../../../Downloads/wetransfer_metingen-8-04-tot-15-40-5min_2024-04-15_0905/metingen 8-04 tot 15-40 (5min)/\"\n", + "images = [f for f in os.listdir(folder) if f.endswith(\".jpg\")]\n", + "cropped_folder = os.path.join(folder, \"cropped\")\n", + "os.makedirs(cropped_folder, exist_ok=True)\n", + "\n", + "# Initial image for ROI selection\n", + "init_image_path = os.path.join(folder, images[0])\n", + "init_image = cv2.imread(init_image_path)\n", + "sheared_init_image = shear_img(init_image)\n", + "\n", + "regions = []\n", + "for i in range(5): # Assume 5 regions as in your original code\n", + " r = cv2.selectROI(f\"Select the digit {i+1}\", sheared_init_image)\n", + " cv2.destroyAllWindows()\n", + " regions.append(r)\n", + "\n", + "data = {}\n", + "i = 0\n", + "# Process all images\n", + "for image_name in images:\n", + " try:\n", + " image_path = os.path.join(folder, image_name)\n", + " image = cv2.imread(image_path)\n", + " sheared_image = shear_img(image)\n", + "\n", + " for idx, region in enumerate(regions):\n", + " target_path = os.path.join(cropped_folder, f\"{image_name[:-4]}_{idx+1}.jpg\")\n", + " cropped = crop_image(sheared_image, region, target_path)\n", + " digit = ownOCR(cropped)\n", + "\n", + " if image_name not in data:\n", + " data[image_name] = \"\"\n", + "\n", + " data[image_name] += str(digit)\n", + " except Exception as e:\n", + " print(e)\n", + " continue" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "metadata": {} + }, "outputs": [], "source": [ "data2excel(data)" @@ -130,7 +205,9 @@ { "cell_type": "code", "execution_count": 12, - "metadata": {}, + "metadata": { + "metadata": {} + }, "outputs": [], "source": [ "# clean excel file\n", @@ -146,9 +223,10 @@ " row = 0\n", " for key, value in data.items():\n", " try:\n", + " value = \"6\"+value[1:]\n", " worksheet.write(row, 2, float(value[:6]))\n", " date = key.split(\" \", 1)[1][:-4]\n", - " writeDate(worksheet, row, 0, date, dateFormat)\n", + " writeDate(worksheet, row, 0, date, dateFormat) \n", " worksheet.write(row, 1, value)\n", " except Exception as _:\n", " continue\n", @@ -157,6 +235,7 @@ "\n", " workbook.close()\n", "\n", + "\n", "data2cleanexcel(data)" ] } diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index f6cbdea..0000000 --- a/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -paddlepaddle==2.6.0 -paddleocr>=2.0.1 \ No newline at end of file