Форум программистов, компьютерный форум, киберфорум
Python для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.53/40: Рейтинг темы: голосов - 40, средняя оценка - 4.53
1 / 1 / 0
Регистрация: 25.02.2021
Сообщений: 15

Opencv распознает числа с ошибками. Как поднять точность?

25.02.2021, 14:53. Показов 7778. Ответов 19

Студворк — интернет-сервис помощи студентам
Здравствуйте! Прошу навести на путь к решению проблемы или подсказать может я совсем далек от решения. Имеется задача: с блока питания с цифровым дисплеем получить значение дисплея в opencv python в режиме реального времени. Сейчас я имею кадры с видеопотока каждую секунду, с этого изображения с помощью tesseract получаю значения дисплея. Но значения оооочень значительно не совпадают с картинкой (например вместо 108 получаю просто 1 или 08 или 168 и тп). Как поднять точность? Буду благодарен в решении проблемы. Прошу прощения за кашу в коде.

имеется код:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import numpy as np
import cv2
import time
import imutils
 
from imutils import contours
from imutils import grab_contours
from imutils.perspective import four_point_transform
from PIL import Image
import pytesseract
 
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'
 
webcam = cv2.VideoCapture('video.mp4')
t = time.time()
 
i = 0
while (1):
    i += 1
    _, imageFrame = webcam.read()
    imageFrame = cv2.resize(imageFrame, (700, 500))
    imageFrame = cv2.rotate(imageFrame, cv2.ROTATE_90_CLOCKWISE)
    image = imageFrame[200:285, 70:440]
    cv2.imshow("frame", image)
 
    #img = cv2.GaussianBlur(image, (3, 3), 0)
    #edge = cv2.Canny(img, 255, 0)
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    gray = cv2.bilateralFilter(gray, 11, 5, 5)
    thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (1, 5))
    thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
    thresh2 = cv2.resize(thresh, (0, 0), fx=1, fy=1)
    thresh3 = cv2.threshold(thresh2, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
 
    zeroscreen = np.zeros((85, 370, 1), np.uint8)
 
    cnts = cv2.findContours(thresh3.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    cnts = imutils.grab_contours(cnts)
    digitCnts = []
    for c in cnts:
        x, y, w, h = cv2.boundingRect(c)
        if (w >= 0 and w <= 100) and (h >= 0 and h <= 100):
            cv2.rectangle(image, (x, y), (x + w, y + h), (0, 0, 0), 1)
            digitCnts.append(c)
 
    digits = []
 
    for c in digitCnts:
        cv2.drawContours(zeroscreen, digitCnts, -1, (255, 255, 255), 2)
        zer = cv2.resize(zeroscreen, (0, 0), fx=0.6, fy=1)
            #cv2.imshow('7.png', zer)
        if time.time() - t >= 1.5:
            t = time.time()
            cv2.imwrite("frames\\frame " + str(i) + ".jpg", zer)
            cv2.imwrite("7.jpg", zer)
            # print(digits)
            zer = cv2.imread("7.jpg")
            cv2.imshow('zer', zer)
            text = pytesseract.image_to_string(zer, config='--psm 13 --oem 3 -c tessedit_char_whitelist=0123456789')
            print(text)
            custom_config = r'--oem 3 --psm 6 outputbase digits'
            # print(pytesseract.image_to_string(zer, config=custom_config))
 
    if cv2.waitKey(10) & 0xFF == ord('q'):
        webcam.release()
        cv2.destroyAllWindows()
        break
Миниатюры
Opencv распознает числа с ошибками. Как поднять точность?   Opencv распознает числа с ошибками. Как поднять точность?  
Изображения
  
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
25.02.2021, 14:53
Ответы с готовыми решениями:

Как opencv, распознаёт точки на лице человека?
Можете объяснить как opencv отличает объект от лица человека и находит точки?

OpenCV как поднять FPS
Здравствуйте имею программу, датчик движения с веб камеры. При выводе изображения сильно проседает FPS и грузит CPU под завязку. Пробовал...

Как задать точность числа
У меня есть число, но оно настолько маленькое, что представляется мне в экспоненциальном виде (ну т.е. с е). А как мне задать точность, с...

19
102 / 85 / 25
Регистрация: 21.05.2019
Сообщений: 481
25.02.2021, 15:31
Adel1994, Лень читать твой код, сравни с моим, у меня была таблица с числами и я с помощью тесеракта и opencv распознавал их
1) Особенно обрати внимание на config='outputbase digits'
2) И на cv2.resize(img, None, fx=1.2, fy=2) # Увеличение изображения в 9 раз
Второе в моём случае не особо помогало, мб тебе поможет

Отпиши как сделаешь, интересно


Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import sys
import numpy as np
import cv2
import uuid
import pytesseract
import re
 
 
pytesseract.pytesseract.tesseract_cmd = r"C:\Program Files\Tesseract-OCR\tesseract.exe"
 
img = cv2.imread("123.jpg", 1)
# img = cv2.resize(img, None, fx=1.2, fy=2)  # Увеличение изображения в 9 раз
data = pytesseract.image_to_string(img, config='outputbase digits')
 
summa = list(map(float, data.split()))
list_rec = sum((float(summa[i]) for i in range(0, int(len(summa)))))
 
print("Массив - ", summa)
print("Сумма  - ", list_rec)
 
cv2.imshow('contours', img)
cv2.waitKey()
cv2.destroyAllWindows()
Добавлено через 9 минут
Ещё читал что лучше чтобы текст был чёрным а фот белым
1
1 / 1 / 0
Регистрация: 25.02.2021
Сообщений: 15
25.02.2021, 16:32  [ТС]
RSAX, как Вы и говорили, 2 случай особо не помогает (необходимо варьировать коэф для разных скринов и иногда все равно не видит некоторые цифры). В первом же случае дает примерно те же результаты, что были у меня (путаются с другими и иногда не обнаруживаются цифры). Прикладываю скрины. Также попробовал сменить фон.
Миниатюры
Opencv распознает числа с ошибками. Как поднять точность?   Opencv распознает числа с ошибками. Как поднять точность?   Opencv распознает числа с ошибками. Как поднять точность?  

Opencv распознает числа с ошибками. Как поднять точность?  
0
1 / 1 / 0
Регистрация: 25.02.2021
Сообщений: 15
25.02.2021, 16:39  [ТС]
RSAX, как Вы и говорили, 2 случай особо не помогает (необходимо варьировать коэф для разных скринов и иногда все равно не видит некоторые цифры). В первом же случае дает примерно те же результаты, что были у меня (путаются с другими и иногда не обнаруживаются цифры). Прикладываю скрины. Также попробовал сменить фон.
0
102 / 85 / 25
Регистрация: 21.05.2019
Сообщений: 481
25.02.2021, 16:43
Adel1994, хмм ещё из пассивного могу предложить поменять язык тесеракта, но для этого надо заново его ставить и все языки скачивать, по умолчанию у тебя анг, но для каждого языка делались разные датасеты, мб есть язык где именно под такие цифры подходит


Python
1
2
3
data = pytesseract.image_to_string(img, config='outputbase digits', lang="chi_sim")
data = pytesseract.image_to_string(img, config='outputbase digits', lang="eng")
data = pytesseract.image_to_string(img, config='outputbase digits', lang="rus")
Добавлено через 1 минуту
Если не поможет то только работа с входным фото, стараться сделать его границы более чёткими
1
5514 / 2867 / 571
Регистрация: 07.11.2019
Сообщений: 4,752
25.02.2021, 18:38
Adel1994,
1. Попробуйте сделать инверсию. Tesseract расчитан на распознавание печатных текстов, а там фон светлый, а символы темные.

2. Tesseract и распознавание в реальном времени несовместимы скорее всего.
3. Выложите видеофайл для тестов.
1
1 / 1 / 0
Регистрация: 25.02.2021
Сообщений: 15
25.02.2021, 21:11  [ТС]
RSAX, добавив языки вполне увеличился процент сходимости. Уже примерно половину из значений считывает верно. Причем используя разные языки распознаются разные значения.
u235, прикрепляю уже обрезанный видеофайл output.
Также прикрепил архив изображений для тестов.
Как думаете может попробовать написать свой словарь tesseract и обучить его? Или уйти от tesseract и изучить более подходящие библиотеки?
Вложения
Тип файла: rar output.rar (844.0 Кб, 17 просмотров)
Тип файла: rar frames.rar (128.6 Кб, 10 просмотров)
0
5514 / 2867 / 571
Регистрация: 07.11.2019
Сообщений: 4,752
26.02.2021, 06:41
Adel1994,
1. Предобработка. Перевод в оттенки серого COLOR_BGR2GRAY неоптимален с точки зрения подавления ореола вокруг цифр.
А вот если взять зеленый канал, то цифры получаются четкими, без ореола и дальнейшая обработка билатеральным фильтром не нужна.
Python
1
2
    gray=imageFrame[:,:,1]
    thresh = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY)[1]
2. Я бы ушел от tesseract (если важна скорость) . Вариант первый: cv2.matchTemplate(). Вариант второй: выделение разядов и сегментов индикатора. Расчет центроида разряда, других моментов, топологических инвариантов. Всего того, что быстро считается и позволит отличить одни цифры от дугих.
3. Глобальное решение проблемы: заменить вольтметр на такой же только с RS-485
Изображения
 
1
102 / 85 / 25
Регистрация: 21.05.2019
Сообщений: 481
26.02.2021, 08:55
u235, А если попробовать разделить кадр на сегменты где 1 цифра 1 сегмент, и дальше обучить через каскад хаара(минут 30 займёт)?
1
5514 / 2867 / 571
Регистрация: 07.11.2019
Сообщений: 4,752
26.02.2021, 09:34
RSAX, думаю это тоже вариант рабочий, но я хочу немного по другому сделать: дилатацией выделить разряды (намеренно не называю их сегментами чтобы не возникло путаницы с сегментами 7ми сегментного индикатора). А затем найти количество и положение горизонтальных и вертикальных сегментов в разряде. Например, 4 вертикальных и 3 горизонтальных - цифра 8.
1
102 / 85 / 25
Регистрация: 21.05.2019
Сообщений: 481
26.02.2021, 10:02
u235, Хмм да, не плохо, такое можно сделать даже с помощью встроенного поиска контуров в OpenCV, нужно всего немного увеличить фото, а дальше по двум координатам бокса понять вертикаль это или горизонталь
1
533 / 438 / 47
Регистрация: 17.07.2013
Сообщений: 2,236
26.02.2021, 10:36
Цитата Сообщение от u235 Посмотреть сообщение
найти количество и положение горизонтальных и вертикальных сегментов
Хорошо бы повернуть картинку влево градусов на 5 (подобрать точное значение угла поворота), а потом пройти фильтрами выделения горизонтальных и вертикальных линий, они в cv2 есть, работал с ними, но сейчас не помню как они называются.
0
1 / 1 / 0
Регистрация: 25.02.2021
Сообщений: 15
26.02.2021, 10:58  [ТС]
RSAX, u235, Nick07, все, что Вы написали перепробую. Отпишусь о результатах! Ну кроме RS-485)
0
5514 / 2867 / 571
Регистрация: 07.11.2019
Сообщений: 4,752
26.02.2021, 13:05
RSAX, я контуры без необходимости стараюсь не использовать. Использую Connected Component whith stats.
Nick07, зачем поворот? Тут лучше тогда уж аффинное преобразование типа сдвига. Чтобы сделать сегменты ортогональными.
1
533 / 438 / 47
Регистрация: 17.07.2013
Сообщений: 2,236
26.02.2021, 14:15
Цитата Сообщение от u235 Посмотреть сообщение
зачем поворот?
Чтобы вертикаль была и не просто поворот, а сдвиг верхней части картинки
0
5514 / 2867 / 571
Регистрация: 07.11.2019
Сообщений: 4,752
27.02.2021, 23:39
Adel1994, Сделал, но не полностью, нужно еще доделать логику разделения цифр 2,5,3 и 6,9.
Но все почти в реалтайме.
результат в архиве:
Вложения
Тип файла: zip out.zip (4.72 Мб, 6 просмотров)
1
5514 / 2867 / 571
Регистрация: 07.11.2019
Сообщений: 4,752
28.02.2021, 14:20
Лучший ответ Сообщение было отмечено Adel1994 как решение

Решение

Доделал:
скрипт
Кликните здесь для просмотра всего текста
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import numpy as np
import cv2
webcam = cv2.VideoCapture('output.avi')
 
fourcc = cv2.VideoWriter_fourcc(*'MJPG')
out = cv2.VideoWriter('result.avi', fourcc, 20.0, (300, 60))
 
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (1, 6))
kernel2 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (7, 2))
kernel_summary = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (9, 9))
numbers = {(0, 2): '1', (2, 4): '0',  (1, 0): '-', (1, 2): '7', \
          (3, 4): '8', (1, 3): '4', (3, 2): '2,3,5', (3, 3): '6,9'}
 
 
def get_vertical(img):  # select vertical lines
    return cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
 
 
def get_horizintal(img):  # select horizontal lines
    return cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel2)
 
 
def detect69(stats, i, img):
    x, y = stats[i, 0], stats[i, 1]
    w, h = stats[i, 2], stats[i, 3]
    x_up = x+w//2
    y_up = y+h//3
    w_up = w//2
    h_up = 2
    up = np.any(img[y_up:y_up+h_up, x_up:x_up+w_up])
    if up:
        return '9'
    else:
        return '6'
 
 
def detect235(stats, i, img):
    x, y = stats[i, 0], stats[i, 1]
    w, h = stats[i, 2], stats[i, 3]
    x_up = x
    y_up = y+h//3
    w_up = w//2
    h_up = 2
    up = np.any(img[y_up:y_up+h_up, x_up:x_up+w_up])
    x_down = x
    y_down = y+2*h//3
    w_down = w//2
    h_down = 2
    down = np.any(img[y_down:y_down+h_down, x_down:x_down+w_down])
    num = {(True, False): '5', (False, True): '2', (False, False): '3'}
    return num[(up, down)]
 
 
while True:
    ret, imageFrame = webcam.read()
    if ret is False:
        break
    gray = imageFrame[:, :, 1]
    thresh = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY)[1]
    retval, labels, stats, centroids = cv2.connectedComponentsWithStats(thresh, connectivity = 8)
    hor = get_horizintal(thresh)  # horizontal lines
    vert = get_vertical(thresh)  # vertical lines
    thresh = cv2.morphologyEx(thresh, cv2.MORPH_DILATE, kernel_summary)  # split image by digits
    num_sign, labels2, stats2, centroids2=cv2.connectedComponentsWithStats(thresh, connectivity = 8)
    result = []
    for i in range(1, num_sign):
        mask = cv2.bitwise_and(np.uint8(255*(labels2 == i)), hor)
        num_horiz, _ = cv2.connectedComponents(mask)
        mask = cv2.bitwise_and(np.uint8(255*(labels2 == i)), vert)
        num_vert, _ = cv2.connectedComponents(mask)
        num_horiz -= 1
        num_vert -= 1
        if (num_horiz, num_vert) in numbers:
            if (num_horiz, num_vert) == (3, 3):  # case 6,9
                num = detect69(stats2, i, vert)
            elif (num_horiz, num_vert) == (3, 2):  # case 2,3,5
                num = detect235(stats2, i, vert)
            else:
                num = numbers[(num_horiz, num_vert)]
            result.append((num, int(centroids2[i, 0])))
    result.sort(key=lambda x: x[1])  # sort signs by x-position
    imageFrame = cv2.putText(imageFrame, ''.join([i[0] for i in result]),\
                    (0, 50), cv2.FONT_HERSHEY_SIMPLEX,\
                    0.5, (40, 0, 0), 0, cv2.LINE_AA)
    cv2.imshow("frame", imageFrame)
    out.write(imageFrame)
    if cv2.waitKey(10) & 0xFF == ord('q'):
        break
cv2.destroyAllWindows()
webcam.release()
out.release()

результат в архиве:
Вложения
Тип файла: zip result.zip (4.13 Мб, 20 просмотров)
0
1 / 1 / 0
Регистрация: 25.02.2021
Сообщений: 15
01.03.2021, 09:08  [ТС]
u235, Nick07, RSAX, всем спасибо огромное!
1
102 / 85 / 25
Регистрация: 21.05.2019
Сообщений: 481
01.03.2021, 14:18
Adel1994, Получилось? Код u235 использовал?
0
1 / 1 / 0
Регистрация: 25.02.2021
Сообщений: 15
01.03.2021, 14:30  [ТС]
RSAX, да!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
01.03.2021, 14:30
Помогаю со студенческими работами здесь

OpenCV в Python не распознает лица вместе с глазами на видео. Или глаза, или ничего, третьего не дано
Здравствуйте! Пробовал запустить программу для динамического распознавания лиц и глаз на видео, приведенную в этом уроке...

Как сделать, чтобы для синуса и числа пи подбиралась своя точность вычисления
import math def is_digit(string): if string.isdigit(): return True else: try: float(string)...

Перевести десятичные числа X и Y в двоичную сс (точность перевода – 10 цифр в мантиссе нормализованного числа)
3. Перевести десятичные числа X и Y в двоичную с.с. (точность перевода – 10 цифр в мантиссе нормализованного числа). Записать их в ячейки в...

Не распознает дробные числа
Всем привет! Помогите новичку Подключил БД к Delphi (во вложении сама программа) Не распознает дробные числа, что делать?

Не распознает дробные числа
делаю калькулятор сделала функцию, кот-ую буду вызывать в последующем: Private Function result(a As Double, s As Double, z As String)...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru