Je veux extraire des caractères manuscrits qui sont écrits dans des boîtes comme ceci. Je suis en train d'extraire des carrés d'une largeur de 29 pixels, ce qui me donne des images comme celles-ci.Comment supprimer les bordures d'images prises d'un document (comme les caractères manuscrits MNIST)?
Pour reconnaître correctement les caractères, les images de caractère individuel doivent être extrêmement propres. Comme cela,
Qu'est-ce que je fais est,
- Calculer la projection horizontale et verticale de chaque image.
Effectuez une itération sur chaque élément des deux matrices. Si la valeur de la projection est supérieure à un certain seuil, cela signifie qu'elle n'a pas rencontré la frontière. Il supprime les espaces autour de la frontière.
Puis trouvez les contours dans l'image.
- Si la zone de contour est supérieure à un certain seuil. Obtenez le rectangle de délimitation et recadrez-le.
Mais le problème est que la méthode n'est pas très précise. Dans certains cas, cela fonctionne bien, mais dans la plupart des cas, si elle échoue lamentablement. Il produit des images comme,
également les valeurs de projection sont très spécifiques à cette image (ou des images plus proches de cette image). Ça ne généralise pas bien.
Y a-t-il une autre méthode qui peut fonctionner dans cette situation?
Le code,
char = cv2.imread(image)
char_gray = cv2.cvtColor(char, cv2.COLOR_BGR2GRAY)
char_bw = cv2.adaptiveThreshold(char_gray, 255,
cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 9)
(rows, cols) = char_gray.shape
bit_not = cv2.bitwise_not(char_bw)
proj_h = cv2.reduce(bit_nv2.REDUCE_AVG)
proj_v = cv2.reduce(bit_not, 0, cv2.REDUCE_AVG)
thresh_h = 200
thresh_v = 100
start_x, start_y, end_x, end_y = 0, 0, cols - 1, rows - 1
#proj_h = proj_h[0]
proj_v = proj_v[0]
num_iter_h = cols // 8
num_iter_v = rows // 8
for _ in range(num_iter_h):
if proj_h[start_y][0] > 35:
start_y += 1
for _ in range(num_iter_h):
if proj_h[end_y][0] > 160:
end_y -= 1
for _ in range(num_iter_v):
if proj_v[start_x] > 15: #25:
start_x += 1
for _ in range(num_iter_v):
if proj_v[end_x] > 125:
end_x -= 1
print('processing.. %s.png' % idx)
output_char = char[start_y:end_y, start_x:end_x]
output_char = get_cropped_char(output_char)
return output_char
def get_cropped_char(img):
"""
Returns Grayscale cropped image
"""
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(img, (3,3), 0)
thresh = cv2.adaptiveThreshold(blur, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 75, 10)
im2, cnts, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contour = None
for c in cnts:
area = cv2.contourArea(c)
if area > 100:
contour = c
if contour is None: return None
(x, y, w, h) = cv2.boundingRect(contour)
img = img[y:y+h, x:x+w]
return img
Parlez-vous d'une opération d'érosion? – Arka
oui, vous l'avez. – Silencer
Wow. C'est exactement ce que je veux faire. Mais, après s'être érodé. Comment séparez-vous les boîtes? – Arka