Mam schemat wielu obrazów, z których wszystkie zawierają etykiety jako znaki alfanumeryczne zamiast samej etykiety tekstowej. Chcę, aby mój model YOLO identyfikował wszystkie zawarte w nim cyfry i znaki alfanumeryczne.
Jak mogę wytrenować mój model YOLO, aby robił to samo. Zestaw danych można znaleźć tutaj. https://drive.google.com/open?id=1iEkGcreFaBIJqUdAADDXJbUrSj99bvoi
Na przykład: zobacz ramki ograniczające. Chcę, aby YOLO wykrywał, gdziekolwiek tekst jest obecny. Jednak obecnie nie jest konieczne identyfikowanie tekstu w nim zawartego.
To samo należy zrobić dla tego typu obrazów
Obrazy można pobrać tutaj
Właśnie tego próbowałem za pomocą opencv, ale to nie działa dla wszystkich obrazów w zestawie danych.
import cv2
import numpy as np
import pytesseract
pytesseract.pytesseract.tesseract_cmd = r"C:\Users\HPO2KOR\AppData\Local\Tesseract-OCR\tesseract.exe"
image = cv2.imread(r'C:\Users\HPO2KOR\Desktop\Work\venv\Patent\PARTICULATE DETECTOR\PD4.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
clean = thresh.copy()
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (15,1))
detect_horizontal = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, horizontal_kernel, iterations=2)
cnts = cv2.findContours(detect_horizontal, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
cv2.drawContours(clean, [c], -1, 0, 3)
vertical_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1,30))
detect_vertical = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, vertical_kernel, iterations=2)
cnts = cv2.findContours(detect_vertical, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
cv2.drawContours(clean, [c], -1, 0, 3)
cnts = cv2.findContours(clean, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
area = cv2.contourArea(c)
if area < 100:
cv2.drawContours(clean, [c], -1, 0, 3)
elif area > 1000:
cv2.drawContours(clean, [c], -1, 0, -1)
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.02 * peri, True)
x,y,w,h = cv2.boundingRect(c)
if len(approx) == 4:
cv2.rectangle(clean, (x, y), (x + w, y + h), 0, -1)
open_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (2,2))
opening = cv2.morphologyEx(clean, cv2.MORPH_OPEN, open_kernel, iterations=2)
close_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,2))
close = cv2.morphologyEx(opening, cv2.MORPH_CLOSE, close_kernel, iterations=4)
cnts = cv2.findContours(close, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
x,y,w,h = cv2.boundingRect(c)
area = cv2.contourArea(c)
if area > 500:
ROI = image[y:y+h, x:x+w]
ROI = cv2.GaussianBlur(ROI, (3,3), 0)
data = pytesseract.image_to_string(ROI, lang='eng',config='--psm 6')
if data.isalnum():
cv2.rectangle(image, (x, y), (x + w, y + h), (36,255,12), 2)
print(data)
cv2.imwrite('image.png', image)
cv2.imwrite('clean.png', clean)
cv2.imwrite('close.png', close)
cv2.imwrite('opening.png', opening)
cv2.waitKey()
Czy jest jakiś model lub jakaś technika opencv lub jakiś wstępnie wyszkolony model, który może zrobić to samo dla mnie? Potrzebuję tylko obwiedni wokół wszystkich znaków alfanumerycznych obecnych na obrazach. Następnie muszę określić, co w nim jest. Jednak druga część nie jest obecnie ważna.
źródło
Odpowiedzi:
Możliwym podejściem jest użycie detektora głębokiego uczenia EAST (Efficient and Accurate Scene Text) opartego na pracy Zhou i wsp. Z 2017 roku, EAST: An Efficient and Accurate Scene Text Detector . Model został pierwotnie przeszkolony do wykrywania tekstu na naturalnych scenach, ale może być możliwe zastosowanie go na obrazach diagramów. EAST jest dość solidny i potrafi wykrywać rozmazany lub odblaskowy tekst. Oto zmodyfikowana wersja implementacji EAST Adriana Rosebrocka. Zamiast stosować detektor tekstu bezpośrednio na obrazie, możemy spróbować usunąć jak najwięcej obiektów nietekstowych z obrazu przed wykryciem tekstu. Chodzi o to, aby usunąć linie poziome, linie pionowe i kontury nietekstowe (krzywe, przekątne, kształty kołowe) przed zastosowaniem detekcji. Oto wyniki niektórych zdjęć:
Wprowadź
->
kontury nietekstowe do usunięcia na zielonoWynik
Inne obrazy
Wstępnie przeszkolony
frozen_east_text_detection.pb
model niezbędny do wykrycia tekstu można znaleźć tutaj . Chociaż model przechwytuje większość tekstu, wyniki nie są w 100% dokładne i od czasu do czasu mają fałszywie dodatnie wyniki, prawdopodobnie ze względu na sposób, w jaki był trenowany na naturalnych obrazach scen. Aby uzyskać dokładniejsze wyniki, prawdopodobnie będziesz musiał trenować własny model niestandardowy. Ale jeśli chcesz przyzwoitego, gotowego do użycia rozwiązania, powinno to działać. Zobacz post na blogu Adriana OpenCV Text Detection (detektor tekstu EAST), aby uzyskać pełniejsze wyjaśnienie detektora tekstu EAST.Kod
źródło
Dla wygody chciałbym dodać pakiet keras_ocr . Można go łatwo zainstalować za pomocą pipa i jest oparty na detektorze tekstu CRAFT, który jest nieco nowszy niż detektor EAST, jeśli się nie mylę.
Poza wykrywaniem robi już także trochę OCR! Wyniki przedstawiono poniżej, patrz na to jako alternatywę, być może łatwiejszą do wdrożenia, niż zaakceptowana odpowiedź.
źródło
To, co opisujesz, wydaje się być OCR ( optyczne rozpoznawanie znaków ). Jeden silnik OCR, o którym wiem, to tesseract , chociaż jest też ten od IBM i innych.
Ponieważ YOLO początkowo było szkolone do bardzo różnych zadań, używanie go do lokalizowania tekstu prawdopodobnie wymagać będzie ponownego przeszkolenia go od zera. Można spróbować użyć istniejących pakietów (dostosowanych do twojego konkretnego ustawienia) dla prawdziwej prawdy (chociaż warto pamiętać, że model byłby co najwyżej tak dobry, jak prawdziwa prawda). Lub, być może łatwiej, wygeneruj syntetyczne dane do szkolenia (tj. Dodaj tekst w wybranych pozycjach do istniejących rysunków, a następnie trenuj, aby go zlokalizować).
Alternatywnie, jeśli wszystkie obrazy docelowe mają strukturę podobną do powyższej, można spróbować stworzyć prawdę podstawową przy użyciu klasycznej heurystyki CV, tak jak to zrobiono powyżej, aby oddzielić / segmentować symbole, a następnie klasyfikację przy użyciu CNN przeszkolonego na MNIST lub podobnym w celu ustalenia jeśli dana kropelka zawiera symbol.
W przypadku, gdy zdecydujesz się na YOLO - istnieją już implementacje w Pythonie, np. Miałem trochę doświadczenia z tym - powinno być dość proste, aby skonfigurować szkolenie z własną prawdą.
Wreszcie, jeśli użycie YOLO lub CNN nie jest celem samym w sobie, a jedynie rozwiązaniem, każda z powyższych „podstawowych prawd” może być wykorzystana bezpośrednio jako rozwiązanie, a nie do szkolenia modelu.
Mam nadzieję, że poprawnie zrozumiałem twoje pytanie
źródło