Draw lines between squared points. Get rotation angles (still need to fix verts_angle())
This commit is contained in:
parent
e1c6777bf8
commit
602b6dc26c
|
@ -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)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue