fine tunning

This commit is contained in:
千住柱間 2025-04-21 18:52:11 -04:00
commit ad123fd7a8
Signed by: hashirama
GPG key ID: 53E62470A86BC185

View file

@ -8,10 +8,54 @@ import os
from pathlib import Path
from typing import Optional, Union, List
import pyinotify
import fnmatch
import glob
import subprocess
from collections import Counter
import re
import numpy as np
WATCH_DIR = "/tmp/mote-ocr-screenshots/"
def deconvolve_image_path(input_path, psf_size=5, iterations=10, output_path=None):
"""
Reads the image at input_path, applies RL deconvolution, and
returns an 8bit numpy array. Optionally saves to output_path.
"""
img = io.imread(input_path)
if img.ndim == 3:
gray = color.rgb2gray(img)
else:
gray = img_as_float(img)
psf = np.ones((psf_size, psf_size), dtype=float)
psf /= psf.sum()
deconv = richardson_lucy(gray, psf, iterations=iterations)
deconv_u8 = img_as_ubyte(np.clip(deconv, 0, 1))
if output_path:
io.imsave(output_path, deconv_u8)
return deconv_u8
def deconvolve_image_array(gray_float, psf_size=5, iterations=10):
"""
Takes a grayscale float image in [0,1], runs RL deconv, and
returns an 8bit numpy array.
"""
psf = np.ones((psf_size, psf_size), dtype=float)
psf /= psf.sum()
deconv = richardson_lucy(gray_float, psf, iterations=iterations)
return img_as_ubyte(np.clip(deconv, 0, 1))
def contrast_stretch(gray):
p2, p98 = np.percentile(gray, (2, 98))
return cv2.normalize(gray, None, p2, p98, cv2.NORM_MINMAX)
def copy_to_clipboard(text):
subprocess.run(["xsel", "--clipboard", "--input"], input=text.encode(), check=True)
# we we're kinda forced to implement the argmax by hand because of two factors:
# 1- the argmax from this model always takes the last axis, and this is not possible in numcpp , it only goes right or left.
@ -27,37 +71,6 @@ def argmax_last_axis(mat: List[List[int]]) -> List[int]:
for row in mat
]
def get_most_recent_file(
directory: Union[str, Path],
pattern: str = "*",
recursive: bool = False,
return_path: bool = True
) -> Optional[Union[str, Path]]:
dir_path = Path(directory)
if not dir_path.exists():
raise FileNotFoundError(f"Directory not found: {directory}")
if not dir_path.is_dir():
raise ValueError(f"Path is not a directory: {directory}")
# Get all matching files
if recursive:
files = list(dir_path.rglob(pattern))
else:
files = list(dir_path.glob(pattern))
# Filter out directories
files = [f for f in files if f.is_file()]
if not files:
return None
# Find most recent file by modification time
latest = max(files, key=lambda f: f.stat().st_mtime)
return str(latest) if return_path else latest
class TextProcessor:
def __init__(self, vocab_path: str):
@ -102,9 +115,9 @@ class TextProcessor:
self.vocab[idx] if 1 <= idx <= len(self.vocab) else self.unk_token
for idx in indices
)
final_text = self._remove_specials(raw_text)
text = self._remove_specials(raw_text)
return final_text
return text
def bicubic(img):
@ -138,18 +151,35 @@ def adjust_gamma(image, gamma=1.0, alpha=1.0, beta=0):
return adjusted
def enhance_text(image_path):
# Improve contrast using CLAHE
gray = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8, 8))
contrast = clahe.apply(gray)
# Apply adaptive thresholding to emphasize text
binarized = cv2.adaptiveThreshold(
contrast, 255,
cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY,
blockSize=11,
C=2
)
return binarized
def preprocess_image(image_path):
# Load image in grayscale (1-channel)
gray = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
gray = enhance_text(image_path)
resampled = bicubic(gray)
# Convert grayscale to 3-channel RGB by duplicating the gray channel
img = adjust_gamma(cv2.cvtColor(resampled, cv2.COLOR_GRAY2RGB),gamma=1.3,alpha=1.65,beta=-2) # perfect tunning
img = contrast_stretch(adjust_gamma(cv2.cvtColor(resampled, cv2.COLOR_GRAY2RGB),gamma=1,alpha=1.65,beta=-1)) # perfect tunning
mat_in = ncnn.Mat.from_pixels_resize(
img, ncnn.Mat.PixelType.PIXEL_RGB, img.shape[1], img.shape[0], 224, 224
)
mean_vals = [0.5, 0.5, 0.5] * 3
norm_vals = [1/255, 1/255, 1/255] * 3
mean_vals = [0.5, 0.5, 0.5] * 4
norm_vals = [1/255, 1/255, 1/255] * 4
mat_in.substract_mean_normalize(mean_vals, norm_vals)
return mat_in
@ -188,10 +218,30 @@ def main(image_path):
processor = TextProcessor("model/vocab.txt")
result = processor.decode(logits)
print(f"Decoded text: {result}")
copy_to_clipboard(result)
# raw_text = decode_tokens(logits)
# return post_process(raw_text)
def get_most_recent_file(directory, pattern="*.png", recursive=True):
search_path = os.path.join(directory, "**", pattern) if recursive else os.path.join(directory, pattern)
files = glob.glob(search_path, recursive=recursive)
return max(files, key=os.path.getctime) if files else None
class EventHandler(pyinotify.ProcessEvent):
def process_IN_CLOSE_WRITE(self, event):
if fnmatch.fnmatch(event.pathname, "*.png"):
recent_img = get_most_recent_file(WATCH_DIR, pattern="*.png", recursive=True)
print("PROCESSED OUT:", main(recent_img))
if __name__ == "__main__":
recent_img = get_most_recent_file("/home/hashirama/screenshots/", pattern="*.png", recursive=True)
print("PROCESSED OUT:", main(recent_img))
wm = pyinotify.WatchManager()
handler = EventHandler()
notifier = pyinotify.Notifier(wm, handler)
mask = pyinotify.IN_CLOSE_WRITE # triggers when a file is written and closed
wm.add_watch(WATCH_DIR, mask, rec=True, auto_add=True)
print(f"Watching {WATCH_DIR} for new PNG files...")
notifier.loop()