分水岭算法实现图像分割

2022-03-29 13:44:35 浏览数 (1)

原文:

Watershed OpenCV - PyImageSearch

https://pyimagesearch.com/2015/11/02/watershed-opencv/

内容就先不说了,代码如下:

代码语言:javascript复制
class Watershed:
   def __init__(self):
      pass

   def process(self, image_path):
      # load the image and perform pyramid mean shift filtering
      # to aid the thresholding step
      image = cv2.imread(image_path)
      shifted = cv2.pyrMeanShiftFiltering(image, 21, 51)
      cv2.imshow("Input", image)
      # convert the mean shift image to grayscale, then apply
      # Otsu's thresholding
      gray = cv2.cvtColor(shifted, cv2.COLOR_BGR2GRAY)
      thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
      cv2.imshow("Thresh", thresh)
      # find contours in the thresholded image
      cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
      cnts = imutils.grab_contours(cnts)
      print("[INFO] {} unique contours found".format(len(cnts)))
      # loop over the contours
      for (i, c) in enumerate(cnts):
          # draw the contour
          ((x, y), _) = cv2.minEnclosingCircle(c)
          cv2.putText(image, "#{}".format(i   1), (int(x) - 10, int(y)), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2)
          cv2.drawContours(image, [c], -1, (0, 255, 0), 2)
      # show the output image
      cv2.imshow("Image", image)

      # compute the exact Euclidean distance from every binary
      # pixel to the nearest zero pixel, then find peaks in this
      # distance map
      D = ndimage.distance_transform_edt(thresh)
      localMax = peak_local_max(D, indices=False, min_distance=10, labels=thresh)
      # perform a connected component analysis on the local peaks,
      # using 8-connectivity, then appy the Watershed algorithm
      markers = ndimage.label(localMax, structure=np.ones((3, 3)))[0]
      labels = watershed(-D, markers, mask=thresh)
      cv2.imshow("labels", labels.astype(np.float32))
      print("[INFO] {} unique segments found".format(len(np.unique(labels)) - 1))

      # loop over the unique labels returned by the Watershed
      # algorithm
      for label in np.unique(labels):
         # if the label is zero, we are examining the 'background'
         # so simply ignore it
         if label == 0:
            continue
         # otherwise, allocate memory for the label region and draw
         # it on the mask
         mask = np.zeros(gray.shape, dtype="uint8")
         mask[labels == label] = 255
         # detect contours in the mask and grab the largest one
         cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
         cnts = imutils.grab_contours(cnts)
         c = max(cnts, key=cv2.contourArea)
         # draw a circle enclosing the object
         ((x, y), r) = cv2.minEnclosingCircle(c)
         cv2.circle(image, (int(x), int(y)), int(r), (0, 255, 0), 2)
         cv2.putText(image, "#{}".format(label), (int(x) - 10, int(y)), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2)
      # show the output image
      cv2.imshow("Output", image)
      cv2.waitKey(0)


w = Watershed2()
w.process('./pictures/new.jpg')

0 人点赞