Ich habe ein Bild der Nummer wie unten gezeigt.
Ich segmentierte die Nummer oben in ihre Ziffern mit Methoden der adaptiven Schwellenwertbildung und Erkennung von Konturen und eine Beschränkung der Höhe und des Gewichts für Begrenzungsrechteck größer als 15, um die folgenden segmentierten Ziffern zu erhalten.
Zeichensegmentierung und Erkennung für ungleichmäßig beabstandete Ziffern
Statt über Ausgabe, würde ich oben so die Zahl im Bild zu segmentieren gerne als jede Ziffer einzeln zu bekommen. Dieses Ergebnis kann nach der Größenanpassung an (28, 28) CNN von MNIST zur besseren Vorhersage bestimmter Ziffern zugeführt werden.
Eine Methode wie erwähnt here schlägt vor, ein grünes Fenster von fester Größe zu schieben und die Ziffern durch Training eines neuronalen Netzes zu erkennen. Also, wie wird diese NN trainiert, um die Ziffern zu klassifizieren? Diese Methode vermeidet den OpenCV-Ansatz, um jede einzelne Ziffer zu trennen, aber nur ein Schiebefenster über das ganze Bild ist nicht ein bisschen teuer. Wie man mit positiven und negativen Beispielen während des Trainings umgehen kann (sollte ich einen separaten Datensatz erstellen ... positive Beispiele können aus kleinen Ziffern bestehen, aber was ist mit negativen Beispielen?)?
Segmentation:
img = cv2.imread('Image')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray,(3,3), 0)
thresh = cv2.adaptiveThreshold(blur,255,cv2.ADAPTIVE_THRESH_MEAN_C,\
cv2.THRESH_BINARY_INV, 7,10)
thresh = clear_border(thresh)
# find contours in the thresholded image, then initialize the
# list of group locations
clone = np.dstack([gray.copy()] * 3)
groupCnts = cv2.findContours(thresh.copy(), cv2.RETR_TREE,
cv2.CHAIN_APPROX_SIMPLE)
groupCnts = groupCnts[0] if imutils.is_cv2() else groupCnts[1]
groupLocs = []
clone = np.dstack([gray.copy()] * 3)
# loop over the group contours
for (i, c) in enumerate(groupCnts):
# compute the bounding box of the contour
(x, y, w, h) = cv2.boundingRect(c)
# only accept the contour region as a grouping of characters if
# the ROI is sufficiently large
if w >= 15 and h >= 15:
print (i, (x, y, w, h))
cv2.rectangle(clone, (x,y), (x+w, y+h), (255,0,0), 1)
groupLocs.append((x, y, w, h))
gleitendes Fenster:
clf = joblib.load("digits_cls.pkl") #mnist trained classifier
img = cv2.imread('Image', 0)
winW, winH = (22, 40)
cv2.imshow("Window0", img)
cv2.waitKey(1)
blur = cv2.GaussianBlur(img, (5,5),0)
thresh = cv2.adaptiveThreshold(blur,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,\
cv2.THRESH_BINARY,11,2)
thresh = clear_border(thresh)
for (x, y, window) in sliding_window(img, stepSize=10, windowSize=(winW, winH)):
if (window.shape[0] != winH or window.shape[1] != winW):
continue
clone = img.copy()
roi = thresh[y:y+winH, x:x+winW]
roi = cv2.resize(roi, (28, 28), interpolation=cv2.INTER_AREA)
roi = cv2.dilate(roi, (3, 3))
cv2.imshow("Window1", roi)
cv2.waitKey(1)
roi_hog_fd = hog(roi, orientations=9, pixels_per_cell=(14, 14), cells_per_block=(1, 1), visualise=False)
nbr = clf.predict(np.array([roi_hog_fd], 'float64'))
print (nbr)
# since we do not have a classifier, we'll just draw the window
clone = img.copy()
cv2.rectangle(clone, (x, y), (x + winW, y + winH), (0, 255, 0), 2)
cv2.imshow("Window2", clone)
cv2.waitKey(1)
time.sleep(0.95)
Schräge Output (sogar für leeres Fenster vorhersagt IT): 522637753787357777722
Trenn Stellen verbunden:
h,w = img.shape[:2]
count = 0
iw = 15
dw = w
sw, sh = int(0), int(0)
while (dw > 0):
new_img = img[:, sw:(count+1)*iw]
dw = dw - iw
sw = sw + iw
if (dw-iw < 0):
iw = w
new = os.path.join('amount/', 'amount_'+ str(count)+'.png')
cv2.imwrite(new, new_img)
Mit einer Art und Weise, diese verbundene Ziffern seprate gefunden und Fütterung trainierte Klassifizierer mnist, ausgegeben noch ungenau.
Schritte, die ich verwendete:
(i) Erstes Bild extrahieren
(ii) Segmentieren Sie das erste Bild in ein separates Bild, zum Beispiel das zweite Bild.
(iii) Prüfen Sie, ob die Bildbreite einen bestimmten Schwellenwert überschreitet, falls ja, segmentiert sie weiter getrennte Ziffern (im Fall von verbundenen Ziffern wie oben)
(iv) Führen Sie alle separaten Ziffern nach Schritt 3 ein, um mnist classifier zu erhalten die Vorhersage der Ziffer basierend auf dem umgeformten Bild. Lengthy right?
Is there any other efficient way to convert first image to digits directly (yes I used pytesseract too!!)?
Können Sie Code-Segmentierung hinzufügen? – Link
Wäre es nicht einfacher, das CNN zu trainieren, 00 und 000 (und andere verknüpfte Ziffernkombinationen) zu erkennen und zu generieren? – barny
@ barny, statt mehrstelligen Datensatz zu erstellen, wird Training auf SVHN-Datensatz und Tests auf oben mehrstellige geben gutes Ergebnis? – SupposeXYZ