Spaces:
Sleeping
Sleeping
Upload 7 files
Browse files- src/__init__.py +7 -0
- src/document.py +45 -0
- src/llms.py +33 -0
- src/ocr_model.py +25 -0
- src/pipeline.py +34 -0
- src/prompts.py +43 -0
- src/setting.py +3 -0
src/__init__.py
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import logging
|
2 |
+
import os
|
3 |
+
from pathlib import Path
|
4 |
+
|
5 |
+
logging.basicConfig(level=logging.INFO,format = "[%(asctime)s]: %(message)s:")
|
6 |
+
project_name = "medical_report_analysis"
|
7 |
+
|
src/document.py
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import fitz
|
2 |
+
from PIL import Image
|
3 |
+
from src.setting import LOCAL_TEST
|
4 |
+
import numpy as np
|
5 |
+
from src import logging
|
6 |
+
|
7 |
+
|
8 |
+
class PDF_Processing:
|
9 |
+
def __init__(self):
|
10 |
+
pass
|
11 |
+
|
12 |
+
def pdf_to_image(file):
|
13 |
+
"""
|
14 |
+
This function will take pdf file and convert first page into image and return it.
|
15 |
+
|
16 |
+
LOCAL_TEST : True / False
|
17 |
+
|
18 |
+
"""
|
19 |
+
|
20 |
+
try:
|
21 |
+
if LOCAL_TEST:
|
22 |
+
pdf_file = fitz.open(filename=file,filetype="pdf")
|
23 |
+
else:
|
24 |
+
pdf_file = fitz.open(stream=file.read(), filetype="pdf")
|
25 |
+
|
26 |
+
page = pdf_file.load_page(0)
|
27 |
+
pix = page.get_pixmap(matrix=fitz.Matrix(300/72, 300/72)) # 300 DPI
|
28 |
+
image_bytes = pix.samples
|
29 |
+
image = Image.frombytes("RGB", [pix.width, pix.height], image_bytes)
|
30 |
+
image_np = np.array(image)
|
31 |
+
|
32 |
+
return image_np
|
33 |
+
except Exception as e:
|
34 |
+
logging.info(f"Error {e} : pdf_to_image")
|
35 |
+
|
36 |
+
def load_image(file):
|
37 |
+
"""
|
38 |
+
This function take image and return numpy array
|
39 |
+
"""
|
40 |
+
try:
|
41 |
+
image = Image.open(file)
|
42 |
+
image_np = np.array(image)
|
43 |
+
return image_np
|
44 |
+
except Exception as e:
|
45 |
+
logging.info(f"Error {e} : load_image")
|
src/llms.py
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import google.generativeai as genai
|
3 |
+
from src.setting import MODEL_NAME
|
4 |
+
from dotenv import load_dotenv
|
5 |
+
from src.prompts import Prompts
|
6 |
+
from src import logging
|
7 |
+
load_dotenv()
|
8 |
+
|
9 |
+
|
10 |
+
class LLM:
|
11 |
+
def __init__(self):
|
12 |
+
self.API_KEY = os.getenv("GOOGLE_API_KEY")
|
13 |
+
|
14 |
+
def get_json(self,input_data:str,key:str = None):
|
15 |
+
"""
|
16 |
+
Input_data : It is a string input. It can take json as well as raw text
|
17 |
+
|
18 |
+
key : Default None.
|
19 |
+
It can Json and None. If the input_data is json than key will json else None
|
20 |
+
|
21 |
+
"""
|
22 |
+
if key == "json":
|
23 |
+
prompts = Prompts.text_json_prompt().format(text = input_data)
|
24 |
+
else:
|
25 |
+
prompts = Prompts.final_prompt().format(json_data = input_data)
|
26 |
+
|
27 |
+
try:
|
28 |
+
genai.configure(api_key = self.API_KEY)
|
29 |
+
model = genai.GenerativeModel(model_name=MODEL_NAME)
|
30 |
+
response = model.generate_content(prompts)
|
31 |
+
return response.text
|
32 |
+
except Exception as e:
|
33 |
+
logging.info(f"Error :{e} : LLM.get_json")
|
src/ocr_model.py
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from easyocr import Reader
|
2 |
+
from src.setting import OCR_MODEL_LANGUAGE
|
3 |
+
from src import logging
|
4 |
+
|
5 |
+
class OCR:
|
6 |
+
def __init__(self):
|
7 |
+
pass
|
8 |
+
|
9 |
+
def extract_text(image):
|
10 |
+
"""
|
11 |
+
image : image or numpy array.
|
12 |
+
|
13 |
+
This function is for OCR
|
14 |
+
|
15 |
+
Return : raw text from ocr model
|
16 |
+
|
17 |
+
"""
|
18 |
+
try:
|
19 |
+
ocr = Reader(lang_list=[OCR_MODEL_LANGUAGE])
|
20 |
+
result = ocr.readtext(image)
|
21 |
+
text = [bbox[1] for bbox in result]
|
22 |
+
text = "\n".join(text)
|
23 |
+
return text
|
24 |
+
except Exception as e:
|
25 |
+
logging.info(f"Error : {e} : OCR.extract_text")
|
src/pipeline.py
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from src.document import PDF_Processing
|
2 |
+
from src.ocr_model import OCR
|
3 |
+
from src.llms import LLM
|
4 |
+
from src import logging
|
5 |
+
import os
|
6 |
+
|
7 |
+
|
8 |
+
class Pipeline:
|
9 |
+
def __init__(self):
|
10 |
+
self.cwd = os.getcwd()
|
11 |
+
|
12 |
+
def process(file,type):
|
13 |
+
"""
|
14 |
+
file : data it can be image or pdf
|
15 |
+
Type : format of PDF / Image (png, jpg)
|
16 |
+
|
17 |
+
return : Clean Text.
|
18 |
+
"""
|
19 |
+
try:
|
20 |
+
print("startd")
|
21 |
+
if type == "pdf":
|
22 |
+
image = PDF_Processing.pdf_to_image(file)
|
23 |
+
else:
|
24 |
+
image = PDF_Processing.load_image(file)
|
25 |
+
text = OCR.extract_text(image)
|
26 |
+
json_text = LLM().get_json(input_data=text,key = "json")
|
27 |
+
final = LLM().get_json(input_data=json_text)
|
28 |
+
return final
|
29 |
+
except Exception as e:
|
30 |
+
logging.info(f"Error :{e} :Pipeline.process")
|
31 |
+
|
32 |
+
if __name__ == "__main__":
|
33 |
+
path = "test_docs/CBC-test-report-format-example-sample-template-Drlogy-lab-report.pdf"
|
34 |
+
result = Pipeline.process(path)
|
src/prompts.py
ADDED
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
class Prompts:
|
2 |
+
|
3 |
+
def __init__(self) -> None:
|
4 |
+
pass
|
5 |
+
|
6 |
+
def final_prompt():
|
7 |
+
return """
|
8 |
+
You are a doctor explaining a patient's medical report in simple, easy-to-understand language. Focus only on the areas of concern and explain the health issues, if any, and provide natural suggestions to improve the condition.
|
9 |
+
|
10 |
+
Here is the report:
|
11 |
+
|
12 |
+
Report: {json_data}
|
13 |
+
|
14 |
+
Based on the above report, explain only the report do not give patient details and provide natural remedies or ways to heal.
|
15 |
+
"""
|
16 |
+
|
17 |
+
|
18 |
+
def text_json_prompt():
|
19 |
+
return """
|
20 |
+
You are an expert in text comprehension. Your task is straightforward: understand the provided text and return the output in the specified JSON format.
|
21 |
+
|
22 |
+
Text: {text}
|
23 |
+
|
24 |
+
Output: Please provide the output in the following JSON format:
|
25 |
+
|
26 |
+
{{
|
27 |
+
"patient_name": "<patient name>",
|
28 |
+
"lab_no": "<lab number>",
|
29 |
+
"lab_name": "<laboratory name>",
|
30 |
+
"collection_date_time": "<sample collection date and time>",
|
31 |
+
"reported_date_time": "<report date and time>",
|
32 |
+
"test_name": "<test name>",
|
33 |
+
"patient_age": "<patient age>",
|
34 |
+
"patient_gender": "<patient gender>",
|
35 |
+
"Report": {{
|
36 |
+
"<investigation name>": {{
|
37 |
+
"result": "<result value>",
|
38 |
+
"reference_value": "<reference range>",
|
39 |
+
"unit": "<unit of measurement>"
|
40 |
+
}}
|
41 |
+
}}
|
42 |
+
}}
|
43 |
+
"""
|
src/setting.py
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
LOCAL_TEST = False # if local test = True than pass the pdf file path
|
2 |
+
MODEL_NAME = "gemini-pro" # LLM model name
|
3 |
+
OCR_MODEL_LANGUAGE = "en" # ocr model language.
|