问题
I used Hough lines to get intersection of horizontal and vertical lines in this image:
but the complexity grows with the grid cells count significantly.
Is there any simple way to complete the grid without using line detection ?
Thank you.
回答1:
Here's a potential solution using morphological operations with OpenCV
Obtain binary image. Load image, grayscale, Gaussian blur, Otsu's threshold
Obtain horizontal/vertical lines masks. Create horizontal/vertical kernel and isolate horizontal/vertical grid lines with cv2.getStructuringElement and cv2.morphologyEx
Combine masks. Bitwise-and masks together to complete grid
Fill individual grid holes. Find contours and fix holes by filling in each grid cell
Binary image
Horizontal mask (left) and vertical mask (right)
Combine masks
Repair individual grid holes
Invert for result
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:
I thought of a creative solution that based on morphological operations.
The final result is not so impressive, and I don't know if it fulfills your goals.
I implemented the code in MATLAB (you didn't add a language tag).
Here is the code (details are in the comments):
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.
Results:
BW1:
BW2:
J:
来源:https://stackoverflow.com/questions/60361575/how-to-repair-incomplete-grid-cells-and-fix-missing-sections-in-image