Skip to content
Snippets Groups Projects
Commit e25437b1 authored by Sebastian Böttger's avatar Sebastian Böttger
Browse files

implement corner detection

parent 2e4f7ec2
No related branches found
No related tags found
No related merge requests found
#%% imports
import cv2
import cv2 as cv
import numpy as np
import imutils as im
from scipy.spatial import distance
import matplotlib.pyplot as plt
#%% clases
class ImageAnalyser():
def __init__(self):
self._image_path = None
self.__image = None
def __init__(self, image_path, corner_value = 0.04):
self.image_path = image_path
self.corner_value = corner_value
self.load_image(image_path)
self.outline_image = None
self.cart_path = None
self.pol_path = None
self.index_high_spots = None
self.index_corners = None
self.angles = None
self.corners = None
def load_image(self, path):
self.__image = cv2.imread(path)
\ No newline at end of file
self.image = cv.imread(path)
def show_image(self, path):
cv.show("puzzle piece", self.image)
cv.waitKey(0)
cv.destroyAllWindows()
def get_outline_image(self):
if self.outline_image is not None:
self.find_outline_image()
return self.outline_image
def find_outline_image(self):
gray = cv.cvtColor(self.image,cv.COLOR_BGR2GRAY)
outline_detection = np.zeros_like(gray)
found_white = False
for line in range(gray.shape[0]):
for col in range(gray.shape[1]):
if gray[line, col] > 30:
if not found_white:
outline_detection[line, col] = 255
found_white = True
else:
if found_white:
outline_detection[line, col-1] = 255
found_white = False
for col in range(gray.shape[1]):
for line in range(gray.shape[0]):
if gray[line, col] > 30:
if not found_white:
outline_detection[line, col] = 255
found_white = True
else:
if found_white:
outline_detection[line-1, col] = 255
found_white = False
self.outline_image = outline_detection.copy()
def convert_to_cart_path(self, outline_image):
cart_path = np.where(outline_image > 10)
cart_path = np.stack(cart_path, 1)
cart_path = self.sort_by_diff(cart_path)
self.cart_path = cart_path.copy()
def sort_by_diff(self, cart_path):
sorted_cart_path = np.zeros_like(cart_path)
unsorted_cart_path = cart_path.copy()
sorted_cart_path[0] = unsorted_cart_path[0]
unsorted_cart_path = unsorted_cart_path[1:]
for index in range(unsorted_cart_path.shape[0]):
distances = distance.cdist(sorted_cart_path[np.newaxis, index], unsorted_cart_path, 'euclidean')
min_index = np.argmin(distances)
sorted_cart_path[index+1] = unsorted_cart_path[min_index]
unsorted_cart_path = np.delete(unsorted_cart_path, min_index, axis=0)
return sorted_cart_path
def get_center_point(self, cart_path):
return np.array(cart_path.mean(axis=0),dtype = int)
def convert_to_pol_path(self, cart_path):
center_point = self.get_center_point(cart_path)
center_point[0]*=(-1)
shifted_cart_path = cart_path.copy()
shifted_cart_path[:,0]*=(-1)
shifted_cart_path -= center_point
pol_path = np.zeros_like(cart_path, dtype=float)
pol_path[:,0] = np.sqrt((shifted_cart_path**2).sum(axis=1))
pol_path[:,1] = np.arctan2(shifted_cart_path[:,1], shifted_cart_path[:,0])
shift = pol_path.shape[0] - pol_path[:,1].argmin()
pol_path = np.roll(pol_path, shift, axis=0)
self.cart_path = np.roll(self.cart_path, shift, axis=0)
self.pol_path = pol_path.copy()
def get_high_spots_index(self):
if self.index_high_spots is not None:
self.find_high_spots_index(self.pol_path)
return self.index_high_spots
def find_high_spots_index(self, pol_path, size=20):
size //= 2
index_high_spots = np.array([], dtype=int)
for index in range(pol_path.shape[0])[10:-10]:
if pol_path[index,0] == pol_path[index-size:index+size, 0].max():
index_high_spots = np.append(index_high_spots, index)
self.index_high_spots = index_high_spots.copy()
def calculate_angle(self, index_high_spots, size=20):
size //= 2
angles = np.zeros_like(index_high_spots, dtype=float)
points = np.zeros((index_high_spots.shape[0],3,2))
points[:,0] = self.pol_path[index_high_spots-size]
points[:,1] = self.pol_path[index_high_spots]
points[:,2] = self.pol_path[index_high_spots+size]
points = points[:,:,[1,0]]
angles = self.calculate_gamma(points)
self.angles = angles.copy()
def calculate_gamma(self, points):
sides = np.zeros((points.shape[0],3))
sides[:,0] = np.sqrt(((points[:,2]-points[:,1])**2).sum(axis=1))
sides[:,1] = np.sqrt(((points[:,0]-points[:,1])**2).sum(axis=1))
sides[:,2] = np.sqrt(((points[:,0]-points[:,2])**2).sum(axis=1))
numerators = (sides[:,0]**2) + (sides[:,1]**2) - (sides[:,2]**2)
denominators = 2* sides[:,0]*sides[:,1]
angles = np.arccos(numerators/denominators)
return angles
def extracted_corners(self):
if self.angles is None:
raise Exception('No angles was found!')
self.index_corners = self.index_high_spots[self.angles<self.corner_value]
if self.index_corners.size > 4:
raise Exception('More than four corners are possible!')
if self.index_corners.size < 4:
raise Exception('Less than four corners are deteceted!')
self.corners = np.zeros((4,2), dtype=int)
self.corners = self.cart_path[self.index_corners]
shift = self.cart_path.shape[0] - self.index_high_spots[self.corners.sum(axis=1).argmin()]
self.index_corners = np.roll(self.index_corners, self.index_corners.size - self.corners.sum(axis=1).argmin(), axis=0)
self.corners = np.roll(self.corners, self.corners.size - self.corners.sum(axis=1).argmin(), axis=0)
self.cart_path = np.roll(self.cart_path, shift, axis=0)
self.pol_path = np.roll(self.pol_path, shift, axis=0)
self.index_corners = (self.index_corners + shift) % self.cart_path.shape[0]
def split_sites(self):
self.sides_cart_path = np.array([[],[],[],[]],dtype=np.ndarray)
for i in range(3):
self.sides_cart_path[i] = self.cart_path[self.index_corners[i]:self.index_corners[i+1]]
self.sides_cart_path[3] = self.cart_path[self.index_corners[3]:]
#%% test functions
def print_outline(cart_path, image_shape):
image = np.zeros(image_shape)
for index in range(cart_path.shape[0]):
y,x = cart_path[index]
image[y,x] = 255
if index%500 == 0:
cv.imshow("outline sorted", image)
cv.waitKey(0)
cv.destroyWindow("outline sorted")
cv.imshow("outline sorted", image)
cv.waitKey(0)
cv.destroyWindow("outline sorted")
def show_pol_path(pol_path):
pol_path_edit = pol_path.copy()
#(pol_path_edit[pol_path_edit[:,1]<0])[:,1] = (pol_path_edit[pol_path_edit[:,1]<0][:,1]*(-1))+np.pi
plt.plot(pol_path_edit[:,1], pol_path_edit[:,0])
#%% test script
if __name__ == "__main__":
image_path = "..\\..\\resources\\binary_pic\\binary_puzzle.png"
print("create image analyser")
ia = ImageAnalyser(image_path)
cv.imshow("binary image", ia.image)
cv.waitKey(0)
cv.destroyAllWindows()
print("find outline image")
ia.find_outline_image()
cv.imshow("outline image", ia.outline_image)
cv.waitKey(0)
cv.destroyAllWindows()
print("convert to cartesian coordinates")
ia.convert_to_cart_path(ia.outline_image)
print_outline(ia.cart_path, ia.outline_image.shape)
print("convert to polar coordianates")
ia.convert_to_pol_path(ia.cart_path)
show_pol_path(ia.pol_path)
print("find high spots")
ia.find_high_spots_index(ia.pol_path)
print (ia.get_high_spots_index())
print("calculate angles")
ia.calculate_angle(ia.index_high_spots)
print(ia.angles)
print("extracted corners")
ia.extracted_corners()
print(ia.corners)
#%% playground
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment