Draw lines between squared points. Get rotation angles (still need to fix verts_angle())

This commit is contained in:
Matthew McWilliams 2022-11-09 16:56:14 -05:00
parent e1c6777bf8
commit 602b6dc26c
1 changed files with 98 additions and 16 deletions

View File

@ -1,6 +1,7 @@
import sys import sys
import cv2 import cv2
import numpy as np import numpy as np
import math
def image_resize(image, width = None, height = None, inter = cv2.INTER_AREA): def image_resize(image, width = None, height = None, inter = cv2.INTER_AREA):
dim = None dim = None
@ -30,6 +31,35 @@ def display (image) :
break break
exit(0) exit(0)
def get_center (contour) :
M = cv2.moments(contour)
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])
return cX, cY
def draw_line (image, hps, a, b) :
print(f'{a} -> {b}')
lA = (hps[a-1]['x'], hps[a-1]['y'])
lB = (hps[b-1]['x'], hps[b-1]['y'])
cv2.line(image, lA, lB, [0, 255, 0], 10)
return (lA, lB)
def horiz_angle (line) :
deltaY = line[1][1] - line[0][1] #P2_y - P1_y
deltaX = line[1][0] - line[0][0] #P2_x - P1_x
angleInDegrees = math.degrees(math.atan2(deltaY, deltaX))
print(angleInDegrees)
return angleInDegrees
def verts_angle (line) :
deltaY = line[1][1] - line[0][1] #P2_y - P1_y
deltaX = line[1][0] - line[0][0] #P2_x - P1_x
angleInDegrees = - (math.atan2(deltaX, deltaY) * 180 / math.pi)
print(angleInDegrees)
return angleInDegrees
if len(sys.argv) < 2: if len(sys.argv) < 2:
print('Please provide path to image for analysis') print('Please provide path to image for analysis')
exit(1) exit(1)
@ -43,7 +73,8 @@ templateFile = sys.argv[-1]
print(f'Analyzing {scanImage} and creating {templateFile}') print(f'Analyzing {scanImage} and creating {templateFile}')
img = cv2.imread(scanImage) orig = cv2.imread(scanImage)
img = orig.copy()
height, width = img.shape[:2] height, width = img.shape[:2]
orientation = height > width orientation = height > width
@ -65,13 +96,9 @@ else :
bottom = height * 0.8 bottom = height * 0.8
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blur = cv2.medianBlur(gray, 31) blur = cv2.medianBlur(gray, 31)
ret, thresh = cv2.threshold(blur, 200, 255, cv2.THRESH_BINARY) ret, thresh = cv2.threshold(blur, 200, 255, cv2.THRESH_BINARY)
canny = cv2.Canny(thresh, 75, 200) canny = cv2.Canny(thresh, 75, 200)
contours, hierarchy = cv2.findContours(canny, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) contours, hierarchy = cv2.findContours(canny, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
contourList = [] contourList = []
@ -79,9 +106,7 @@ areaList = []
for contour in contours: for contour in contours:
approx = cv2.approxPolyDP(contour, 0.03 * cv2.arcLength(contour, True), True) approx = cv2.approxPolyDP(contour, 0.03 * cv2.arcLength(contour, True), True)
if cv2.isContourConvex(approx) : if cv2.isContourConvex(approx) :
M = cv2.moments(contour) cX, cY = get_center(contour)
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])
if (orientation and ( cX < left or cX > right) ) or ( not orientation and ( cY < top or cY > bottom)) : if (orientation and ( cX < left or cX > right) ) or ( not orientation and ( cY < top or cY > bottom)) :
area = cv2.contourArea(contour) area = cv2.contourArea(contour)
areaList.append(area) areaList.append(area)
@ -90,6 +115,7 @@ for contour in contours:
maxArea=0 maxArea=0
maxIndex=0 maxIndex=0
#reduce to lambda
for i in range(len(areaList)) : for i in range(len(areaList)) :
area = areaList[i] area = areaList[i]
if area > maxArea: if area > maxArea:
@ -98,9 +124,10 @@ for i in range(len(areaList)) :
count = 0 count = 0
holePunches = [] holePunches = []
centers = []
centersStr = [] centersStr = []
areaRange = 0 areaRange = 0
topLeft = None
minDist = 1000000
# pretty good # pretty good
# add position constraint # add position constraint
@ -110,21 +137,76 @@ while count < 6 :
for i in range(len(areaList)) : for i in range(len(areaList)) :
area = areaList[i] area = areaList[i]
if area == maxArea or area * ((100 + areaRange) / 100) > maxArea : if area == maxArea or area * ((100 + areaRange) / 100) > maxArea :
M = cv2.moments(contourList[i]) cX, cY = get_center(contourList[i])
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])
strC = f'{cX},{cY}' strC = f'{cX},{cY}'
if strC in centersStr : if strC in centersStr :
continue continue
centersStr.append(strC) centersStr.append(strC)
centers.append((cX, cY))
print(f'{cX},{cY}') print(f'{cX},{cY}')
cv2.circle(img, (cX, cY), 40, (255, 0, 0), -1) #cv2.circle(img, (cX, cY), 40, (255, 0, 0), -1)
holePunches.append(contourList[i]) hp = {
'x' : cX,
'y' : cY,
'contour' : contourList[i],
'dist' : math.dist((cX, cY), (0, 0)),
'order': -1
}
if hp['dist'] < minDist :
minDist = hp['dist']
topLeft = hp
holePunches.append(hp)
count+=1 count+=1
for hp in holePunches :
hp['dist'] = math.dist( (topLeft['x'], topLeft['y']), (hp['x'], hp['y']) )
holePunches = sorted(holePunches, key = lambda hp: hp['dist'])
i = 0
for hp in holePunches :
hp['order'] = i
cv2.putText(img, str(i + 1), (hp['x'], hp['y']), cv2.FONT_HERSHEY_SIMPLEX, 20, (0, 0, 255), 5, cv2.LINE_AA, False)
i+=1
verts = []
horiz = []
#across top
horiz.append(horiz_angle(draw_line(img, holePunches, 1, 3)))
#across bottom
horiz.append(horiz_angle(draw_line(img, holePunches, 4, 6)))
#middle
horiz.append(horiz_angle(draw_line(img, holePunches, 2, 5)))
#top left
verts.append(verts_angle(draw_line(img, holePunches, 1, 2)))
#long left
verts.append(verts_angle(draw_line(img, holePunches, 1, 4)))
#top right
verts.append(verts_angle(draw_line(img, holePunches, 3, 5)))
#long right
verts.append(verts_angle(draw_line(img, holePunches, 3, 6)))
#bottom left
verts.append(verts_angle(draw_line(img, holePunches, 2, 4)))
#bottom right
verts.append(verts_angle(draw_line(img, holePunches, 5, 6)))
#for v in verts :
#print(v)
#for h in horiz :
# print(h)
# horiz_angle(h)
print(f'Found hole punches within {areaRange}% of largest') print(f'Found hole punches within {areaRange}% of largest')
#print(holePunches)
#cv2.drawContours(img, list(map(lambda hp : hp['contour'], holePunches)), -1, (0, 255, 0), 20)
#cv2.circle(img, (topLeft['x'], topLeft['y']), 50, (0, 0, 255), -1)
cv2.drawContours(img, holePunches, -1, (0, 255, 0), 20)
display(img) display(img)