From f103133b9fdcb8d214d41ceb59f19c696713156e Mon Sep 17 00:00:00 2001 From: mattmcw Date: Tue, 8 Nov 2022 22:47:36 -0500 Subject: [PATCH] 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. --- fourcell/analyze.py | 92 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-) diff --git a/fourcell/analyze.py b/fourcell/analyze.py index 454022b..66cebd1 100644 --- a/fourcell/analyze.py +++ b/fourcell/analyze.py @@ -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 \ No newline at end of file +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) +