¿Qué técnica recomienda para segmentar los caracteres en esta imagen para que estén listos para alimentar un modelo como los que se usan con el conjunto de datos MNIST; porque toman un personaje a la vez. Esta pregunta no tiene en cuenta la importancia de transformar la imagen y su binarización.
¡Gracias!
Como punto de partida probaría lo siguiente:
Aquí están las primeras 4 etapas. Ahora necesita agregar su software de reconocimiento para reconocer los dígitos.
import cv2 import numpy as np from matplotlib import pyplot as plt # Params EPSSILON = 0.4 MIN_AREA = 10 BIG_AREA = 75 # Read img img = cv2.imread('i.jpg',0) # Otzu threshold a,thI = cv2.threshold(img,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU) # Morpholgical se = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(1,1)) thIMor = cv2.morphologyEx(thI,cv2.MORPH_CLOSE,se) # Connected compoent labling stats = cv2.connectedComponentsWithStats(thIMor,connectivity=8) num_labels = stats[0] labels = stats[1] labelStats = stats[2] # We expect the conneccted compoennt of the numbers to be more or less with a constats ratio # So we find the medina ratio of all the comeonets because the majorty of connected compoent are numbers ratios = [] for label in range(num_labels): connectedCompoentWidth = labelStats[label,cv2.CC_STAT_WIDTH] connectedCompoentHeight = labelStats[label, cv2.CC_STAT_HEIGHT] ratios.append(float(connectedCompoentWidth)/float(connectedCompoentHeight)) # Find median ratio medianRatio = np.median(np.asarray(ratios)) # Go over all the connected component again and filter out compoennt that are far from the ratio filterdI = np.zeros_like(thIMor) filterdI[labels!=0] = 255 for label in range(num_labels): # Ignore biggest label if(label==1): filterdI[labels == label] = 0 continue connectedCompoentWidth = labelStats[label,cv2.CC_STAT_WIDTH] connectedCompoentHeight = labelStats[label, cv2.CC_STAT_HEIGHT] ratio = float(connectedCompoentWidth)/float(connectedCompoentHeight) if ratio > medianRatio + EPSSILON or ratio < medianRatio - EPSSILON: filterdI[labels==label] = 0 # Filter small or large compoennt if labelStats[label,cv2.CC_STAT_AREA] < MIN_AREA or labelStats[label,cv2.CC_STAT_AREA] > BIG_AREA: filterdI[labels == label] = 0 plt.imshow(filterdI) # Now go over each of the left compoenet and run the number recognotion stats = cv2.connectedComponentsWithStats(filterdI,connectivity=8) num_labels = stats[0] labels = stats[1] labelStats = stats[2] for label in range(num_labels): # Crop the bounding box around the component left = labelStats[label,cv2.CC_STAT_LEFT] top = labelStats[label, cv2.CC_STAT_TOP] width = labelStats[label, cv2.CC_STAT_WIDTH] height = labelStats[label, cv2.CC_STAT_HEIGHT] candidateDigit = labels[top:top+height,left:left+width] # plt.figure(label) # plt.imshow(candidateDigit)
Me conecto a la respuesta de Amitay.
Para el 2: utilizaría el adelgazamiento como operación morfológica (mire el algoritmo de adelgazamiento en opencv )
Para el 3: Y en OpenCV 3.0 ya existe una función llamada cv :: connectedComponents )
Espero eso ayude