W trakcie wymiany stosów TeX rozmawialiśmy o tym, jak wykryć „rzeki” w akapitach tego pytania .
W tym kontekście rzeki to pasma białych znaków, które powstają w wyniku przypadkowego wyrównania odstępów międzytekstowych w tekście. Ponieważ może to być dość rozpraszające dla czytelnika, złe rzeki są uważane za objaw złej typografii. Przykładem tekstu z rzekami jest ta, w której dwie rzeki płyną po przekątnej.
Istnieje zainteresowanie automatycznym wykrywaniem rzek, aby można było ich uniknąć (prawdopodobnie poprzez ręczną edycję tekstu). Raphink robi pewne postępy na poziomie TeX (który zna tylko pozycje glifów i ramki ograniczające), ale jestem przekonany, że najlepszym sposobem na wykrycie rzek jest trochę przetwarzania obrazu (ponieważ kształty glifów są bardzo ważne i niedostępne dla TeXa) . Próbowałem różnych sposobów na wydobycie rzek z powyższego obrazu, ale mój prosty pomysł zastosowania niewielkiej ilości elipsoidalnego rozmycia nie wydaje się wystarczający. Spróbowałem też RadonaFiltrowanie oparte na transformacji Hougha, ale z nimi też nie dotarłem. Rzeki są bardzo widoczne dla obwodów detekcji ludzkiego oka / siatkówki / mózgu i jakoś sądzę, że można to przełożyć na jakąś operację filtrowania, ale nie jestem w stanie sprawić, by działała. Jakieś pomysły?
Mówiąc ściślej, szukam operacji, która wykryje 2 rzeki na powyższym obrazie, ale nie wykryje zbyt wielu innych fałszywych alarmów.
EDYCJA: endolith zapytał, dlaczego stosuję podejście oparte na przetwarzaniu obrazu, biorąc pod uwagę, że w TeXie mamy dostęp do pozycji glifów, odstępów itp. I może być znacznie szybsze i bardziej niezawodne użycie algorytmu, który bada rzeczywisty tekst. Moim powodem robienia rzeczy w inny sposób jest kształtglifów może wpływać na to, jak zauważalna jest rzeka, a na poziomie tekstu bardzo trudno jest wziąć pod uwagę ten kształt (który zależy od czcionki, ligaturacji itp.). Na przykład, w jaki sposób kształt glifów może być ważny, rozważ dwa następujące przykłady, w których różnica między nimi polega na tym, że zamieniłem kilka glifów na inne o prawie takiej samej szerokości, aby analiza tekstowa rozważyła są równie dobre / złe. Należy jednak pamiętać, że rzeki w pierwszym przykładzie są znacznie gorsze niż w drugim.
źródło
ImageLines[]
z Mathematica, z pewnym przetwarzaniem wstępnym i bez niego. Myślę, że technicznie używa się transformacji Hougha zamiast Radona. Nie zdziwię się, jeśli poprawne przetwarzanie wstępne (nie próbowałem sugerowanego przez filtr danych filtru dylatacyjnego) i / lub ustawienia parametrów mogą zadziałać.Odpowiedzi:
Zastanowiłem się nad tym trochę i uważam, że następujące elementy powinny być dość stabilne. Zauważ, że ograniczyłem się do operacji morfologicznych, ponieważ powinny one być dostępne w dowolnej standardowej bibliotece przetwarzania obrazu.
(1) Otwórz obraz za pomocą maski nPix-by-1, gdzie nPix jest mniej więcej pionową odległością między literami
(2) Otwórz zdjęcie za pomocą maski 1 na mPix, aby wyeliminować wszystko, co jest zbyt wąskie, aby mogło być rzeką.
(3) Usuń poziome „rzeki i jeziora”, które są spowodowane odstępem między akapitami lub wcięciem. W tym celu usuwamy wszystkie wiersze, które są prawdziwe, i otwieramy za pomocą maski nPix-by-1, która, jak wiemy, nie wpłynie na rzeki, które znaleźliśmy wcześniej.
Aby usunąć jeziora, możemy użyć maski otwierającej, która jest nieco większa niż nPix-by-nPix.
Na tym etapie możemy również wyrzucić wszystko, co jest zbyt małe, aby być prawdziwą rzeką, tj. Wszystko, co obejmuje mniejszy obszar niż (nPix + 2) * (mPix + 2) * 4 (co da nam ~ 3 linie). Jest tam +2, ponieważ wiemy, że wszystkie obiekty mają co najmniej nPix wysokości i mPix szerokości, i chcemy pójść nieco wyżej.
(4) Jeśli interesuje nas nie tylko długość, ale także szerokość rzeki, możemy połączyć transformację odległości ze szkieletem.
(kolory odpowiadają szerokości rzeki (choć pasek kolorów jest wyłączony 2 razy)
Teraz możesz uzyskać przybliżoną długość rzek, zliczając liczbę pikseli w każdym podłączonym komponencie i średnią szerokość, uśredniając ich wartości pikseli.
Oto dokładna analiza zastosowana do drugiego obrazu „no-river”:
źródło
W Mathematica za pomocą erozji i transformacji Hougha:
Edytuj odpowiedź na komentarz pana Kreatora
Jeśli chcesz pozbyć się poziomych linii, po prostu zrób coś takiego (prawdopodobnie ktoś mógłby to uprościć):
źródło
lines = ImageLines[ImageResize[#, {300, 300}], .6, "Segmented" -> True] & /@ i1;
. Biorąc to wszystko pod uwagę, podejście morfologiczne wydaje się bardziej solidne.Hmmm ... Myślę, że transformacja Radona nie jest taka łatwa do wydobycia. (Transformacja radonowa zasadniczo obraca obraz podczas „patrzenia przez niego” brzegiem. Jest to zasada skanów CAT). Transformacja twojego obrazu tworzy ten sinogram, z „rzekami” tworzącymi jasne szczyty, które są zakreślone:
Ten przy obrocie o 70 stopni jest dość wyraźnie widoczny jako szczyt po lewej stronie tego wykresu plastra wzdłuż osi poziomej:
Zwłaszcza jeśli tekst był najpierw rozmazany Gaussa:
Ale nie jestem pewien, jak niezawodnie wydobyć te szczyty z reszty szumu. Jasne górne i dolne końce sinogramu reprezentują „rzeki” między poziomymi liniami tekstu, na których oczywiście nie masz znaczenia. Może funkcja ważenia w funkcji kąta podkreśla więcej linii pionowych i minimalizuje linie poziome?
Prosta funkcja ważenia cosinus dobrze działa na tym obrazie:
znajdowanie pionowej rzeki pod kątem 90 stopni, która jest globalnymi maksimami na sinogramie:
a na tym zdjęciu znalezienie tego przy 104 stopniach, choć najpierw rozmycie powoduje, że jest bardziej dokładne:
(
radon()
Funkcja SciPy jest trochę głupia , inaczej odwzoruję ten szczyt z powrotem na oryginalny obraz jako linię przechodzącą przez środek rzeki.)Ale po rozmyciu i ważeniu nie znajduje żadnego z dwóch głównych pików na sinogramie dla twojego obrazu:
Są tam, ale są przytłoczeni materiałami w pobliżu środkowego szczytu funkcji ważenia. Przy odpowiednim ważeniu i poprawianiu ta metoda prawdopodobnie mogłaby działać, ale nie jestem pewien, jakie są poprawne poprawki. Prawdopodobnie zależy to również od właściwości skanów strony. Może ważenie musi być wyprowadzone z ogólnej energii w plasterku lub czymś takim, jak normalizacja.
źródło
Przeszkoliłem klasyfikator dyskryminujący piksele przy użyciu funkcji pochodnych (do 2. rzędu) w różnych skalach.
Moje etykiety:
Prognozy dotyczące obrazu treningowego:
Prognozy na pozostałe dwa obrazy:
Wydaje mi się, że wygląda to obiecująco i może przynieść użyteczne wyniki, biorąc pod uwagę więcej danych szkoleniowych i być może inteligentniejsze funkcje. Z drugiej strony uzyskanie tych wyników zajęło mi tylko kilka minut. Możesz odtworzyć wyniki samodzielnie, korzystając z oprogramowania open source ilastik . [Oświadczenie: Jestem jednym z głównych programistów.]
źródło
(Przepraszamy, ten post nie zawiera niesamowitych demonstracji).
Jeśli chcesz pracować z informacjami, które TeX już posiada (litery i pozycje), możesz ręcznie klasyfikować litery i pary liter jako „pochyłe” w jednym lub drugim kierunku. Na przykład „w” ma nachylenie narożne SW i SE, kombinacja „al” ma nachylenie narożne NW, „k” ma nachylenie narożne NE. (Nie zapomnij interpunkcji - cytat, po którym następuje litera wypełniająca dolną połowę pola glifu, tworzy przyjemne nachylenie; cytat po którym następuje q jest szczególnie silny.)
Następnie poszukaj występowania odpowiadających stoków po przeciwnych stronach przestrzeni - „w al” dla rzeki SW-do-NE lub „k T” dla rzeki NW-do-SE. Kiedy znajdziesz jeden w linii, sprawdź, czy podobny wiersz występuje odpowiednio przesunięty w lewo lub w prawo na liniach powyżej / poniżej; kiedy znajdziesz ich szereg, prawdopodobnie jest tam rzeka.
Oczywiście po prostu poszukaj przestrzeni ułożonych prawie pionowo, dla prostych pionowych rzek.
Możesz się nieco bardziej wyrafinować, mierząc „siłę” stoku: ile skrzynek postępowych jest „pustych” ze względu na nachylenie, a tym samym wpływa na szerokość rzeki. „w” jest dość małe, ponieważ ma tylko niewielki narożnik swojego pudełka awansu, aby przyczynić się do rzeki, ale „V” jest bardzo silny. „b” jest nieco silniejsze niż „k”; łagodna krzywa zapewnia bardziej ciągłą wizualnie krawędź rzeki, czyniąc ją silniejszą i wizualnie szerszą.
źródło