Мой код работает, но он может извлекать только числа 1, 2, 3. Он не может обнаружить 4, потому что во входном изображении нижняя граница изображения резко обрывается. То есть у него нет границы в качестве верхней и левой границы изображения. Если входное изображение имеет границы со всех сторон, вы получите желаемый результат. Кроме того, если ваше входное изображение не содержит границы, вы все равно можете использовать этот код после простого шага. Просто добавьте границу шириной в несколько пикселей внизу и справа от изображения с помощью функции cv2.copyMakeBorder ().
Код: (поясняется ниже)
img = cv2.imread("num.png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
edge = cv2.Canny(gray, 0, 40)
Contours, Hierarchy = cv2.findContours(edge, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
Ratios = []
for i in range(len(Contours)):
Contour = Contours[i]
# Getting bounding rectangle
Rect = cv2.boundingRect(Contour)
# Drawing contour on new image and finding number of white pixels for contour area
C_Image = np.zeros(edge.shape, dtype=np.uint8)
cv2.drawContours(C_Image, [Contour], -1, 255, -1)
ContourArea = np.sum(C_Image == 255)
# Area of the bounding rectangle
Rect_Area = Rect[2]*Rect[3]
# Calculating ratio as explained above
Ratio = ContourArea / Rect_Area
Ratios.append(Ratio)
RequiredContours = []
for i in range(len(Ratios)):
if Ratios[i] > 0.95:
if Hierarchy[0][i][2] != -1:
if Ratios[Hierarchy[0][i][2]] < 0.95:
RequiredContours.append(Contours[i])
if len(RequiredContours) > 0:
FinalContour = RequiredContours[0]
for i in range(1, len(RequiredContours)):
FinalContour = np.append(FinalContour, RequiredContours[i], axis=0)
(x, y, w, h) = cv2.boundingRect(FinalContour)
FinalImage = img[y : y + h, x : x + w]
cv2.imwrite("FinalImage.png", FinalImage)
Прочтите документацию OpenCV, чтобы лучше понять используемые функции.
Сначала я читаю изображение, конвертирую его в оттенки серого и нахожу изображение края.
Затем я я нахожу все контуры с отношениями родитель-потомок на изображении. (Обратите внимание на флаг RETR_TREE).
Теперь для каждого контура в l oop я нахожу соотношение площади контура (в пикселях ) в область его ограничивающего прямоугольника (в пикселях). Для контура прямоугольной / квадратной формы соотношение будет почти 1
, но я сохранил порог ошибки 0.05
, поэтому, если соотношение больше 0.95
, то это прямоугольный / квадратный контур, иначе это будет контуры других форм (например, числа внутри ящиков).
Теперь, используя найденную выше крысу ios и Иерархию контуров, я обнаружил, что эти контуры имеют прямоугольную / квадратную форму и не имеют -править angular контур внутри них. Теперь я сохраняю все такие контуры в переменной «RequiredContours».
Теперь нам нужно объединить все контуры «RequiredContours» и сохранить их как единый контур («FinalContour»). Причина в том, что если у нас есть эти контуры по отдельности, то обрезать эти контуры и сохранить их в одном изображении было бы очень долго.
контур и увы обрезать его из входного изображения и сохранить конечное изображение.
Выходное изображение кода:
вывод