Как исправить неполные ячейки сетки и исправить недостающие участки в изображении - PullRequest
2 голосов
/ 23 февраля 2020

Я использовал линии Hough, чтобы получить пересечение горизонтальных и вертикальных линий на этом изображении:

enter image description here

, но сложность возрастает при значительном количестве ячеек сетки ,

Есть ли какой-нибудь простой способ завершить сетку без использования определения линии?

Спасибо.

Ответы [ 2 ]

4 голосов
/ 25 февраля 2020

Вот потенциальное решение с использованием морфологических операций с OpenCV

  1. Получение бинарного изображения. Загрузка изображения, оттенки серого, размытие по Гауссу , Порог Оцу

  2. Получение масок горизонтальных / вертикальных линий. Создание горизонтального / вертикального ядра и изоляция горизонтальных / вертикальных линий сетки с помощью cv2.getStructuringElement и cv2.morphologyEx

  3. Объединение масок. Побитовые и маски вместе для завершения сетки

  4. Заполните отдельные отверстия сетки. Найдите контуры и зафиксируйте отверстия, заполнив каждую ячейку сетки


Двоичное изображение

image

Горизонтальная маска (слева) и вертикальная маска (справа)

image image

Комбинированные маски

image

Ремонт отдельных отверстий сетки

image

Инвертировать для результата

image

import cv2

# Load image, grayscale, blur, Otsu's threshold
image = cv2.imread('1.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (3,3), 0)
thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

# Obtain horizontal lines mask
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (50,1))
horizontal_mask = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, horizontal_kernel, iterations=1)
horizontal_mask = cv2.dilate(horizontal_mask, horizontal_kernel, iterations=9)

# Obtain vertical lines mask
vertical_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1,50))
vertical_mask = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, vertical_kernel, iterations=1)
vertical_mask= cv2.dilate(vertical_mask, vertical_kernel, iterations=9)

# Bitwise-and masks together
result = 255 - cv2.bitwise_or(vertical_mask, horizontal_mask)

# Fill individual grid holes
cnts = cv2.findContours(result, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    x,y,w,h = cv2.boundingRect(c)
    cv2.rectangle(result, (x, y), (x + w, y + h), 255, -1)

cv2.imshow('thresh', thresh)
cv2.imshow('vertical_mask', vertical_mask)
cv2.imshow('horizontal_mask', horizontal_mask)
cv2.imshow('result', result)
cv2.waitKey()
2 голосов
/ 23 февраля 2020

Я подумал о креативном решении, основанном на морфологических операциях.

Конечный результат не так впечатляет, и я не знаю, соответствует ли он вашим целям.

Я реализовал код в MATLAB (вы не добавили языковой тег).

Вот код (подробности в комментариях):

I = imread('RedGrid.jpg'); %Read grid image
BW = imbinarize(rgb2gray(I)); %Convert to from RGB to Grayscale, and to binary image.
BW = ~BW; %Inverse polarity

BW = padarray(BW, [1, 1], 1); %Insert frame of white pixels around the image

BW1 = imerode(BW, ones(1, 20)); % Remove vertical lines by erode with short horizontal kernel
BW1 = imdilate(BW1, ones(1, 600)); %Complete horizontal line by dilate with long horizontal kernel
BW1 = imerode(BW1, ones(1, 800)); %Remove some of the horizontal duplications using erode with long horizontal kernel

imwrite(BW1, 'BW1.jpg')

%Repeat the above 3 stages with horizontal lines:
BW2 = imerode(BW, ones(20, 1)); % Remove vertical lines by erode with short horizontal kernel
BW2 = imdilate(BW2, ones(600, 1)); %Complete horizontal line by dilate with long horizontal kernel
BW2 = imerode(BW2, ones(800, 1)); %Remove some of the horizontal duplication using erode with long horizontal kernel

BW = BW1 | BW2; % Merge horizontal and vertical lines.

BW = BW(2:end-1, 2:end-1); %Remove the white frame added at the beginning.

%Paint lines with red color (assume the desired red is RGB = [220, 20, 20])
R = im2uint8(~BW); %Red color channel
G = im2uint8(~BW); %Green color channel
B = im2uint8(~BW); %Blue color channel
R(BW) = 220; %Red color
G(BW) = 20;
B(BW) = 20;

J = cat(3, R, G, B); % Create RGB image from R, G and B.

Результаты:

BW1:
enter image description here

BW2:
enter image description here

J:
enter image description here

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