OpenCV найти символы на изображении
Вот код которым пользуюсь,для некоторых тестовых изображений он работает,но если я беру то изображение которое в последующем хочу распознать то ничего не получается
Так же посоветуйте как мне лучше обработать изображение для последующего распознавания.
def letters_extract(image_file: str, out_size=28):
img = cv2.imread(image_file)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY)
img_erode = cv2.erode(thresh, np.ones((3, 3), np.uint8), iterations=1)
# Get contours
contours, hierarchy = cv2.findContours(img_erode, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
output = img.copy()
letters = []
for idx, contour in enumerate(contours):
(x, y, w, h) = cv2.boundingRect(contour)
if hierarchy[0][idx][3] == 0:
cv2.rectangle(output, (x, y), (x + w, y + h), (70, 0, 0), 1)
letter_crop = gray[y:y + h, x:x + w]
# Resize letter canvas to square
size_max = max(w, h)
letter_square = 255 * np.ones(shape=[size_max, size_max], dtype=np.uint8)
if w > h:
# Enlarge image top-bottom
y_pos = size_max // 2 - h // 2
letter_square[y_pos:y_pos + h, 0:w] = letter_crop
elif w < h:
# Enlarge image left-right
x_pos = size_max // 2 - w // 2
letter_square[0:h, x_pos:x_pos + w] = letter_crop
else:
letter_square = letter_crop
# Resize letter to 28x28 and add letter and its X-coordinate
letters.append((x, w, cv2.resize(letter_square, (out_size, out_size), interpolation=cv2.INTER_AREA)))
# Sort array in place by X-coordinate
letters.sort(key=lambda x: x[0], reverse=False)
#Save letters
counter = 1
for i in range(len(letters)):
for j in range(len(letters[i])):
cv2.imshow("0", letters[i][j])
# cv2.waitKey(0)
# cv2.destroyAllWindows()
cv2.imwrite("imag/"+str(counter)+".jpg", letters[i][j])
counter = counter + 1
return letters
def img_to_str(model: Any, image_file: str):
letters = letters_extract(image_file)
s_out = ""
for i in range(len(letters)):
dn = letters[i + 1][0] - letters[i][0] - letters[i][1] if i < len(letters) - 1 else 0
s_out += emnist_predict_img(model, letters[i][2])
if (dn > letters[i][1] / 4):
s_out += ' '
return s_out
Ответы (1 шт):
Автор решения: Denis Murashko
→ Ссылка
Вот этот кот работает лучше,но я не могу понять как мне его ограничить в плане получения контуров.
img = cv2.imread('C:\\Users\\dennn\\PycharmProjects\\untitled2\\imag\\output5.jpg')
# grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.waitKey(0)
# binarize
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY_INV)
cv2.waitKey(0)
# find contours
ctrs, hier = cv2.findContours(thresh.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
# sort contours
sorted_ctrs = sorted(ctrs, key=lambda ctr: cv2.boundingRect(ctr)[0])
for i, ctr in enumerate(sorted_ctrs):
# Get bounding box
x, y, w, h = cv2.boundingRect(ctr)
# Getting ROI
roi = img[y:y + h, x:x + w]
# show ROI
# cv2.imwrite('roi_imgs.png', roi)
cv2.imshow('charachter' + str(i), roi)
cv2.rectangle(img, (x, y), (x + w, y + h), (90, 0, 255), 2)
cv2.waitKey(0)
cv2.imshow('marked areas', img)
cv2.waitKey(0)