OpenCV оттенки серого игнорируют красный цвет - PullRequest
0 голосов
/ 08 июня 2018

Я делаю приложение для распознавания цифр (OCR), поэтому мне нужно подготовить для него imamge.Нет проблем, когда я перевожу фотографию на синий, зеленый, желтый или другой цвет, но красные цифры становятся такими серыми после того, как в OpenCV они становятся серыми, и эти цифры не могут быть распознаны.

Исходное изображение: enter image description here

Изображение после оттенков серого (желтые и красные цифры): enter image description here

Изображение после порога:

enter image description here

Как видите, после этого красные цифры исчезли.

Вот фрагмент кода, который я использую:

mat.ConvertTo(mat, CvType.Cv8uc1);
Imgproc.CvtColor(mat, mat, Imgproc.ColorBgr2gray);
Imgproc.Threshold(mat, mat, 127, 255, Imgproc.ThreshBinary);

Какие-нибудь решения?

Ответы [ 2 ]

0 голосов
/ 08 июня 2018

@ Решение Джеру Люка должно быть достаточно надежным для широкого диапазона входных изображений.Но если вам нужна необработанная скорость, вы можете подумать о простой операции яркости / контрастности, за которой следует глобальное пороговое значение.

Если вы используете яркость и контрастность, что вычислительно дешево, вы можете сделать фон черным, а затемиспользуйте глобальное пороговое значение, чтобы получить хорошее двоичное изображение.

Фоторедакторы (Photoshop, Gimp и т. д.) часто используют шкалу яркости / контраста ± 127.Математическая формула для одновременного добавления яркости (b) и контрастности (c) равна

img = (1 + c / 127) * img + (bc)

Еслиу вас есть доступ к mat из C #, затем вы можете использовать функцию cv.mat.convertTo :

cv.Mat.convertTo( OutputArray, cv.CV_8U, 1+c/127, b-c)

Для вашего изображения я использовал b = -45 и c = +45

Затем преобразуйте в оттенки серого и оцифруйте (я использовал порог 50 на вашем изображении)

Обновление

OP был помечен для C #.Но многие из нас используют Python.В Python у нас нет доступа к Mat.Однако мы можем использовать функцию cv2.addWeighted, которая выполняет:

dst = src1 * alpha + src2 * beta + gamma

Если мы установим beta = 0, тоэто становится эквивалентным cv.Mat.convertTo масштабированию.Кажется, это быстрее, чем делать матричные операции в Numpy.Numpy немного медленнее, потому что мы должны сделать некоторые дополнительные вещи для обработки переполнения.

0 голосов
/ 08 июня 2018

Как я уже упоминал в комментариях, вы можете выполнить порог Оцу для каждого из цветовых каналов R, G, B.

Порог Оцу синего канала:

enter image description here

Порог Оцу красного канала:

enter image description here

Порог Оцу красного канала:

enter image description here

Наконец я добавил все вышеперечисленное, чтобы получить следующий результат:

enter image description here

Я использовал толькоследующие функции:

  1. cv2.threshold()

  2. cv2.add()

ОБНОВЛЕНИЕ

код

import os
import cv2
import numpy as np

#--- performs Otsu threshold ---
def threshold(img, st):
    ret, thresh = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
    cv2.imwrite(os.path.join(path, 'res_' + str(st) + '.jpg'), thresh) 
    return  thresh

path = r'C:\Users\Desktop'
filename = 'digits.jpg'

img = cv2.imread(os.path.join(path, filename))
img = cv2.resize(img, (0, 0), fx = 0.5, fy = 0.5)   #--- resized the image because it was to big 
cv2.imshow('Original', img)

#--- see each of the channels individually ---
cv2.imshow('b', img[:,:,0])
cv2.imshow('g', img[:,:,1])
cv2.imshow('r', img[:,:,2])

m1 = threshold(img[:,:,0], 1)   #--- threshold on blue channel
m2 = threshold(img[:,:,1], 2)   #--- threshold on green channel
m3 = threshold(img[:,:,2], 3)   #--- threshold on red channel

#--- adding up all the results above ---
res = cv2.add(m1, cv2.add(m2, m3))

cv2.imshow('res', res)
cv2.imwrite(os.path.join(path, 'res.jpg'), res)

cv2.waitKey()
cv2.destroyAllWindows()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...