Я хочу извлечь рукописные символы, написанные в таких полях.
Я извлекаю квадраты шириной 29 пикселей, что дает мне такие изображения.
Чтобы правильно распознавать символы, изображения отдельных символов должны быть очень чистыми. Нравится,
Что я делаю,
- Вычислите горизонтальную и вертикальную проекцию каждого изображения.
Перебрать каждый элемент обоих массивов. Если значение проекции больше определенного порога, это означает, что она не достигла границы. Он удаляет пробелы вокруг границы.
Затем найдите контуры на изображении.
- Если площадь контура больше некоторого порога. Получите ограничивающий прямоугольник и обрежьте его.
Но проблема в том, что метод не точен. В некоторых случаях это работает нормально, но в большинстве случаев, если терпит неудачу с треском. Он создает такие изображения, как
Также значения проекции очень специфичны для этого изображения (или изображений, близких к этому изображению). Это плохо обобщает.
Есть ли другой метод, который может хорошо работать в этой ситуации?
Код,
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