Contours in OpenCV
จาก Morange Wiki
เนื้อหา
Contours : Getting Started
วัตถุประะสงค์
- เข้าใจว่าอะไรคือ Contour (เส้นชั้น ความสูง)
- รู้วิธีการเขียนเส้นชั้นความสูงและหาเส้นชั้นความสูง
- เรียนรู้การใช้งานฟังก์ชั่น : cv2.findContours(), cv2.drawContours()
อะไรคือ เส้นชั้นความสูง
- รูปทรงที่สามารถอธิบายได้ว่า เส้นไหนเป็นเส้นโค้งโดยร่วมแบบต่อเนื่อง โดยมีสีที่หรือความเข้มของรูปทรงที่เป็นเส้นชั้น ในการใช้นั้น จะมีีเครื่องมือที่มีประโยชน์ที่เหมาะสำหรับการวิเคราะห์รูปทรงและการตรวจสอบวัตถุและการเรียนรู้
- เพื่อความถูกต้องดีกว่าใช้ภาพไบนารี ดังนั้นก่อนที่จะหาเส้นชั้นความสูง ควรใช้เกณฑ์ในการตรวจหาด้วย Canny Edge Detection
- ฟังก์ชั่น findContours จะปรับเปลี่ยนภาพที่นำเข้ามา ดังนั้นหากคุณต้องการทั้งภาพที่นำเข้าและภาพที่หาเส้นชั้นความสูงแล้ว จะต้องนำไปเก็บไว้เป็นตัวแปรอื่นๆ
- ใน OpenCV การหาเส้นชั้นความสูงเป็นเหมือนการหาวัตถุสีขาวจากพื้นหลังสีดำ ดังนั้นจำวัตถุที่จะพบควรเป็นสีขาวและพื้นหลังควรเป็นสีดำ
CODE
import numpy as np import cv2 im = cv2.imread('test.jpg') imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY) ret,thresh = cv2.threshold(imgray,127,255,0) im2, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
วิธีการวาดเส้นชั้นความสูง
การวาดรูปเส้นชั้นความสูง ฟังก์ชั่น cv2.drawContours() ถูกนำมาใช้ นอกจากนี้ยังสามารถใช้ในการวาดรูปทรงใด ๆ ที่ให้คุณมีจุดเขตแดน อาร์กิวเมนต์แรกคือภาพที่ต้นฉบับที่นำเข้ามาส่วนอาร์กิวเมนต์ที่สองภาพที่แสดงเส้นชั้นความสูงที่ควรจะผ่านเป็นโปรแกรม Python ในอาร์กิวเมนต์ที่สามคือดัชนีของเส้นชั้นความสูง (มีประโยชน์เมื่อวาดเส้นชั้นความสูงของแต่ละส่วน. ในการวาดเส้นชั้นความสูงทั้งหมดผ่านมีค่า -1) และข้อโต้แย้งที่เหลือเป็นสีและความหนา เป็นต้น
- การวาดรูปเส้นชั้นความสูง
cv2.drawContours(img, contours, -1, (0,255,0), 3)
- สำหรับการวาด Individual Contour
cv2.drawContours(img, contours, 3, (0,255,0), 3)
- แต่ส่วนมากของเวลาที่ด้านล่างวิธีการจะเป็นประโยชน์:
cnt = contours[4] cv2.drawContours(img, [cnt], 0, (0,255,0), 3)
วิธีการประมาณเส้นชั้นความสูง
- นี่คืออาร์กิวเมนต์ที่สามของฟังก์ชั่น cv2.findContours มันจะมีอะไรแสดงได้จริง?
- ข้างต้นที่เราบอกว่าขอบเขตเส้นชั้นความสูงของรูปทรงที่มีความเข้มข้นเหมือนกัน โดยจะเก็บ (x, y) พิกัดเขตแดนของรูปร่าง แต่ไม่ได้เก็บพิกัดทั้งหมด ที่ระบุไว้นั้นจะได้โดยวิธีการประมาณ เส้นชั้นความสูงนี้
- ด้านล่างภาพของรูปสี่เหลี่ยมผืนผ้า แสดงให้เห็นถึงเทคนิคนี้ เพียงแค่ วาดวงกลมบนพิกัดทั้งหมดในอาร์เรย์รูปร่าง (วาดเส้นสีฟ้า) ภาพแรกแสดงให้เห็นถึงจุดที่มี
- cv2.CHAIN_APPROX_NONE (734 จุด)
- และภาพที่สองแสดงให้เห็นว่าเป็นในแนวเดียวกัน
- cv2.CHAIN_APPROX_SIMPLE (เฉพาะ 4 จุด) มาดูกันว่าวิธีไหนจะประหยัดการใช้ memory กว่ากัน
Contour Features
วัตถุประสงค์
- เพื่อหาสิ่งที่คุณสมบัติแตกต่างกันของรูปทรงเส้นความสูงเช่นพื้นที่, ปริมณฑล, เซนทรอยด์, กล่อง ฯลฯ
- จะได้เห็นทุกๆฟังก์ชั่นแบบเต็มรูปแบบ
Moments
- Image Moment จะช่วยเรื่องการคำนวณ โดยบาง Features เหมือนจุดศูนย์กลางมวลของวัตถุพื้นที่ของวัตถุ ฯลฯ ตรวจสอบหน้าวิกิพีเดียในช่วงเวลาที่ภาพ
- โดยฟังก์ชั่น cv2.moments() จะให้ทั้งหมดของ dictionary ของค่าที่คำนวณ
Example Code
import cv2 import numpy as np img = cv2.imread('star.jpg',0) ret, thresh = cv2.threshold(img,127,255,0) contours , hierarchy = cv2.findContours(thresh,1,2) cnt = contours[0] M = cv2.moments(cnt) print M
จาก Moment นี้ คุณจะเห็นได้ชัดว่าข้อมูลของพื้นที่ , centroid และอื่นๆนั้น จะมีค่าความสัมพันธ์ ตามสูตร คือ
cx = int(M['m10']/M['m00']) cy = int(M['m01']/M['m00'])
Contour Area
- ในฟังก์ชั่นนี้จะได้ พื้นที่ของเส้นชั้นความสูงโดย ใช้คำสั่งที่ชื่อว่า cv2.contourArea() หรือ ได้จาก M['m00']
area = cv2.contourArea(cnt)
Contour Perimeter
- นอกจากนี้ยังเรียกใช้ฟังก์ชั้นเพื่อหาค่า arc length โดยจะใช้คำสั่ง cv2.arcLength() และใช้ 2 parameter หรือ 2 argument ในการเรียกใช้
perimeter = cv2.arcLength(cnt,True)
Contour Approximation
Example Code
epsilon = 0.1*cv2.arcLength(cnt,True) approx = cv2.approxPolyDP(cnt,epsilon,True)
Result
Convex Hull
Image Example
Code
hull = cv2.convexHull(points[, hull[, clockwise[, returnPoints]] และ hull = cv2.convexHull(cnt)
Checking Convexity
- เป็นฟังก์ชั่นการตรวจสอบว่าเป็นเส้นโค้งนูนหรือไม่ ใช้คำสั่งชื่อว่า cv2.isContourConvex()
Code Example
k = cv2.isContourConvex(cnt)
Bounding Rectangle
Straight Bounding Rectangle
Code Example
x,y,w,h = cv2.boundingRect(cnt) cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
Rotated Rectangle
Code Example
rect = cv2.minAreaRect(cnt) box = cv2.boxPoints(rect) box = np.int0(box) cv2.drawContours(img,[box],0,(0,0,255),2)
Image Result
Minimum Enclosing Circle
- ในการทำวงกลมล้อมรอบ Object นั้นทำได้ด้วยคำสั่งชื่อว่า cv2.minEnclosingCicle()
Code Example
(x,y),radius = cv2.minEnclosingCircle(cnt) center = (int(x),int(y)) radius = int(radius) cv2.circle(img,center,radius,(0,255,0),2)
Image Result
Fitting an Ellipse
- ในการวาดลงรีทับนั้นใช้คำสั่งดังด้านล่างนี้
Code Example
ellipse = cv2.fitEllipse(cnt) cv2.ellipse(img,ellipse,(0,255,0),2)
Image Result
Fitting a Line
- เรื่องนี้จะเป็นการวาดเส้นทับรูปภาพ
Code Example
rows,cols = img.shape[:2] [vx,vy,x,y] = cv2.fitLine(cnt, cv2.DIST_L2,0,0.01,0.01) lefty = int((-x*vy/vx) + y) righty = int(((cols-x)*vy/vx)+y) cv2.line(img,(cols-1,righty),(0,lefty),(0,255,0),2)