Guest User

Untitled

a guest
Nov 25th, 2021
53
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.38 KB | None | 0 0
  1. # inspiration: https://www.pyimagesearch.com/2016/03/28/measuring-size-of-objects-in-an-image-with-opencv/
  2. from scipy.spatial import distance as dist
  3. from imutils import perspective
  4. from imutils import contours
  5. import numpy as np
  6. import cv2
  7. import imutils
  8.  
  9.  
  10. # program configuration variables
  11.  
  12. # input file
  13. image = cv2.imread('spore-40x.png')
  14.  
  15. # pixels per um
  16. pixelsPerMetric = 9.7
  17.  
  18. # minimum allowed spores which are measured
  19. minSporeSize = 3
  20.  
  21. # maximum allowed spore size
  22. maxSporeSize = 14
  23.  
  24.  
  25. def midpoint(ptA, ptB):
  26.     return ((ptA[0] + ptB [0]) * 0.5, (ptA[1] + ptB[1]) * 0.5)
  27.  
  28. # grayscale and blur it
  29. gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
  30. #blured = cv2.GaussianBlur(gray, (3, 3), 0)
  31. blured = cv2.GaussianBlur(gray, (7, 7), 0)
  32.  
  33. # perform edge detection, dilation and erosion to close gaps bewteen object edges
  34. edged = cv2.Canny(blured, 20, 100)
  35.  
  36. edged = cv2.dilate(edged, None, iterations=1)
  37. edged = cv2.erode(edged, None, iterations=1)
  38.  
  39. cv2.imshow("Image", edged)
  40. cv2.waitKey(0)
  41.  
  42. # find contours
  43. cnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
  44. cnts = imutils.grab_contours(cnts)
  45.  
  46. # sort contours from left to right
  47. # pixels per petric calibration variable
  48. (cnts, _) =  contours.sort_contours(cnts)
  49.  
  50. orig = image.copy()
  51. # measuring all contours
  52. for idx, c in enumerate(cnts):
  53.     # ignore contours, whoich are not sufficient large
  54.    
  55.     # buggy
  56.     #print(cv2.contourArea(c))
  57.     #if cv2.contourArea(c) < 100 or cv2.contourArea(c) > 100*100:        
  58.     #    continue
  59.        
  60.     #orig = image.copy()
  61.     box = cv2.minAreaRect(c)
  62.     box = cv2.cv.BoxPoints(box) if imutils.is_cv2() else cv2.boxPoints(box)
  63.     box = np.array(box, dtype='int')
  64.    
  65.    
  66.     box = perspective.order_points(box)
  67.     cv2.drawContours(orig, [box.astype("int")], -1, (0, 255, 0), 1)
  68.    
  69.     # loop over points and draw them
  70.     for (x, y) in box:
  71.         cv2.circle(orig, (int(x), int(y)), 2, (0, 0, 255), -1)
  72.            
  73.     # unpack the ordered bounding box, then compute the midpoint
  74.     # between the top-left and top-right coordinates, followed by
  75.     # the midpoint between bottom-left and bottom-right coordinates
  76.     (tl, tr, br, bl) = box
  77.     (tltrX, tltrY) = midpoint(tl, tr)
  78.     (blbrX, blbrY) = midpoint(bl, br)
  79.    
  80.     # compute the midpoint between the top-left and top-right points,
  81.     # followed by the midpoint between the top-righ and bottom-right
  82.     (tlblX, tlblY) = midpoint(tl, bl)
  83.     (trbrX, trbrY) = midpoint(tr, br)
  84.  
  85.     # compute the Euclidean distance between the midpoints
  86.     dA = dist.euclidean((tltrX, tltrY), (blbrX, blbrY))
  87.     dB = dist.euclidean((tlblX, tlblY), (trbrX, trbrY))
  88.     # if the pixels per metric has not been initialized, then
  89.     # compute it as the ratio of pixels to supplied metric
  90.     # (in this case, inches)
  91.     if pixelsPerMetric is None:
  92.         pixelsPerMetric = 1.0#dB / 1#0.9700#args["width"]
  93.        
  94.     # compute the size of the object
  95.     dimA = dA / pixelsPerMetric
  96.     dimB = dB / pixelsPerMetric
  97.  
  98.  
  99.     if(dimA > maxSporeSize or dimB > maxSporeSize or dimA < minSporeSize or dimB < minSporeSize):
  100.         continue # invalid spore sizes
  101.    
  102.     # draw midpoints
  103.     cv2.circle(orig, (int(tltrX), int(tltrY)), 2, (255, 0, 0), -1)
  104.     cv2.circle(orig, (int(blbrX), int(blbrY)), 2, (255, 0, 0), -1)
  105.     cv2.circle(orig, (int(tlblX), int(tlblY)), 2, (255, 0, 0), -1)
  106.     cv2.circle(orig, (int(trbrX), int(trbrY)), 2, (255, 0, 0), -1)
  107.    
  108.     # draw lines between the midpoints
  109.     cv2.line(orig, (int(tltrX), int(tltrY)), (int(blbrX), int(blbrY)), (255, 0, 0), 1)
  110.     cv2.line(orig, (int(tlblX), int(tlblY)), (int(trbrX), int(trbrY)), (255, 0, 0), 1)
  111.    
  112.  
  113.     # draw the object sizes on the image
  114.     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)
  115.     #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)
  116.     # cv2.putText(orig, "{:.3f}um".format(dimB), (int(trbrX + 10), int(trbrY)), cv2.FONT_HERSHEY_SIMPLEX, 0.4, (255, 255, 255), 1)
  117.        
  118.     # show the output image
  119.  
  120.     print("{:03d}: {:03.03f} um x {:03.03f} um".format(idx, dimA, dimB))
  121.     #print(idx, dimA, "um x", dimB, "um")
  122.  
  123. cv2.imshow("Image", orig)
  124. cv2.imwrite("output.png", orig)
  125. cv2.waitKey(0)
Advertisement
Add Comment
Please, Sign In to add comment