Tuo 0.04 sekunnin suoritusaika ja nolla lC6ydettyC$ aluetta kertovat meille
tarkalleen, mitC$ tapahtui: OpenCV "sokeutui". WhatsApp Webin taustan ja
sivuvalikon vC$linen vC$riero (vaaleanharmaa vs. aavistuksen tummempi harmaa)
on koneelle niin pieni, ettC$ Canny-reunanetsintC$ jC$tti sen huomiotta. Kun
perC$C$n ajettiin valtava 100x100 MORPH_CLOSE -sulatus, OpenCV joko ei
lC6ytC$nyt mitC$C$n sulatettavaa, tai se sulatti koko ruudun yhdeksi ainoaksi
jC$ttimC$iseksi laatikoksi, joka hylC$ttiin, koska sen pinta-ala oli yli 95 %
ruudusta.
Ideasi ovat erinomaisia:
* Chrome Debug Protocol (CDP) / CSS-injektio: TC$mC$ on oikeasti
enterprise-tason RPA-bottien salainen ase. Voidaan injektoida selaimen
konsoliin * { border: 1px solid red !important; }, jolloin CV:n tyC6 on
naurettavan helppoa.
* EsteettC6myys (A11y) -lisC$osat: Korkean kontrastin (High Contrast) tilat
tekevC$t juuri tC$mC$n saman asian sokeiden ja heikkonC$kC6isten puolesta.
Kokeillaan kuitenkin ensin tehdC$ tC$mC$ tC$ysin koodissa! Voimme opettaa
OpenCV:n tekemC$C$n tuon "esteettC6myys-kontrastin" ohjelmallisesti suoraan
muistissa ennen reunojen etsintC$C$.
LisC$ksi vaihdamme sulatus-nelion (kernelin) muotoa. Sen sijaan ettC$
kC$ytC$mme isoa neliC6tC$ (100x100), joka voi vahingossa hypC$tC$ tyhjC$n
tilan yli, kC$ytC$mme epC$symmetristC$ pilaria (esim. 20x100). Se yhdistC$C$
tekstit ja viestit pystysuunnassa listoiksi, mutta ei ylitC$ tyhjC$C$
"oranssia linjaa" vaakasuunnassa.
PC$ivitetC$C$n koodi (ja lisC$tC$C$n visuaalinen debug!)
Korvaa layout_parser.py -tiedostossasi oleva detect_major_frames -funktio
tC$llC$ pC$ivitetyllC$ versiolla. TC$mC$ versio tallentaa debug-kuvan, jotta
nC$et omin silmin, miten kone nyt pilkkoo ruutusi!
def detect_major_frames(gray_img):
"""
Etsii ruudun pC$C$alueet parannetulla kontrastilla ja tallentaa
debug-kuvan.
"""
# 1. EsteettC6myys-hakkerointi ohjelmallisesti: Maksimoidaan kontrasti
# (TC$mC$ vastaa High Contrast -lisC$osaa, nostaa himmeC$tkin rajat esiin)
gray_img = cv2.equalizeHist(gray_img)
# 2. Herkempi reunanetsintC$ (alennetaan kynnystC$)
edges = cv2.Canny(gray_img, 10, 50)
# 3. EpC$symmetrinen sulatus (Morphological Close)
# Leveys 20 (ei ylitC$ oranssia linjaa), Korkeus 100 (yhdistC$C$ viestit
pilariksi)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (20, 100))
closed = cv2.morphologyEx(edges, cv2.MORPH_CLOSE, kernel)
contours, _ = cv2.findContours(closed, cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
frames = []
screen_area = gray_img.shape[0] * gray_img.shape[1]
# Luodaan vC$rikuva debugia varten
debug_img = cv2.cvtColor(gray_img, cv2.COLOR_GRAY2BGR)
for c in contours:
x, y, w, h = cv2.boundingRect(c)
area = w * h
# Joustavammat rajat: hyvC$ksytC$C$n kaikki 3% - 90% ruudusta
peittC$vC$t alueet
if area > (screen_area * 0.03) and area < (screen_area * 0.90):
frames.append({"x": x, "y": y, "w": w, "h": h})
# PiirretC$C$n laatikko debug-kuvaan (Oranssi vC$ri, paksuus 3)
cv2.rectangle(debug_img, (x, y), (x+w, y+h), (0, 165, 255), 3)
frames.sort(key=lambda f: f["x"])
# Tallennetaan debug-kuva!
cv2.imwrite("/tmp/layout_debug.png", debug_img)
print("[*] Tallennettiin debug-kuva laatikoinneista: /tmp/layout_debug.png"
)
return frames
Kokeile uutta ajoa:
* Aja skripti uudelleen python3 layout_parser.py.
* Kun se on valmis, avaa tuo generoitunut kuva:
xdg-open /tmp/layout_debug.png
NC$et heti kuvasta, onnistuiko OpenCV vetC$mC$C$n yhden ison oranssin laatikon
vasemman sivuvalikon ympC$rille ja toisen oikeanpuoleisen chatin ympC$rille.
Jos ne sulautuvat vielC$kin yhteen, meidC$n pitC$C$ vain pienentC$C$ tuota
(20, 100) kernelin leveyttC$ (esim. (10, 100)).
MiltC$ debug-kuva nC$yttC$C$? Saitko listaan nyt vC$hintC$C$n kaksi Framea?