ผลต่างระหว่างรุ่นของ "Contours in OpenCV"
จาก Morange Wiki
Patcharapun (คุย | มีส่วนร่วม) (Contours : Getting Started Done!) |
Patcharapun (คุย | มีส่วนร่วม) (fix center) |
||
(ไม่แสดง 4 รุ่นระหว่างกลางโดยผู้ใช้คนเดียวกัน) | |||
แถว 56: | แถว 56: | ||
[[ไฟล์:None.jpg]] | [[ไฟล์:None.jpg]] | ||
</center> | </center> | ||
+ | |||
+ | <br> | ||
+ | = Contour Features = | ||
+ | == วัตถุประสงค์ == | ||
+ | * เพื่อหาสิ่งที่คุณสมบัติแตกต่างกันของรูปทรงเส้นความสูงเช่นพื้นที่, ปริมณฑล, เซนทรอยด์, กล่อง ฯลฯ | ||
+ | * จะได้เห็นทุกๆฟังก์ชั่นแบบเต็มรูปแบบ | ||
+ | |||
+ | == Moments == | ||
+ | * Image Moment จะช่วยเรื่องการคำนวณ โดยบาง Features เหมือนจุดศูนย์กลางมวลของวัตถุพื้นที่ของวัตถุ ฯลฯ ตรวจสอบหน้าวิกิพีเดียในช่วงเวลาที่ภาพ | ||
+ | * โดยฟังก์ชั่น cv2.moments() จะให้ทั้งหมดของ dictionary ของค่าที่คำนวณ | ||
+ | === Example Code === | ||
+ | <pre> | ||
+ | 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 | ||
+ | </pre> | ||
+ | จาก Moment นี้ คุณจะเห็นได้ชัดว่าข้อมูลของพื้นที่ , centroid และอื่นๆนั้น จะมีค่าความสัมพันธ์ ตามสูตร คือ [[ไฟล์:Selection 068.png ]] | ||
+ | <pre> | ||
+ | cx = int(M['m10']/M['m00']) | ||
+ | cy = int(M['m01']/M['m00']) | ||
+ | </pre> | ||
+ | == Contour Area == | ||
+ | * ในฟังก์ชั่นนี้จะได้ พื้นที่ของเส้นชั้นความสูงโดย ใช้คำสั่งที่ชื่อว่า cv2.contourArea() หรือ ได้จาก M['m00'] | ||
+ | <pre> | ||
+ | area = cv2.contourArea(cnt) | ||
+ | </pre> | ||
+ | |||
+ | == Contour Perimeter == | ||
+ | * นอกจากนี้ยังเรียกใช้ฟังก์ชั้นเพื่อหาค่า arc length โดยจะใช้คำสั่ง cv2.arcLength() และใช้ 2 parameter หรือ 2 argument ในการเรียกใช้ | ||
+ | <pre> | ||
+ | perimeter = cv2.arcLength(cnt,True) | ||
+ | </pre> | ||
+ | == Contour Approximation == | ||
+ | === Example Code === | ||
+ | <pre> | ||
+ | epsilon = 0.1*cv2.arcLength(cnt,True) | ||
+ | approx = cv2.approxPolyDP(cnt,epsilon,True) | ||
+ | </pre> | ||
+ | === Result === | ||
+ | <center>[[ไฟล์:Approx.jpg]]</center> | ||
+ | |||
+ | == Convex Hull == | ||
+ | === Image Example === | ||
+ | <center>[[ไฟล์:Convexitydefects.jpg]]</center> | ||
+ | === Code === | ||
+ | <pre> | ||
+ | hull = cv2.convexHull(points[, hull[, clockwise[, returnPoints]] | ||
+ | และ | ||
+ | hull = cv2.convexHull(cnt) | ||
+ | </pre> | ||
+ | == Checking Convexity == | ||
+ | * เป็นฟังก์ชั่นการตรวจสอบว่าเป็นเส้นโค้งนูนหรือไม่ ใช้คำสั่งชื่อว่า cv2.isContourConvex() | ||
+ | === Code Example === | ||
+ | <pre> | ||
+ | k = cv2.isContourConvex(cnt) | ||
+ | </pre> | ||
+ | |||
+ | == Bounding Rectangle == | ||
+ | === Straight Bounding Rectangle === | ||
+ | ==== Code Example ==== | ||
+ | <pre> | ||
+ | x,y,w,h = cv2.boundingRect(cnt) | ||
+ | cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2) | ||
+ | </pre> | ||
+ | === Rotated Rectangle === | ||
+ | ==== Code Example ==== | ||
+ | <pre> | ||
+ | rect = cv2.minAreaRect(cnt) | ||
+ | box = cv2.boxPoints(rect) | ||
+ | box = np.int0(box) | ||
+ | cv2.drawContours(img,[box],0,(0,0,255),2) | ||
+ | </pre> | ||
+ | ==== Image Result ==== | ||
+ | <center>[[ไฟล์:Boundingrect.png]]</center> | ||
+ | |||
+ | == Minimum Enclosing Circle == | ||
+ | * ในการทำวงกลมล้อมรอบ Object นั้นทำได้ด้วยคำสั่งชื่อว่า cv2.minEnclosingCicle() | ||
+ | === Code Example === | ||
+ | <pre> | ||
+ | (x,y),radius = cv2.minEnclosingCircle(cnt) | ||
+ | center = (int(x),int(y)) | ||
+ | radius = int(radius) | ||
+ | cv2.circle(img,center,radius,(0,255,0),2) | ||
+ | </pre> | ||
+ | === Image Result === | ||
+ | <center>[[ไฟล์:Circumcircle.png]]</center> | ||
+ | |||
+ | == Fitting an Ellipse == | ||
+ | * ในการวาดลงรีทับนั้นใช้คำสั่งดังด้านล่างนี้ | ||
+ | === Code Example === | ||
+ | <pre> | ||
+ | ellipse = cv2.fitEllipse(cnt) | ||
+ | cv2.ellipse(img,ellipse,(0,255,0),2) | ||
+ | </pre> | ||
+ | === Image Result === | ||
+ | <center>[[ไฟล์:Fitellipse.png]]</center> | ||
+ | |||
+ | == Fitting a Line == | ||
+ | * เรื่องนี้จะเป็นการวาดเส้นทับรูปภาพ | ||
+ | === Code Example === | ||
+ | <pre> | ||
+ | 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) | ||
+ | </pre> | ||
+ | === Image Result === | ||
+ | <center>[[ไฟล์:Fitline.jpg]]</center> | ||
+ | <br> | ||
+ | <br> | ||
+ | = Contour Properties = | ||
+ | * ในบทนี้ จะเรียนรู้เกี่ยวกับคุณสมบัติของ Contour ว่า Object อะไรบ้าง เช่น Solidity, Equivalent Diameter, Mask image, Mean Intensity เพิ่มเติมที่ : [[http://www.mathworks.in/help/images/ref/regionprops.html เพิ่มเติม]] | ||
+ | |||
+ | == Aspect Ratio == | ||
+ | * เรื่องการหาอัตราส่วนของความกว้างความสูง และขอบเขตของวัตถุ ตามสูตร | ||
+ | <center>[[ไฟล์:Selection 069.png | AspectRatio=Width/Height ]]</center> | ||
+ | === Code Example === | ||
+ | <pre> | ||
+ | x,y,w,h = cv2.boundingRect(cnt) | ||
+ | aspect_ratio = float(w)/h | ||
+ | </pre> | ||
+ | == Extent == | ||
+ | * ขอบเขตของอัตราส่วนพื้นที่สี่เหลี่ยมผืนผ้า ตามสูตร | ||
+ | <center>[[ไฟล์:Selection 070.png]]</center> | ||
+ | === Code Example === | ||
+ | <pre> | ||
+ | area = cv2.contourArea(cnt) | ||
+ | x,y,w,h = cv2.boundingRect(cnt) | ||
+ | rect_area = w*h | ||
+ | extent = float(area)/rect_area | ||
+ | </pre> | ||
+ | == Solidity == | ||
+ | * ค่าความแข็งแรงคือ อัตราส่วนของพื้นที่เส้นแสดงรูปร่างการนูนออกของพื้นที่ ตามสูตร | ||
+ | <center>[[ไฟล์:Selection 072.png]]</center> | ||
+ | === Code Example === | ||
+ | <pre> | ||
+ | area= cv2.contourArea(cnt) | ||
+ | hull = cv2.convexHull(cnt) | ||
+ | hull_area = cv2.contourArea(hull) | ||
+ | solidity = float(area)/hull_area | ||
+ | </pre> | ||
+ | == Equivalent Diameter == | ||
+ | * การหาเส้นผ่าศูนย์กลางของวงกลมนั้น ทำได้เหมือนกันกับการหาพื้นที่เส้นแสดงรูปร่าง ตามสูตร | ||
+ | <center>[[ไฟล์:Selection 073.png]]</center> | ||
+ | === Code Example === | ||
+ | <pre> | ||
+ | area = cv2.contourArea(cnt) | ||
+ | equi_diameter = np.sqrt(4*area/np.pi) | ||
+ | </pre> | ||
+ | == Orientation == | ||
+ | * คือการจัดวางแนวที่เป็นมุมของวัตถุ วิธีนี้ช่วยให้ได้ค่าความยาวของแกนหลักและแกนรอง | ||
+ | === Code Example === | ||
+ | <pre> | ||
+ | (x,y),(MA,ma),angle = cv2.fitEllipse(cnt) | ||
+ | </pre> | ||
+ | == Mask and Pixel Points == | ||
+ | * วิธีนี้ ทุกๆจัดต้องประกอบด้วยวัตถุ สามารถทำได้ดังนี้ | ||
+ | === Code Example === | ||
+ | <pre> | ||
+ | mask = np.zeros(imgray.shape,np.uint8) | ||
+ | cv2.drawContours(mask,[cnt],0,255,-1) | ||
+ | pixelpoints = np.transpose(np.nonzero(mask)) | ||
+ | #pixelpoints = cv2.findNonZero(mask) | ||
+ | </pre> | ||
+ | == Maximum Value, Minimum Value and their locations == | ||
+ | * ในบทนี้จะสามารถหาค่าพารามิเตอร์โดยการใช้ mask image | ||
+ | === Code Example === | ||
+ | <pre> | ||
+ | min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(imgray,mask = mask) | ||
+ | </pre> | ||
+ | == Mean Color or Mean Intensity == | ||
+ | * หัวข้อนี้สามารถหาสีที่มีค่าเฉลี่ยของวัตถุ หรืออาจใช้ความเข้มเฉลี่ย ของวัตถุในโหมดสีเทา อาจจะใช้วิธีเดียวกันกับ mask image | ||
+ | === Code Example === | ||
+ | <pre> | ||
+ | mean_val = cv2.mean(im,mask = mask) | ||
+ | </pre> | ||
+ | == Extreme Points == | ||
+ | * จุดที่สูงที่สุดหมายถึง Topmost , Bottommost , rightmost , leftmost หรือ จุดสุดท้ายของแต่ละด้าน ของวัตถุ | ||
+ | === Code Example === | ||
+ | <pre> | ||
+ | leftmost = tuple(cnt[cnt[:,:,0].argmin()][0]) | ||
+ | rightmost = tuple(cnt[cnt[:,:,0].argmax()][0]) | ||
+ | topmost = tuple(cnt[cnt[:,:,1].argmin()][0]) | ||
+ | bottommost = tuple(cnt[cnt[:,:,1].argmax()][0]) | ||
+ | </pre> | ||
+ | === Result Extream Point === | ||
+ | <center> [[ไฟล์:Extremepoints-non.jpg]] </center> | ||
+ | <br> | ||
+ | <br> | ||
+ | = Contours : More Functions = | ||
+ | == วัตถุประสงค์ == | ||
+ | * เพื่อหาข้อบกพร่องนูนและวิธีการที่จะพบ | ||
+ | * การหาระยะทางที่สั้นที่สุดจาก A ไปหา เหลี่ยม | ||
+ | * จับคุ่รูปร่างที่แตกต่าง | ||
+ | |||
+ | == Convexity Defects == | ||
+ | * ในการสิ่งที่เป็นเปลือกนูนในบทที่ 2 ของ Contour นั้น ทุกๆ การเบี่ยงเบนของ Object นั้น จะถือเป็นข้อบกพร่องของการนูน | ||
+ | * โดย OpenCV จะนำมีฟังก์ชั้นเกี่ยวกับเรื่องนี้มาด้วย นั้นคือฟังก์ชั่น cv2.convexityDefects() | ||
+ | === Code การใช้ฟังก์ชั่น === | ||
+ | <pre> | ||
+ | hull = cv2.convexHull(cnt,returnPoints = False) | ||
+ | defects = cv2.convexityDefects(cnt,hull) | ||
+ | </pre> | ||
+ | === Code เต็ม === | ||
+ | <pre> | ||
+ | import cv2 | ||
+ | import numpy as np | ||
+ | |||
+ | img = cv2.imread('star.jpg') | ||
+ | img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) | ||
+ | ret, thresh = cv2.threshold(img_gray, 127, 255,0) | ||
+ | contours,hierarchy = cv2.findContours(thresh,2,1) | ||
+ | cnt = contours[0] | ||
+ | |||
+ | hull = cv2.convexHull(cnt,returnPoints = False) | ||
+ | defects = cv2.convexityDefects(cnt,hull) | ||
+ | |||
+ | for i in range(defects.shape[0]): | ||
+ | s,e,f,d = defects[i,0] | ||
+ | start = tuple(cnt[s][0]) | ||
+ | end = tuple(cnt[e][0]) | ||
+ | far = tuple(cnt[f][0]) | ||
+ | cv2.line(img,start,end,[0,255,0],2) | ||
+ | cv2.circle(img,far,5,[0,0,255],-1) | ||
+ | |||
+ | cv2.imshow('img',img) | ||
+ | cv2.waitKey(0) | ||
+ | cv2.destroyAllWindows() | ||
+ | </pre> | ||
+ | <center> [[ไฟล์:Defects.jpg|frame|center|ขอบคุณรูปภาพจาก OpenCV.org ]] </center> | ||
+ | == Point Polygon Test == | ||
+ | * ฟังก์ชั่นนี้จะหาระยะทางที่สั้นที่สุดระหว่างจุดในภาพและเส้นแสดงรูปร่าง โดยกลับระยะทางที่เป็นลบเมื่อจุดนั้นอยู่นอกเส้นบวก | ||
+ | ** ยกตัวอย่างการหาค่า (50,50) | ||
+ | === Code Example === | ||
+ | <pre> | ||
+ | dist = cv2.pointPolygonTest(cnt,(50,50),True | ||
+ | </pre> | ||
+ | == Match Shapes == | ||
+ | * การหารูปร่างที่ตรงกัน โดยจะใช้ฟังก์ชั่น cv2.matchShapes() เพื่อเปิดการหาภาพที่ตรงกันทั้งสองภาพ มี Code ดังนี้ | ||
+ | === Code Example === | ||
+ | <pre> | ||
+ | import cv2 | ||
+ | import numpy as np | ||
+ | |||
+ | img1 = cv2.imread('star.jpg',0) | ||
+ | img2 = cv2.imread('star2.jpg',0) | ||
+ | |||
+ | ret, thresh = cv2.threshold(img1, 127, 255,0) | ||
+ | ret, thresh2 = cv2.threshold(img2, 127, 255,0) | ||
+ | contours,hierarchy = cv2.findContours(thresh,2,1) | ||
+ | cnt1 = contours[0] | ||
+ | contours,hierarchy = cv2.findContours(thresh2,2,1) | ||
+ | cnt2 = contours[0] | ||
+ | |||
+ | ret = cv2.matchShapes(cnt1,cnt2,1,0.0) | ||
+ | print ret | ||
+ | </pre> | ||
+ | === Result === | ||
+ | <center> [[ไฟล์:Matchshapes.jpg|frame|center|ขอบคุณรูปภาพจาก OpenCV.org ]] </center> | ||
+ | |||
+ | * ผลลัพธ์ที่ได้เป็นค่าคือ | ||
+ | ** รูป A กับ A = 0.0 | ||
+ | ** รูป A กับ B = 0.001946 | ||
+ | ** รูป A กับ C = 0.326911 | ||
+ | |||
+ | |||
+ | = Contours Hierarchy = | ||
+ | == วัตถุประสงค์ == | ||
+ | * เรียนรู้เกี่ยวกับลำดับชั้นของรูปทรงที่ i.e มีความสัมพันธ์กับ parent-child ใน Contour | ||
+ | == Hierarchy? == | ||
+ | * โดยตกติจะใช้ฟังก์ชั่น cv2.findContours() เพื่อตรวจจับวัตถุของรูปภาพที่นำเข้ามา แต่บางครั้ง วัตถุอื่นที่อยู่คนละ location เดียวกัน ในวิธีนี้บาง object อาจอยู่ในอีก object โดยการหา Parent และในนั้นเป็น child นั้นว่าทั้งสองมีความสัมพันธ์กันอย่างไรมีการเชื่อมต่อกับแบบไหนอย่างไร ทั้งหมดนั้นคือ Hierarchy | ||
+ | <center> [[ไฟล์:Hierarchy.png|frame|center|ขอบคุณรูปภาพจาก OpenCV.org ]] </center> | ||
+ | |||
+ | == Hierarchy Representation in OpenCV == | ||
+ | * ในการหาเส้นรูปร่างของสารสนเทศที่นำเข้ามานั้นเพื่อหาว่าใครเป็น โน๊ดแม่ โน๊ดลูก (Parent-Child) ใน OpenCV จะแสดง Array of four values ออกมา จะเห็นได้ในโค๊ดตัวอย่างในหัวข้อ Contour Retrieval Mode | ||
+ | |||
+ | == Contour Retrieval Mode == | ||
+ | === 1. RETR_LIST === | ||
+ | * ในการยกตัวอย่างเรื่องนี้ จะยกตัวอย่างการผลลัพธ์ที่งมดที่ได้จาก Contour แต่จะไม่มีการสร้างความสัมพันธ์ของ Parent - Child ทั้งสั้น โดยกล่าวได้ว่า | ||
+ | * '''Parents and kids are equal under this rule, and they are just contours''' | ||
+ | ==== ยกตัวอย่าง CODE ==== | ||
+ | <pre> | ||
+ | >>> hierarchy | ||
+ | array([[[ 1, -1, -1, -1], | ||
+ | [ 2, 0, -1, -1], | ||
+ | [ 3, 1, -1, -1], | ||
+ | [ 4, 2, -1, -1], | ||
+ | [ 5, 3, -1, -1], | ||
+ | [ 6, 4, -1, -1], | ||
+ | [ 7, 5, -1, -1], | ||
+ | [-1, 6, -1, -1]]]) | ||
+ | </pre> | ||
+ | |||
+ | === 2. RETR_EXTERNAL === | ||
+ | * ในเรื่องนี้จะหาค่าจุดสุดท้ายของแต่ละด้าน กล่าวได้ว่า | ||
+ | * '''We can say, under this law, Only the eldest in every family is taken care of. It doesn't care about other members of the family :)''' | ||
+ | ==== ยกตัวอย่าง CODE ==== | ||
+ | <pre> | ||
+ | >>> hierarchy | ||
+ | array([[[ 1, -1, -1, -1], | ||
+ | [ 2, 0, -1, -1], | ||
+ | [-1, 1, -1, -1]]]) | ||
+ | </pre> | ||
+ | |||
+ | === 3. RETR_CCOMP === | ||
+ | * เรื่องนี้จะแสดงเส้นแสดงรูปร่างของการจัดวางของ 2-level hierachy ยกตัวอย่างว่า วัตถุที่อยู่นอก object และอยู่ใน Object ดังกล่างโดยสามารถดูรูปเพื่อทำความเข้าใจ ในเรื่องนี้ได้ | ||
+ | ==== ยกตัวอย่างรูปภาพ ==== | ||
+ | <center> [[ไฟล์:Ccomp hierarchy.png|frame|center|ขอบคุณรูปภาพจาก OpenCV.org ]] </center> | ||
+ | ==== ยกตัวอย่าง CODE ==== | ||
+ | <pre> | ||
+ | >>> hierarchy | ||
+ | array([[[ 3, -1, 1, -1], | ||
+ | [ 2, -1, -1, 0], | ||
+ | [-1, 1, -1, 0], | ||
+ | [ 5, 0, 4, -1], | ||
+ | [-1, -1, -1, 3], | ||
+ | [ 7, 3, 6, -1], | ||
+ | [-1, -1, -1, 5], | ||
+ | [ 8, 5, -1, -1], | ||
+ | [-1, 7, -1, -1]]]) | ||
+ | </pre> | ||
+ | |||
+ | === 4. RETR_TREE === | ||
+ | * ในบทนี้จะใช้ฟังก์ชั่น cv2.RETR_TREE เพื่อหาการเรียงลำดับของรูปทรงที่ผลลัพธ์จาก OpenCV โดยจะวิเคราะห์อีกครั้ง โดยข้อความสีแดงจะจะบอก ตัวเลขของ Contour และ ข้อความสีเขียวจะบอก ลำดับชั้นของความสัมพันธ์ (hierarchy) | ||
+ | ==== ยกตัวอย่างรูปภาพ ==== | ||
+ | <center> [[ไฟล์:Tree hierarchy.png|frame|center|ขอบคุณรูปภาพจาก OpenCV.org ]] </center> | ||
+ | ==== ยกตัวอย่าง CODE ==== | ||
+ | <pre> | ||
+ | >>> hierarchy | ||
+ | array([[[ 7, -1, 1, -1], | ||
+ | [-1, -1, 2, 0], | ||
+ | [-1, -1, 3, 1], | ||
+ | [-1, -1, 4, 2], | ||
+ | [-1, -1, 5, 3], | ||
+ | [ 6, -1, -1, 4], | ||
+ | [-1, 5, -1, 4], | ||
+ | [ 8, 0, -1, -1], | ||
+ | [-1, 7, -1, -1]]]) | ||
+ | </pre> |
รุ่นแก้ไขปัจจุบันเมื่อ 03:38, 8 สิงหาคม 2559
เนื้อหา
- 1 Contours : Getting Started
- 2 Contour Features
- 3 Contour Properties
- 4 Contours : More Functions
- 5 Contours Hierarchy
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)
Image Result
Contour Properties
- ในบทนี้ จะเรียนรู้เกี่ยวกับคุณสมบัติของ Contour ว่า Object อะไรบ้าง เช่น Solidity, Equivalent Diameter, Mask image, Mean Intensity เพิ่มเติมที่ : [เพิ่มเติม]
Aspect Ratio
- เรื่องการหาอัตราส่วนของความกว้างความสูง และขอบเขตของวัตถุ ตามสูตร
Code Example
x,y,w,h = cv2.boundingRect(cnt) aspect_ratio = float(w)/h
Extent
- ขอบเขตของอัตราส่วนพื้นที่สี่เหลี่ยมผืนผ้า ตามสูตร
Code Example
area = cv2.contourArea(cnt) x,y,w,h = cv2.boundingRect(cnt) rect_area = w*h extent = float(area)/rect_area
Solidity
- ค่าความแข็งแรงคือ อัตราส่วนของพื้นที่เส้นแสดงรูปร่างการนูนออกของพื้นที่ ตามสูตร
Code Example
area= cv2.contourArea(cnt) hull = cv2.convexHull(cnt) hull_area = cv2.contourArea(hull) solidity = float(area)/hull_area
Equivalent Diameter
- การหาเส้นผ่าศูนย์กลางของวงกลมนั้น ทำได้เหมือนกันกับการหาพื้นที่เส้นแสดงรูปร่าง ตามสูตร
Code Example
area = cv2.contourArea(cnt) equi_diameter = np.sqrt(4*area/np.pi)
Orientation
- คือการจัดวางแนวที่เป็นมุมของวัตถุ วิธีนี้ช่วยให้ได้ค่าความยาวของแกนหลักและแกนรอง
Code Example
(x,y),(MA,ma),angle = cv2.fitEllipse(cnt)
Mask and Pixel Points
- วิธีนี้ ทุกๆจัดต้องประกอบด้วยวัตถุ สามารถทำได้ดังนี้
Code Example
mask = np.zeros(imgray.shape,np.uint8) cv2.drawContours(mask,[cnt],0,255,-1) pixelpoints = np.transpose(np.nonzero(mask)) #pixelpoints = cv2.findNonZero(mask)
Maximum Value, Minimum Value and their locations
- ในบทนี้จะสามารถหาค่าพารามิเตอร์โดยการใช้ mask image
Code Example
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(imgray,mask = mask)
Mean Color or Mean Intensity
- หัวข้อนี้สามารถหาสีที่มีค่าเฉลี่ยของวัตถุ หรืออาจใช้ความเข้มเฉลี่ย ของวัตถุในโหมดสีเทา อาจจะใช้วิธีเดียวกันกับ mask image
Code Example
mean_val = cv2.mean(im,mask = mask)
Extreme Points
- จุดที่สูงที่สุดหมายถึง Topmost , Bottommost , rightmost , leftmost หรือ จุดสุดท้ายของแต่ละด้าน ของวัตถุ
Code Example
leftmost = tuple(cnt[cnt[:,:,0].argmin()][0]) rightmost = tuple(cnt[cnt[:,:,0].argmax()][0]) topmost = tuple(cnt[cnt[:,:,1].argmin()][0]) bottommost = tuple(cnt[cnt[:,:,1].argmax()][0])
Result Extream Point
Contours : More Functions
วัตถุประสงค์
- เพื่อหาข้อบกพร่องนูนและวิธีการที่จะพบ
- การหาระยะทางที่สั้นที่สุดจาก A ไปหา เหลี่ยม
- จับคุ่รูปร่างที่แตกต่าง
Convexity Defects
- ในการสิ่งที่เป็นเปลือกนูนในบทที่ 2 ของ Contour นั้น ทุกๆ การเบี่ยงเบนของ Object นั้น จะถือเป็นข้อบกพร่องของการนูน
- โดย OpenCV จะนำมีฟังก์ชั้นเกี่ยวกับเรื่องนี้มาด้วย นั้นคือฟังก์ชั่น cv2.convexityDefects()
Code การใช้ฟังก์ชั่น
hull = cv2.convexHull(cnt,returnPoints = False) defects = cv2.convexityDefects(cnt,hull)
Code เต็ม
import cv2 import numpy as np img = cv2.imread('star.jpg') img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold(img_gray, 127, 255,0) contours,hierarchy = cv2.findContours(thresh,2,1) cnt = contours[0] hull = cv2.convexHull(cnt,returnPoints = False) defects = cv2.convexityDefects(cnt,hull) for i in range(defects.shape[0]): s,e,f,d = defects[i,0] start = tuple(cnt[s][0]) end = tuple(cnt[e][0]) far = tuple(cnt[f][0]) cv2.line(img,start,end,[0,255,0],2) cv2.circle(img,far,5,[0,0,255],-1) cv2.imshow('img',img) cv2.waitKey(0) cv2.destroyAllWindows()
Point Polygon Test
- ฟังก์ชั่นนี้จะหาระยะทางที่สั้นที่สุดระหว่างจุดในภาพและเส้นแสดงรูปร่าง โดยกลับระยะทางที่เป็นลบเมื่อจุดนั้นอยู่นอกเส้นบวก
- ยกตัวอย่างการหาค่า (50,50)
Code Example
dist = cv2.pointPolygonTest(cnt,(50,50),True
Match Shapes
- การหารูปร่างที่ตรงกัน โดยจะใช้ฟังก์ชั่น cv2.matchShapes() เพื่อเปิดการหาภาพที่ตรงกันทั้งสองภาพ มี Code ดังนี้
Code Example
import cv2 import numpy as np img1 = cv2.imread('star.jpg',0) img2 = cv2.imread('star2.jpg',0) ret, thresh = cv2.threshold(img1, 127, 255,0) ret, thresh2 = cv2.threshold(img2, 127, 255,0) contours,hierarchy = cv2.findContours(thresh,2,1) cnt1 = contours[0] contours,hierarchy = cv2.findContours(thresh2,2,1) cnt2 = contours[0] ret = cv2.matchShapes(cnt1,cnt2,1,0.0) print ret
Result
- ผลลัพธ์ที่ได้เป็นค่าคือ
- รูป A กับ A = 0.0
- รูป A กับ B = 0.001946
- รูป A กับ C = 0.326911
Contours Hierarchy
วัตถุประสงค์
- เรียนรู้เกี่ยวกับลำดับชั้นของรูปทรงที่ i.e มีความสัมพันธ์กับ parent-child ใน Contour
Hierarchy?
- โดยตกติจะใช้ฟังก์ชั่น cv2.findContours() เพื่อตรวจจับวัตถุของรูปภาพที่นำเข้ามา แต่บางครั้ง วัตถุอื่นที่อยู่คนละ location เดียวกัน ในวิธีนี้บาง object อาจอยู่ในอีก object โดยการหา Parent และในนั้นเป็น child นั้นว่าทั้งสองมีความสัมพันธ์กันอย่างไรมีการเชื่อมต่อกับแบบไหนอย่างไร ทั้งหมดนั้นคือ Hierarchy
Hierarchy Representation in OpenCV
- ในการหาเส้นรูปร่างของสารสนเทศที่นำเข้ามานั้นเพื่อหาว่าใครเป็น โน๊ดแม่ โน๊ดลูก (Parent-Child) ใน OpenCV จะแสดง Array of four values ออกมา จะเห็นได้ในโค๊ดตัวอย่างในหัวข้อ Contour Retrieval Mode
Contour Retrieval Mode
1. RETR_LIST
- ในการยกตัวอย่างเรื่องนี้ จะยกตัวอย่างการผลลัพธ์ที่งมดที่ได้จาก Contour แต่จะไม่มีการสร้างความสัมพันธ์ของ Parent - Child ทั้งสั้น โดยกล่าวได้ว่า
- Parents and kids are equal under this rule, and they are just contours
ยกตัวอย่าง CODE
>>> hierarchy array([[[ 1, -1, -1, -1], [ 2, 0, -1, -1], [ 3, 1, -1, -1], [ 4, 2, -1, -1], [ 5, 3, -1, -1], [ 6, 4, -1, -1], [ 7, 5, -1, -1], [-1, 6, -1, -1]]])
2. RETR_EXTERNAL
- ในเรื่องนี้จะหาค่าจุดสุดท้ายของแต่ละด้าน กล่าวได้ว่า
- We can say, under this law, Only the eldest in every family is taken care of. It doesn't care about other members of the family :)
ยกตัวอย่าง CODE
>>> hierarchy array([[[ 1, -1, -1, -1], [ 2, 0, -1, -1], [-1, 1, -1, -1]]])
3. RETR_CCOMP
- เรื่องนี้จะแสดงเส้นแสดงรูปร่างของการจัดวางของ 2-level hierachy ยกตัวอย่างว่า วัตถุที่อยู่นอก object และอยู่ใน Object ดังกล่างโดยสามารถดูรูปเพื่อทำความเข้าใจ ในเรื่องนี้ได้
ยกตัวอย่างรูปภาพ
ยกตัวอย่าง CODE
>>> hierarchy array([[[ 3, -1, 1, -1], [ 2, -1, -1, 0], [-1, 1, -1, 0], [ 5, 0, 4, -1], [-1, -1, -1, 3], [ 7, 3, 6, -1], [-1, -1, -1, 5], [ 8, 5, -1, -1], [-1, 7, -1, -1]]])
4. RETR_TREE
- ในบทนี้จะใช้ฟังก์ชั่น cv2.RETR_TREE เพื่อหาการเรียงลำดับของรูปทรงที่ผลลัพธ์จาก OpenCV โดยจะวิเคราะห์อีกครั้ง โดยข้อความสีแดงจะจะบอก ตัวเลขของ Contour และ ข้อความสีเขียวจะบอก ลำดับชั้นของความสัมพันธ์ (hierarchy)
ยกตัวอย่างรูปภาพ
ยกตัวอย่าง CODE
>>> hierarchy array([[[ 7, -1, 1, -1], [-1, -1, 2, 0], [-1, -1, 3, 1], [-1, -1, 4, 2], [-1, -1, 5, 3], [ 6, -1, -1, 4], [-1, 5, -1, 4], [ 8, 0, -1, -1], [-1, 7, -1, -1]]])