ลำดับที่ | ชื่อ | ค่าที่ต้องใส่ | ชนิดข้อมูล |
---|---|---|---|
1 | curve | ตำแหน่งจุดบนเส้น | np.array |
2 | epsilon | ค่าที่กำหนดความละเอียดของการยุบย่อ | float |
3 | closed | เป็นเส้นปิดหรือไม่ | True/False |
import cv2
import numpy as np
import matplotlib.pyplot as plt
teto = cv2.imread('teto14c01.jpg') # อ่านภาพสี
teto_gr = cv2.cvtColor(teto,cv2.COLOR_BGR2GRAY) # แปลงเป็นขาวดำ
_,teto_thr = cv2.threshold(teto_gr,10,255,0)
# แปลงสัณฐานเพื่อลดจุดปนเปื้อน
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))
teto_thr = cv2.morphologyEx(teto_thr,cv2.MORPH_CLOSE,kernel)
# หาเค้าโครง
contour,_ = cv2.findContours(teto_thr,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
n_contour = len(contour)
# สีของเส้นเค้าโครงแต่ละเส้น
si = plt.get_cmap('rainbow')(np.arange(n_contour)/(n_contour-1))[:,[2,1,0]]*255
# สร้างเค้าโครงใหม่ที่ย่อลงจากเดิมเล็กน้อย
contour_dp1 = [cv2.approxPolyDP(cnt,4.5,True) for cnt in contour]
# สร้างเค้าโครงใหม่ที่ย่อลงจากเดิมไปค่อนข้างมาก
contour_dp2 = [cv2.approxPolyDP(cnt,11,True) for cnt in contour]
teto_cnt = teto.copy()
teto_cnt_dp1 = teto.copy()
teto_cnt_dp2 = teto.copy()
for i in range(n_contour):
teto_cnt = cv2.drawContours(teto_cnt,contour,i,si[i],2)
teto_cnt_dp1 = cv2.drawContours(teto_cnt_dp1,contour_dp1,i,si[i],2)
teto_cnt_dp2 = cv2.drawContours(teto_cnt_dp2,contour_dp2,i,si[i],2)
cv2.imwrite('teto14c02.jpg',teto_cnt)
cv2.imwrite('teto14c03.jpg',teto_cnt_dp1)
cv2.imwrite('teto14c04.jpg',teto_cnt_dp2)
cnt = np.array([[[0,0.5]],
[[1,1]],
[[0.5,0.5]],
[[0.8,0]]],dtype=np.float32)
ax = plt.subplot(121,aspect=1)
ax.add_patch(plt.Polygon(cnt[:,0],fc='w',ec='g'))
cnt_ch = cv2.convexHull(cnt)
ax = plt.subplot(122,aspect=1)
ax.add_patch(plt.Polygon(cnt_ch[:,0],fc='w',ec='g'))
plt.show()
teto_cnt = teto.copy()
for i in range(n_contour):
cnt = cv2.convexHull(contour[i])
teto_cnt = cv2.drawContours(teto_cnt,[cnt],0,si[i],2)
cv2.imwrite('teto14c05.jpg',teto_cnt)
cnt1 = np.array([[[0,0]],
[[1,2]],
[[0,3]],
[[-1,2]]])
cnt2 = np.array([[[0,0]],
[[1,2]],
[[0,1]],
[[-1,3]]])
cnt2_ch = cv2.convexHull(cnt2)
ax = plt.subplot(131,aspect=1,xlim=[-2,2],ylim=[0,4])
ax.add_patch(plt.Polygon(cnt1[:,0],fc='w',ec='m'))
ax = plt.subplot(132,aspect=1,xlim=[-2,2],ylim=[0,4])
ax.add_patch(plt.Polygon(cnt2[:,0],fc='w',ec='m'))
ax = plt.subplot(133,aspect=1,xlim=[-2,2],ylim=[0,4])
ax.add_patch(plt.Polygon(cnt2_ch[:,0],fc='w',ec='m'))
plt.show()
print(cv2.isContourConvex(cnt1)) # ได้ True
print(cv2.isContourConvex(cnt2)) # ได้ False
print(cv2.isContourConvex(cnt2_ch)) # ได้ True
rin = cv2.imread('rin14c01.jpg')
rin_gr = cv2.cvtColor(rin,cv2.COLOR_BGR2GRAY)
_,rin_thr = cv2.threshold(rin_gr,10,255,0)
# แปลงสัณฐานเพื่อลดจุดปนเปื้อน
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))
rin_thr = cv2.morphologyEx(rin_thr,cv2.MORPH_CLOSE,kernel)
# หาเค้าโครง
contour,_ = cv2.findContours(rin_thr,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
n_contour = len(contour)
# สีของเส้นเค้าโครงแต่ละเส้น
si = plt.get_cmap('rainbow')(np.arange(n_contour)/(n_contour-1))[:,[2,1,0]]*255
rin_cnt = rin.copy()
siliam = []
for i,cnt in enumerate(contour):
# วาดเส้นเค้าโครงเดิม
rin_cnt = cv2.drawContours(rin_cnt,[cnt],0,si[i],2)
rect = cv2.minAreaRect(cnt) # หาสี่เหลี่ยมที่ล้อม
siliam.append(rect) # เก็บข้อมูลกรอบสี่เหลี่ยมไว้
for i in range(n_contour):
# แปลงข้อมูลกรอบสี่เหลี่ยมเป็นเค้าโครง ข้อมูลต้องเปลี่ยนเป็น int จึงจะใช้ใน cv2.drawContours() ได้
box = cv2.boxPoints(siliam[i]).astype(int)
# วาดเส้นเค้าโครงสี่เหลี่ยม
rin_cnt = cv2.drawContours(rin_cnt,[box],0,si[i],2)
cv2.imwrite('rin14c02.jpg',rin_cnt)
# ไล่เทียบดูทีละคู่
for i in range(len(siliam)):
for j in range(i+1,len(siliam)):
mi,tat = cv2.rotatedRectangleIntersection(siliam[i],siliam[j])
# ถ้า mi เป็น 1 แสดงว่ามีส่วนซ้อนทับ ก็เอามาวาด
if(mi):
tat = tat.astype(int) # ต้องเปลี่ยนชนิดข้อมูลเป็น int จึงจะใช้ใน cv2.drawContours() ได้
rin_cnt = cv2.drawContours(rin_cnt,[tat],0,(si[i]+si[j])/2,5)
cv2.imwrite('rin14c03.jpg',rin_cnt)
ติดตามอัปเดตของบล็อกได้ที่แฟนเพจ