Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # inspiration: https://www.pyimagesearch.com/2016/03/28/measuring-size-of-objects-in-an-image-with-opencv/
- from scipy.spatial import distance as dist
- from imutils import perspective
- from imutils import contours
- import numpy as np
- import cv2
- import imutils
- # program configuration variables
- # input file
- image = cv2.imread('spore-40x.png')
- # pixels per um
- pixelsPerMetric = 9.7
- # minimum allowed spores which are measured
- minSporeSize = 3
- # maximum allowed spore size
- maxSporeSize = 14
- def midpoint(ptA, ptB):
- return ((ptA[0] + ptB [0]) * 0.5, (ptA[1] + ptB[1]) * 0.5)
- # grayscale and blur it
- gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
- #blured = cv2.GaussianBlur(gray, (3, 3), 0)
- blured = cv2.GaussianBlur(gray, (7, 7), 0)
- # perform edge detection, dilation and erosion to close gaps bewteen object edges
- edged = cv2.Canny(blured, 20, 100)
- edged = cv2.dilate(edged, None, iterations=1)
- edged = cv2.erode(edged, None, iterations=1)
- cv2.imshow("Image", edged)
- cv2.waitKey(0)
- # find contours
- cnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
- cnts = imutils.grab_contours(cnts)
- # sort contours from left to right
- # pixels per petric calibration variable
- (cnts, _) = contours.sort_contours(cnts)
- orig = image.copy()
- # measuring all contours
- for idx, c in enumerate(cnts):
- # ignore contours, whoich are not sufficient large
- # buggy
- #print(cv2.contourArea(c))
- #if cv2.contourArea(c) < 100 or cv2.contourArea(c) > 100*100:
- # continue
- #orig = image.copy()
- box = cv2.minAreaRect(c)
- box = cv2.cv.BoxPoints(box) if imutils.is_cv2() else cv2.boxPoints(box)
- box = np.array(box, dtype='int')
- box = perspective.order_points(box)
- cv2.drawContours(orig, [box.astype("int")], -1, (0, 255, 0), 1)
- # loop over points and draw them
- for (x, y) in box:
- cv2.circle(orig, (int(x), int(y)), 2, (0, 0, 255), -1)
- # unpack the ordered bounding box, then compute the midpoint
- # between the top-left and top-right coordinates, followed by
- # the midpoint between bottom-left and bottom-right coordinates
- (tl, tr, br, bl) = box
- (tltrX, tltrY) = midpoint(tl, tr)
- (blbrX, blbrY) = midpoint(bl, br)
- # compute the midpoint between the top-left and top-right points,
- # followed by the midpoint between the top-righ and bottom-right
- (tlblX, tlblY) = midpoint(tl, bl)
- (trbrX, trbrY) = midpoint(tr, br)
- # compute the Euclidean distance between the midpoints
- dA = dist.euclidean((tltrX, tltrY), (blbrX, blbrY))
- dB = dist.euclidean((tlblX, tlblY), (trbrX, trbrY))
- # if the pixels per metric has not been initialized, then
- # compute it as the ratio of pixels to supplied metric
- # (in this case, inches)
- if pixelsPerMetric is None:
- pixelsPerMetric = 1.0#dB / 1#0.9700#args["width"]
- # compute the size of the object
- dimA = dA / pixelsPerMetric
- dimB = dB / pixelsPerMetric
- if(dimA > maxSporeSize or dimB > maxSporeSize or dimA < minSporeSize or dimB < minSporeSize):
- continue # invalid spore sizes
- # draw midpoints
- cv2.circle(orig, (int(tltrX), int(tltrY)), 2, (255, 0, 0), -1)
- cv2.circle(orig, (int(blbrX), int(blbrY)), 2, (255, 0, 0), -1)
- cv2.circle(orig, (int(tlblX), int(tlblY)), 2, (255, 0, 0), -1)
- cv2.circle(orig, (int(trbrX), int(trbrY)), 2, (255, 0, 0), -1)
- # draw lines between the midpoints
- cv2.line(orig, (int(tltrX), int(tltrY)), (int(blbrX), int(blbrY)), (255, 0, 0), 1)
- cv2.line(orig, (int(tlblX), int(tlblY)), (int(trbrX), int(trbrY)), (255, 0, 0), 1)
- # draw the object sizes on the image
- cv2.putText(orig, " {:03d}: {:2.3f} x {:2.3f} um".format(idx, dimA, dimB), (int(tltrX - 15), int(tltrY - 10)), cv2.FONT_HERSHEY_SIMPLEX, 0.4, (255, 255, 255), 1)
- #cv2.putText(orig, "{:f}px^2".format(cv2.contourArea(c)), (int(trbrX + 10), int(trbrY)), cv2.FONT_HERSHEY_SIMPLEX, 0.4, (255, 255, 255), 1)
- # cv2.putText(orig, "{:.3f}um".format(dimB), (int(trbrX + 10), int(trbrY)), cv2.FONT_HERSHEY_SIMPLEX, 0.4, (255, 255, 255), 1)
- # show the output image
- print("{:03d}: {:03.03f} um x {:03.03f} um".format(idx, dimA, dimB))
- #print(idx, dimA, "um x", dimB, "um")
- cv2.imshow("Image", orig)
- cv2.imwrite("output.png", orig)
- cv2.waitKey(0)
Advertisement
Add Comment
Please, Sign In to add comment