own ocr
parent
bf78be22ca
commit
2bb6a15180
BIN
environment.yml
BIN
environment.yml
Binary file not shown.
201
img2xlsx.ipynb
201
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)"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
paddlepaddle==2.6.0
|
||||
paddleocr>=2.0.1
|
Loading…
Reference in New Issue