Almost blew past a good stopping point.
This script can now, on at least one example. locate the largest contours on the page and then put those contours in an array. It should also look for the largest, most outlying, to prevent errors in the case of large contours in the image. They should never go past the holes. Next step: use this for straightening, which will be good for the image extraction script. Use them as registration points and then just rotate, shift and "shoot" by cropping at a point relative to the holes. For calibration/templating, look into pattern matching fiducials after getting hole punch coordinates.
This commit is contained in:
parent
e5d9d654ac
commit
f103133b9f
|
@ -2,6 +2,34 @@ import sys
|
|||
import cv2
|
||||
import numpy as np
|
||||
|
||||
def image_resize(image, width = None, height = None, inter = cv2.INTER_AREA):
|
||||
dim = None
|
||||
(h, w) = image.shape[:2]
|
||||
|
||||
if width is None and height is None:
|
||||
return image
|
||||
|
||||
if width is None:
|
||||
r = height / float(h)
|
||||
dim = (int(w * r), height)
|
||||
else:
|
||||
r = width / float(w)
|
||||
dim = (width, int(h * r))
|
||||
resized = cv2.resize(image, dim, interpolation = inter)
|
||||
|
||||
return resized
|
||||
|
||||
def display (image) :
|
||||
resized = image_resize(image, 800, 800)
|
||||
cv2.imshow('img', resized)
|
||||
|
||||
while True:
|
||||
key = cv2.waitKey(0)
|
||||
if key == 27:
|
||||
cv2.destroyAllWindows()
|
||||
break
|
||||
exit(0)
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
print('Please provide path to image for analysis')
|
||||
exit(1)
|
||||
|
@ -15,4 +43,66 @@ templateFile = sys.argv[-1]
|
|||
|
||||
print(f'Analyzing {scanImage} and creating {templateFile}')
|
||||
|
||||
#https://stackoverflow.com/questions/51456660/opencv-detecting-drilled-holes
|
||||
img = cv2.imread(scanImage)
|
||||
|
||||
height, width = img.shape[:2]
|
||||
|
||||
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
|
||||
|
||||
blur = cv2.medianBlur(gray, 31)
|
||||
|
||||
ret, thresh = cv2.threshold(blur, 200, 255, cv2.THRESH_BINARY)
|
||||
|
||||
canny = cv2.Canny(thresh, 75, 200)
|
||||
|
||||
contours, hierarchy = cv2.findContours(canny, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
|
||||
|
||||
contour_list = []
|
||||
area_list = []
|
||||
for contour in contours:
|
||||
approx = cv2.approxPolyDP(contour, 0.01 * cv2.arcLength(contour, True), True)
|
||||
area = cv2.contourArea(contour)
|
||||
area_list.append(area)
|
||||
contour_list.append(contour)
|
||||
|
||||
maxArea=0
|
||||
maxIndex=0
|
||||
|
||||
for i in range(len(area_list)) :
|
||||
area = area_list[i]
|
||||
if area > maxArea:
|
||||
maxArea = area
|
||||
maxIndex = i
|
||||
|
||||
count = 0
|
||||
hole_punches = []
|
||||
centers = []
|
||||
centersStr = []
|
||||
area_range = 0
|
||||
|
||||
# pretty good
|
||||
# add position constraint
|
||||
|
||||
while count < 6 :
|
||||
area_range+=1
|
||||
for i in range(len(area_list)) :
|
||||
area = area_list[i]
|
||||
if area == maxArea or area * ((100 + area_range) / 100) > maxArea :
|
||||
M = cv2.moments(contour_list[i])
|
||||
cX = int(M["m10"] / M["m00"])
|
||||
cY = int(M["m01"] / M["m00"])
|
||||
strC = f'{cX},{cY}'
|
||||
if strC in centersStr :
|
||||
continue
|
||||
centers.appendStr(strC)
|
||||
corners.append((cX, cY))
|
||||
print(f'{cX},{cY}')
|
||||
cv2.circle(img, (cX, cY), 40, (255, 0, 0), -1)
|
||||
hole_punches.append(contour_list[i])
|
||||
count+=1
|
||||
print(f'Found hole punches within {area_range}% of largest')
|
||||
|
||||
|
||||
cv2.drawContours(img, hole_punches, -1, (0, 255, 0), 20)
|
||||
display(img)
|
||||
|
||||
|
|
Loading…
Reference in New Issue