Download Game! Currently 81 players. Last logged in:LarppaResinArcanautGarok

Blitzer's Blog >> 72591

Back to blogs index
Posted: 20 Sep 2026 15:47 [ permalink ]
import cv2
import numpy as np
from PIL import ImageGrab
import pytesseract
import time

def generate_ast():
    print("[*] Kaapataan ruutu...")
    # Kaapataan koko ruutu (tai voit rajata bboxilla)
    img_pil = ImageGrab.grab()
    img_np = np.array(img_pil)
    
    # Muunnetaan RGB (Pillow) -> BGR (OpenCV) -> HarmaasC$vy
    gray = cv2.cvtColor(img_np, cv2.COLOR_RGB2GRAY)
    
    print("[*] Pass 1: Edge Mapping & Dilation (OpenCV)...")
    # EtsitC$C$n C$C$riviivat
    edges = cv2.Canny(gray, 50, 150)
    
    # Dilaatio (yhdistC$C$ lC$hekkC$in olevat kirjaimet/reunat yhdeksi
laatikoksi)
    # 10x5 kernel on leveC$mpi kuin korkea, sopii hyvin tekstiriveille
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (10, 5))
    dilated = cv2.dilate(edges, kernel, iterations=1)
    
    contours, _ = cv2.findContours(dilated, cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
    
    nodes = []
    print(f"[*] LC6ydettiin {len(contours)} potentiaalista elementtiC$.
Analysoidaan...")
    
    for i, contour in enumerate(contours):
        x, y, w, h = cv2.boundingRect(contour)
        
        # Suodatetaan liian pienet (kohina) ja liian suuret (koko ruudun
taustat)
        if w < 12 or h < 12 or w > img_np.shape[1] * 0.9:
            continue
            
        crop = gray[y:y+h, x:x+w]
        
        # Pass 2: Kognitiivinen Luokittelu
        # --psm 7 tarkoittaa "Treat the image as a single text line"
        text = pytesseract.image_to_string(crop, config='--psm 7 -l
eng+fin').strip()
        
        # Puhdistetaan OCR-roskaa
        text = "".join([c for c in text if c.isalnum() or c in " .,?!-()/:"])
        
        if len(text) > 1:
            nodes.append({
                "id": f"node_{i}", "type": "TextNode", 
                "content": text, "x": x, "y": y, "w": w, "h": h
            })
        else:
            nodes.append({
                "id": f"node_{i}", "type": "IconNode", 
                "content": "Graphic", "x": x, "y": y, "w": w, "h": h
            })
            
    return nodes

def build_ast_md(nodes):
    print("[*] Pass 4: Rakennetaan AST-MD semanttinen kartta...")
    
    # JC$rjestetC$C$n elementit ylhC$C$ltC$ alas, vasemmalta oikealle
lukujC$rjestykseen
    nodes.sort(key=lambda n: (n['y'] // 20, n['x']))
    
    md = "# AST-MD: Visuaalinen KC$yttC6liittymC$kartta

"
    md += "## Layout Elements

"
    
    for node in nodes:
        node_id = node['id']
        x, y, w, h = node['x'], node['y'], node['w'], node['h']
        
        if node['type'] == 'TextNode':
            md += f"- `[{node_id}]` **TextNode**: \"{node['content']}\"
(X:{x}, Y:{y}, W:{w}, H:{h})
"
        else:
            md += f"- `[{node_id}]` **IconNode**: *{node['content']}* (X:{x},
Y:{y}, W:{w}, H:{h})
"
            
    return md

if __name__ == "__main__":
    start_time = time.time()
    ast_nodes = generate_ast()
    markdown_output = build_ast_md(ast_nodes)
    
    print("
" + "="*50)
    print(markdown_output)
    print("="*50)
    print(f"[+] AST-MD generointi valmis ({(time.time()-start_time):.2f}
sekuntia).")