I am trying to detect the corners of a grid within various pictures I have to process. Images can be skewed and some might be relatively well oriented but we cannot guarantee that all images will be like this.
To determine the corners of the grid, I have tried using Hough lines but to no avail. Sometimes the Hough lines don't identify the edge of the grid and it is hard to determine which of the lines drawn belong to the edge of the grid and which of them are grid lines.
I then decided to use contours to detect the edges of the grid. It however, picks up on numerous contours and it leads to the same problem of identifying which are at the corners amongst all the contours identified.
To help aid this, I've used bilateral filtering, Canny edge detection, morphological dilation, and Harris edge detection as seen in a question with a similar problem as mine. Even after applying all those measures, I still get tons of false corners and sometimes true corners aren't identified.
I was wondering if anyone had a way for me to improve the results of my corner detection or if anyone had a completely different suggestion in mind that might help solve my problem. The goal is to get the corners so I can perform a homography using a 10 X 10 grid to account for skewing in the images. It will also help map grid square to pixel space which is very useful.
This is my code (a bit sloppy with the naming and all but I'll try and fix that later). Also, yes, I went all out on the bilateral filtering, it seemed to help get rid of unnecessary contours and corners.
I also seem to get one error when I tried applying the Hough lines to my contoured image:
error: (-215) img.type() == (((0) & ((1 << 3) - 1)) + (((1)-1) << 3)) in function cv::HoughLinesStandard
from PIL import Image
import numpy as np
import cv2
import glob
#import images using opencv
images = [cv2.imread(file) for file in glob.glob("SpAMImages/*.jpg")]
for image in images:
#resizes image gotten from folder and performs bilateral filtering
img = cv2.bilateralFilter(cv2.resize(image, (715,715)), 15, 800, 800)
#applies a canny edge detection filter on the images loaded from the folder
gridEdges = cv2.Canny(img, 140, 170)
#apply image dilation
kernel = np.ones((5,5), np.uint8)
gridEdges = cv2.dilate(gridEdges, kernel, iterations=1)
gridEdges = np.float32(gridEdges)
gridEdges = cv2.blur(gridEdges,(10,10))
gridEdges = cv2.cornerHarris(gridEdges,2,3,0.04)
gridEdges = cv2.dilate(gridEdges,None)
img[gridEdges>0.01*gridEdges.max()]=[0,0,255]
#draw contours on current image
imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(imgray, 127, 255, 0)
contourImage, contours, hierarchy =
cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
contour = cv2.drawContours(img, contours, -1, (0,255,0), 3)
'''
def largest_4_sided_contour(thresh, show_contours=True):
contourImage, contours, hierarchy =
cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
contour = cv2.drawContours(img, contours, -1, (0,255,0), 3)
contours = sorted(contours, key = cv2.contourArea, reverse = True)
for cnt in contours[:min(5, len(contours))]:
print(len(cnt))
if len(cnt) == 4:
return cnt
return None
print(largest_4_sided_contour(thresh))
#applies a hough transformation to extract gridlines from the image
-----------THIS LINE BELOW GIVES ME THE ERROR-----------------
lines = cv2.HoughLines(img, 1, np.pi/180, 245)
#iterates through an array of lines gottne from the hough transform
#and draws them unto the image
for i in range(len(lines)):
for rho,theta in lines[i]:
a = np.cos(theta)
b = np.sin(theta)
x0 = a * rho
y0 = b * rho
x1 = int(x0 + 1000*(-b))
y1 = int(y0 + 1000*(a))
x2 = int(x0 - 1000*(-b))
y2 = int(y0 - 1000*(a))
cv2.line(img, (x1,y1),(x2,y2),(0,0,255),2)
cv2.imwrite('houghlines.jpg', img)
'''
#resize window because for some reason they are too large.
cv2.namedWindow('image', cv2.WINDOW_NORMAL)
cv2.resizeWindow('image', 800, 800)
#display all the images produced from above processes
cv2.imshow('image', img)
cv2.imshow('dilated edges', gridEdges)
#cv2.imshow('contour', contour)
cv2.waitKey(0)
'''
retrieve image size from imported image.
testImageWidth, testImageHeight = img.shape[:2]
print(testImageHeight, testImageWidth)'''
These are some images gotten from my attempt to obtain corners using contour detection and Harris corner detection.
Identifying corners using contours and harris corner detection:
And some examples of the images I have to work with.
Prime example grid:
Somewhat skewed grid:
Thanks for any help in advance!!!