Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
A
AI Chess Robot
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
jhur22
AI Chess Robot
Commits
a3406f8d
Commit
a3406f8d
authored
11 months ago
by
zalonzo2
Browse files
Options
Downloads
Patches
Plain Diff
cleaned up comments, now finding midpoints of intersections
parent
2564b03b
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
board_detector.py
+49
-73
49 additions, 73 deletions
board_detector.py
with
49 additions
and
73 deletions
board_detector.py
+
49
−
73
View file @
a3406f8d
...
...
@@ -10,32 +10,6 @@ def init_show_cv(val):
def
find_longest_lines
(
img
):
gray_img
=
cv2
.
cvtColor
(
img
,
cv2
.
COLOR_BGR2GRAY
)
hsv_img
=
cv2
.
cvtColor
(
img
,
cv2
.
COLOR_BGR2HSV
)
# hsv_mask = cv2.inRange(hsv_img[:,:,1], 50, 255)
# hsv_after = cv2.bitwise_and(img, img, mask=hsv_mask)
# if (show_cv):
# cv2.imshow('HSV', hsv_after)
# cv2.waitKey(0)
# cv2.destroyAllWindows()
# gray_hsv = cv2.cvtColor(hsv_after, cv2.COLOR_HSV2BGR)
# gray_hsv = cv2.cvtColor(hsv_after, cv2.COLOR_BGR2GRAY)
# gray_img = gray_img - gray_hsv
# # sobel gradients
# sobel_x = cv2.Sobel(gray_img, cv2.CV_64F, 1, 0, ksize=3)
# sobel_y = cv2.Sobel(gray_img, cv2.CV_64F, 0, 1, ksize=3)
# abs_sobel_x = np.absolute(sobel_x)
# abs_sobel_y = np.absolute(sobel_y)
# # threshold on abs values of sobel gradients and combine them
# _, threshold_x = cv2.threshold(abs_sobel_x, 25, 255, cv2.THRESH_BINARY)
# _, threshold_y = cv2.threshold(abs_sobel_y, 25, 255, cv2.THRESH_BINARY)
# combined_threshold = cv2.bitwise_or(threshold_x, threshold_y)
# combined_threshold = np.uint8(combined_threshold) # median blur needs this
# combined_threshold = cv2.medianBlur(combined_threshold, 5) # this gets rid of outliers so weird diagonal lines don't get made
# edges = combined_threshold
edges
=
cv2
.
Canny
(
gray_img
,
50
,
100
,
apertureSize
=
3
)
if
(
show_cv
):
...
...
@@ -43,41 +17,24 @@ def find_longest_lines(img):
cv2
.
waitKey
(
0
)
cv2
.
destroyAllWindows
()
# lines = cv2.HoughLinesP(edges, 1, np.pi/180, 200, minLineLength=400, maxLineGap=15)
# print(lines)
# lines = cv2.HoughLines(edges, 1, np.pi / 180, 200)
# lines = cv2.HoughLines(edges, rho=1, theta=np.pi/180, threshold=80, min_theta=0, max_theta=np.pi)
theta_thresh
=
50
horizontal_lines
=
cv2
.
HoughLines
(
edges
,
rho
=
1
,
theta
=
np
.
pi
/
180
,
threshold
=
80
,
min_theta
=
(
theta_thresh
/
2
-
1
)
*
np
.
pi
/
theta_thresh
,
max_theta
=
(
theta_thresh
/
2
+
1
)
*
np
.
pi
/
theta_thresh
)
vertical_lines
=
cv2
.
HoughLines
(
edges
,
rho
=
1
,
theta
=
np
.
pi
/
180
,
threshold
=
80
,
min_theta
=-
np
.
pi
/
theta_thresh
,
max_theta
=
np
.
pi
/
theta_thresh
)
vertical_line_points
=
convert_lines
(
vertical_lines
)
horizontal_line_points
=
convert_lines
(
horizontal_lines
)
# vertical_lines = []
# horizontal_lines = []
# # separate horizontal and vertical lines
# if line_points is not None:
# for line in line_points:
# x1, y1, x2, y2 = line[0]
# if abs(x2 - x1) < abs(y2 - y1): # vertical line
# vertical_lines.append(line)
# else:
# horizontal_lines.append(line)
# # filter lines too close to each other
theta_thresh
=
60
horizontal_lines
=
cv2
.
HoughLines
(
edges
,
rho
=
1
,
theta
=
np
.
pi
/
180
,
threshold
=
60
,
min_theta
=
(
theta_thresh
/
2
-
1
)
*
np
.
pi
/
theta_thresh
,
max_theta
=
(
theta_thresh
/
2
+
1
)
*
np
.
pi
/
theta_thresh
)
vertical_lines
=
cv2
.
HoughLines
(
edges
,
rho
=
1
,
theta
=
np
.
pi
/
180
,
threshold
=
60
,
min_theta
=-
np
.
pi
/
theta_thresh
,
max_theta
=
np
.
pi
/
theta_thresh
)
vertical_line_points
=
convert_to_cartesian
(
vertical_lines
)
horizontal_line_points
=
convert_to_cartesian
(
horizontal_lines
)
# filter lines too close to each other
filtered_vertical
=
filter_lines
(
vertical_line_points
,
50
)
filtered_horizontal
=
filter_lines
(
horizontal_line_points
,
50
)
# get the 9 largest lines
sorted_vertical
=
sorted
(
filtered_vertical
,
key
=
lambda
line
:
min
(
line
[
0
][
1
],
line
[
0
][
3
]))[:
9
]
sorted_horizontal
=
sorted
(
filtered_horizontal
,
key
=
lambda
line
:
min
(
line
[
0
][
0
],
line
[
0
][
2
]))[:
9
]
return
sorted_vertical
,
sorted_horizontal
# return vertical_line_points, horizontal_line_points
def
convert_lines
(
lines
):
def
convert_to_cartesian
(
lines
):
line_points
=
[]
if
lines
is
not
None
:
for
line
in
lines
:
...
...
@@ -151,12 +108,30 @@ def detect_board(img):
board_lines
=
cv2
.
bitwise_or
(
vertical_mask
,
horizontal_mask
)
contours
,
hierarchy
=
cv2
.
findContours
(
board_lines
,
cv2
.
RETR_TREE
,
cv2
.
CHAIN_APPROX_SIMPLE
)
intersection_points
,
hierarchy
=
cv2
.
findContours
(
intersection
,
cv2
.
RETR_TREE
,
cv2
.
CHAIN_APPROX_SIMPLE
)
intersections
,
hierarchy
=
cv2
.
findContours
(
intersection
,
cv2
.
RETR_TREE
,
cv2
.
CHAIN_APPROX_SIMPLE
)
# find midpoints of intersection contours (this gives us exact coordinates of the corners of the grid)
intersection_points
=
[]
for
contour
in
intersections
:
M
=
cv2
.
moments
(
contour
)
if
(
M
[
"
m00
"
]
!=
0
):
midpoint_x
=
int
(
M
[
"
m10
"
]
/
M
[
"
m00
"
])
midpoint_y
=
int
(
M
[
"
m01
"
]
/
M
[
"
m00
"
])
intersection_points
.
append
((
midpoint_x
,
midpoint_y
))
# sort the coordinates from left to right then top to bottom
sorted_intersection_points
=
sort_square_grid_coords
(
intersection_points
,
unpacked
=
False
)
if
(
show_cv
):
board_lines_img
=
img
.
copy
()
cv2
.
drawContours
(
board_lines_img
,
contours
,
-
1
,
(
255
,
255
,
0
),
2
)
cv2
.
drawContours
(
board_lines_img
,
intersection_points
,
-
1
,
(
0
,
0
,
255
),
2
)
# cv2.drawContours(board_lines_img, intersections, -1, (0, 0, 255), 2)
i
=
0
for
points
in
sorted_intersection_points
:
for
point
in
points
:
cv2
.
circle
(
board_lines_img
,
point
,
5
,
(
255
-
(
3
*
i
),
(
i
%
9
)
*
28
,
3
*
i
),
-
1
)
i
+=
1
print
(
i
)
cv2
.
imshow
(
'
Lines of Board
'
,
board_lines_img
)
cv2
.
waitKey
(
0
)
cv2
.
destroyAllWindows
()
...
...
@@ -201,23 +176,22 @@ def detect_board(img):
corners
=
max_rect
.
reshape
(
-
1
,
2
)
# reshapes it so each row has 2 elements
corners
=
[
tuple
(
corner
)
for
corner
in
corners
]
# convert to tuples
print
(
corners
)
# corners.sort(key=lambda coord: (coord[0], coord[1])) # sort coords. goes from bottom left clockwise to bottom right
corners_sorted
=
sort_square_grid_coords
(
corners
)
# corners.sort(key=lambda coord: (coord[0], coord[1])) # sort coords. goes from bottom left clockwise to bottom right
- DIDN'T WORK
corners_sorted
=
sort_square_grid_coords
(
corners
,
unpacked
=
True
)
print
(
corners_sorted
)
corners
=
corners_sorted
corners_img
=
img
.
copy
()
for
i
,
corner
in
enumerate
(
corners
):
cv2
.
circle
(
corners_img
,
corner
,
5
,
(
60
*
i
,
60
*
i
,
60
*
i
),
-
1
)
if
(
show_cv
):
cv2
.
imshow
(
'
Canny Filter
'
,
corners_img
)
cv2
.
waitKey
(
0
)
cv2
.
destroyAllWindows
()
#
corners_img = img.copy()
#
for i, corner in enumerate(corners
_sorted
):
#
cv2.circle(corners_img, corner, 5, (60 * i, 60 * i, 60 * i), -1)
#
if (show_cv):
#
cv2.imshow('Canny Filter', corners_img)
#
cv2.waitKey(0)
#
cv2.destroyAllWindows()
tl
=
corners
[
0
]
tr
=
corners
[
1
]
bl
=
corners
[
2
]
br
=
corners
[
3
]
tl
=
corners
_sorted
[
0
]
tr
=
corners
_sorted
[
1
]
bl
=
corners
_sorted
[
2
]
br
=
corners
_sorted
[
3
]
src
=
np
.
float32
([
list
(
tl
),
list
(
tr
),
list
(
bl
),
list
(
br
)])
dest
=
np
.
float32
([[
0
,
0
],
[
width
,
0
],
[
0
,
height
],
[
width
,
height
]])
M
=
cv2
.
getPerspectiveTransform
(
src
,
dest
)
...
...
@@ -228,7 +202,7 @@ def detect_board(img):
M
=
cv2
.
getPerspectiveTransform
(
src
,
dest
)
Minv
=
cv2
.
getPerspectiveTransform
(
dest
,
src
)
warped_ip
=
img
.
copy
()
warped_ip
=
cv2
.
drawContours
(
warped_ip
,
intersection
_point
s
,
-
1
,
(
0
,
0
,
255
),
2
)
warped_ip
=
cv2
.
drawContours
(
warped_ip
,
intersections
,
-
1
,
(
0
,
0
,
255
),
2
)
warped_ip
=
cv2
.
warpPerspective
(
np
.
uint8
(
warped_ip
),
M
,
(
width
,
height
))
if
(
show_cv
):
...
...
@@ -254,7 +228,7 @@ def detect_board(img):
# cv2.waitKey(0)
# cv2.destroyAllWindows()
def
sort_square_grid_coords
(
coordinates
):
def
sort_square_grid_coords
(
coordinates
,
unpacked
):
sqrt_len
=
int
(
math
.
sqrt
(
len
(
coordinates
)))
sorted_coords
=
sorted
(
coordinates
,
key
=
lambda
coord
:
coord
[
1
])
# first sort by y values
# then group rows of the square (for example, 9x9 grid would be 81 coordinates so split into 9 arrays of 9)
...
...
@@ -262,6 +236,8 @@ def sort_square_grid_coords(coordinates):
for
group
in
groups
:
group
.
sort
(
key
=
lambda
coord
:
coord
[
0
])
# now sort each row by x
collapsed_groups
=
[
coord
for
sublist
in
groups
for
coord
in
sublist
]
if
(
unpacked
==
False
):
return
groups
collapsed_groups
=
[
coord
for
sublist
in
groups
for
coord
in
sublist
]
# unpack/collapse groups to just be an array of tuples
return
collapsed_groups
\ No newline at end of file
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment