Download Game! Currently 136 players. Last logged in:FonkensembleLikuCroesusRammon

Blitzer's Blog >> 72599

Back to blogs index
Posted: 20 Sep 2026 16:51 [ permalink ]
Kuvasi on tC$ydellinen havainnollistus siitC$, miten tietokonenC$kC6 toimii
"pohjalta ylC6spC$in" (Bottom-Up) ja miksi se joskus epC$onnistuu.
Kuvasi on tC$ydellinen havainnollistus siitC$, miten tietokonenC$kC6 toimii
"pohjalta ylC6spC$in" (Bottom-Up) ja miksi se voi joskus sokeutua tyhjC$lle
tilalle!
Miksi keskiosa ja alapalkki puuttuvat?
OpenCV:n Canny-reunanetsintC$ etsii vain terC$viC$ vC$rimuutoksia. Koska
sumensimme kuvaa reilusti, chatin taustakuvio (doodle) katosi ja muuttui
tC$ysin tasaiseksi, harmaaksi tyhjyydeksi.
KC$yttC$mC$mme morfologinen sulatus (Morphological Close) osaa yhdistC$C$ vain
alueita, joissa on jo valmiiksi reunoja. Koska vasemman sivuvalikon ja
oikeanpuoleisten viestien vC$lissC$ oli massiivinen tyhjC$ kuilu, ne eivC$t
yhdistyneet.
EntC$ alapalkki ("Kirjoita viesti")? Se kyllC$ todennC$kC6isesti lC6ytyi
pienenC$ laatikkona, mutta koska siinC$ oli tyhjC$C$ tilaa sen ja ylempien
viestien vC$lillC$, se jC$i erilliseksi laatikoksi. Aiemmassa koodissa ollut
sC$C$ntC6 if h > (screen_h * 0.3) hylkC$si sen, koska alapalkki on hyvin
matala.
Ratkaisu: Paneelien halkaisu (Top-Down Layout Parsing)
Sen sijaan, ettC$ yritC$mme epC$toivoisesti "liimata" pieniC$ tekstejC$
toisiinsa isoiksi laatikoiksi, muutamme strategiaa kokonaan. Verkkosivut ja
tyC6pC6ytC$sovellukset on lC$hes aina jaettu pystysuuntaisiin, koko ruudun
korkuisiin paneeleihin (kuten sivuvalikko ja pC$C$sisC$ltC6).
KC$ytC$mme OpenCV:tC$ vain lC6ytC$C$ksemme vasemman paneelin leveyden. Kun
tiedC$mme, mihin sivuvalikko loppuu, voimme matemaattisesti viipaloida koko
ruudun kahteen pC$C$kehykseen. NC$in "Frame 2" (PC$C$sisC$ltC6) yltC$C$
automaattisesti ylhC$C$ltC$ alas asti  napaten mukaansa sekC$ viestit, tyhjC$n
tilan ettC$ tuon tC$rkeC$n alapalkin!
PC$ivitetty koodi
Korvaa layout_parser.py -tiedostossasi detect_major_frames -funktio tC$llC$
pC$ivitetyllC$ versiolla:
def detect_major_frames(gray_img):
    """
    Etsii UI:n pystysuuntaiset pC$C$paneelit jakamalla ruudun sivuvalikon ja
pC$C$sisC$llC6n vC$liltC$.
    """
    # Sumennetaan voimakkaasti, jotta vain suuret UI:n muodot jC$C$vC$t
jC$ljelle
    blurred = cv2.GaussianBlur(gray_img, (31, 31), 0)
    edges = cv2.Canny(blurred, 15, 50)
    
    # Sulatetaan vain pystysuunnassa (yhdistC$C$ vasemman kontaktilistan
yhdeksi pilariksi)
    kernel_v = cv2.getStructuringElement(cv2.MORPH_RECT, (10, 300))
    closed = cv2.morphologyEx(edges, cv2.MORPH_CLOSE, kernel_v)
    
    contours, _ = cv2.findContours(closed, cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
    
    screen_h, screen_w = gray_img.shape
    divider_x = 0
    
    # EtsitC$C$n suurin vasemmassa reunassa oleva yhtenC$inen elementti
(Sidebar)
    for c in contours:
        x, y, w, h = cv2.boundingRect(c)
        # Jos elementti on vasemmassa reunassa (alkaa alle 20% leveydestC$) ja
on korkea
        if x < screen_w * 0.2 and h > screen_h * 0.4:
            # EtsitC$C$n kauimmaisena oikealla oleva reuna
            if x + w > divider_x:
                divider_x = x + w
                
    # Fallback: Jos automatiikka ei jostain syystC$ lC6ydC$ rajaa, jaetaan 30%
/ 70%
    if divider_x < 100 or divider_x > screen_w * 0.6:
        divider_x = int(screen_w * 0.3)
        
    # Luodaan kehykset matemaattisesti koko ruudun korkuisiksi!
    frames = [
        {"x": 0, "y": 0, "w": divider_x, "h": screen_h},
        {"x": divider_x, "y": 0, "w": screen_w - divider_x, "h": screen_h}
    ]
    
    # PiirretC$C$n debug-kuva
    debug_img = cv2.cvtColor(gray_img, cv2.COLOR_GRAY2BGR)
    
    # Oranssi = Sidebar (Frame 1)
    cv2.rectangle(debug_img, (0, 0), (divider_x, screen_h), (0, 165, 255), 5) 
    
    # VihreC$ = Main Content (Frame 2)
    cv2.rectangle(debug_img, (divider_x, 0), (screen_w, screen_h), (50, 205,
50), 5) 
    
    cv2.imwrite("/tmp/layout_debug.png", debug_img)
    print(f"[*] LC6ydettiin pC$C$jakaja X-koordinaatista: {divider_x}")
    print("[*] Tallennettiin debug-kuva laatikoinneista: /tmp/layout_debug.png"
)
    
    return frames

MitC$ tapahtuu nyt?
 * Koodi etsii sivuvalikon (se lC6ytC$C$ varmasti tuon yhteystietolistan).
 * Se katsoo, mihin sivuvalikko pC$C$ttyy (esim. X-koordinaatti 378).
 * Se luo Frame_2:n (Widget / Dialog), joka alkaa suoraan koordinaatista 378
ja jatkuu ruudun oikeaan reunaan saakka, koko ruudun korkuisena.
 * Kun seuraava vaihe (generate_ast_for_region) ajaa tarkan OCR/Icon
-analyysin tC$mC$n vihreC$n laatikon sisC$llC$, se skannaa koko chatin, mukaan
lukien sen tC$rkeC$n alapalkin klemmareineen.
Aja koodi uudelleen ja tarkista /tmp/layout_debug.png. Nyt ruutusi pitC$isi
olla halkaistu tC$ydellisesti kahteen osaan, joiden sisC$llC$ AST-generaattori
tekee tarkkaa tyC6tC$C$n!