Image Segmentation with Watershed Algorithm
จาก Morange Wiki
Image Segmentation with Watershed Algorithm
วัตถุประสงค์
- บทนี้จะเรียนรู้เกี่ยวกับการทำ Marker-based ในรูปภาพ โดยใช้ watershed algorithm
- เรียนรู้การใช้งานฟังก์ชั่น cv2.watershed()
ทฤษฎี
- ในการทำรูปภาพในโหมดสีเทานั้น จะสามารถดูมุมมองได้จาก topographic surface ( มุมมองลักษณะภูมิประเทศ ) โดยที่ความเข้มสูงหมายถึงยอดของความสูงที่สุดและเนินที่นูนออกมา ในขณะที่ความเข้มต่ำหมายถึงจุดต่ำของหุบเขา ด้วยการเริ่มต้นกรอกทุกหุบเขาแยก (local minima) ด้วยสีที่แตกต่างกันของน้ำ ( labels ) ในขณะที่น้ำนั้นมีการเพิ่มขึ้นจนถึงยอดโดยการไล่ระดับสี (gradients) ในบริเวณใกล้เคียงน้ำจากหุบเขา ( hill ) ที่แตกต่างกันนั้นจะเห็นได้ชัดว่า สีจะมีความแตกต่างกันโดยจะเริ่มต้นที่จะผสานกัน เพื่อหลีกเลี่ยงการเพิ่มขึ้นของ barriers ในสถานที่ที่ผสานกันของน้ำ โดยจะสามารถทำงานต่อด้วยกสนเพิ่มขึ้นของน้ำและเพิ่ม barriers และใน bariers โดยจะช่วยให้เห็นการแบ่งส่วน โดยสิ่งนี้เรียกว่า "ปรัชญา" Philosophy
- โดยสามารถเยี่ยมชมเว็บ CMM ได้เพื่อดูการข้อมูลเพิ่มเติม [| CMM Link]
- ใน OpenCV นั้นจะช่วยให้สามารถทำ marker-based watershed algorithm ได้ด้วยการระบุซึ่งทุกจุดของ hill นั้นจะมีการรวม ( merged ) และทำให้ไม่สามารถตอบโต้ในรูปภาพได้โดยรับ labels ที่แตกต่างกันใน object
Code
- ในต่อไปนี้จะทำตัวอย่างเกี่ยวกับวิธีการที่จะใช้ในการหา Distance Transform พร้อมกับการใช้ watershed เพื่อแบ่งแยกเป็นกลุ่มๆ โดยวัตถุจะสัมผัสกัน
- ในการพิจารณาเหรียญด้านล่างนี้ จะติดกัน
import numpy as np import cv2 from matplotlib import pyplot as plt img = cv2.imread('Coin512.jpg') gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU) cv2.imshow('image',thresh) cv2.waitKey(0) cv2.destroyAllWindows()
มีข้อผิดพลาดในการสร้างรูปย่อ: ไฟล์สูญหาย
มีข้อผิดพลาดในการสร้างรูปย่อ: ไฟล์สูญหาย
- โดยต่อไปนี้จะเป็นการลบนอดย์ที่อยู่ในวงกลมสีขาว โดยใช้ morphological opening โดยการลบภาพวัตถุพวกนั้น อาจจะใช้ morphological closing เข้ามาร่วมด้วย ยกตัวอย่าง
import numpy as np import cv2 from matplotlib import pyplot as plt img = cv2.imread('Coin512.jpg') gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU) # noise removal kernel = np.ones((3,3),np.uint8) opening = cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel, iterations = 2) # sure background area sure_bg = cv2.dilate(opening,kernel,iterations=3) # Finding sure foreground area dist_transform = cv2.distanceTransform(opening,cv2.DIST_L2,5) ret, sure_fg = cv2.threshold(dist_transform,0.7*dist_transform.max(),255,0) # Finding unknown region sure_fg = np.uint8(sure_fg) unknown = cv2.subtract(sure_bg,sure_fg) cv2.imshow('image',unknown) cv2.waitKey(0) cv2.destroyAllWindows()
- และในผลลัพธ์นั้นจะได้ภาพที่ผ่านฟังก์ชั่น thresholded image เรียบร้อยแล้ว โดยบางพื้นที่ของเหรียญนั้น จะเห้นได้ว่าติดต่อกัน โดยต่อไปจะนำมันออกจากกัน โดยบางกรณีนั้นจะสนใจการแบ่งส่วนเฉพาะด้านหน้า (foreground) เท่านั้น โดยจะไม่ได้สนใจส่วนที่ติดกัน ดังนั้น การเปลี่ยนไปใช้ Erosion ) ดังตัวอย่าง
มีข้อผิดพลาดในการสร้างรูปย่อ: ไฟล์สูญหาย
มีข้อผิดพลาดในการสร้างรูปย่อ: ไฟล์สูญหาย