Opencv Python 輪廓處理
Opencv python從零開始第一天之影像輪廓處理
本人大一數學系學渣菜鳥一枚,由于興趣,課程之余在學習OpenCV,
也是從零開始,想一邊學一邊把學的東西整理放在CSDN存一下
不喜勿噴哈哈哈哈
我是菜雞
`
``python
#program 1.繪制輪廓
import numpy as np
import cv2 as cv
#讀取影像
img = cv.imread("G:\sundries\CVpictures\practice1.jpg")
#一些必要的操作:匯入影像、二值化、canny邊緣檢測、cnt的給出
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
#創建3*3的高斯濾波內核
img_gray = cv.GaussianBlur(img_gray, (3, 3), 0)
# canny邊緣檢測
img_gray = cv.Canny(img_gray, 100, 300)
ret, thresh = cv.threshold(img_gray, 127, 255, cv.THRESH_BINARY)
contours, hierarchy = cv.findContours(thresh, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)
cnt = contours[0]
#進行繪制
cv.drawContours(img, contours, -1, (0,255,0), 3)
cv.imshow("read", img)
cv.waitKey(0) & 0xFF
cv.destroyAllWindows()
#program 2.去除影像的矩形邊框,找到并提取指定輪廓
#由于影像在識別輪廓的程序中可能會把外框矩形也識別并畫出來,所以我們找個辦法把指定的輪廓去除
import numpy as np
import cv2 as cv
img = cv.imread("G:\sundries\CVpictures\practice1.jpg")
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
img_gray = cv.Canny(img_gray, 100, 300)
ret, thresh = cv.threshold(img_gray, 127, 255, cv.THRESH_BINARY)
contours, hierarchy = cv.findContours(thresh, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)
cnt = contours[0]
M = cv.moments(cnt)
cv.imshow("thresh", thresh)
'''
finContours(img, mode, method)
mode(輪廓檢索模式):
RETR_EXTERNAL :只檢索最外面的輪廓;
RETR_LIST:檢索所有的輪廓,并將其保存到一條鏈表當中;
RETR_CCOMP:檢索所有的輪廓,并將他們組織為兩層:頂層是各部分的外部邊界,第二層是空洞的邊界;
RETR_TREE(最常用):檢索所有的輪廓,并重構嵌套輪廓的整個層次;
method(輪廓逼近方法):
CHAIN_APPROX_NONE:以Freeman鏈碼的方式輸出輪廓,所有其他方法輸出多邊形(頂點的序列),
CHAIN_APPROX_SIMPLE(最常用):壓縮水平的、垂直的和斜的部分,也就是,函式只保留他們的終點部分,
'''
# 查看輪廓的數量
number = numpy.array(contours).shape
# 復制影像,新的影像作為邊界繪制的底圖
cp = img.copy()
res1 = cv.drawContours(cp, contours, -1, (0, 0, 255), 2)
cp = img.copy()
res2 = cv.drawContours(cp, contours, 0, (0, 0, 255), 2)
# 合并兩張影像
res = numpy.hstack((res1, res2))
print("number:", number)
cv.imshow("res", res)
cv.waitKey(0) & 0xFF
cv.destroyAllWindows()
#program 3.提取特征矩,進行簡單計算
'''
關于影像的矩的一些決議:
矩用來抽取影像(塊)特征,本質上,Hu矩其實就是泰勒級數展開的對應項,其他型別的矩也是對應多項式展開的級數(如Legendre矩對應Legendre級數),在影像里,低階矩反映低頻(主要的)資訊,高階矩反映高頻(細節)資訊,
0階矩( m[00]):目標區域的面積(Area)
1階矩( m[01] , m[10] ):目標區域的質心(Centroid)
以目標區域的質心為中心構建中心矩,那么矩的計算時永遠是目標區域中的點相對于目標區域的質心,而與目標區域的位置無關,即中心矩具備了平移不變性,
2階矩(m[20] ,m[02] , m[11] ):即慣性矩,可計算目標影像的方向
3階矩(m[30] , m[03] , m[12], m[21]):目標區域的方位和斜度,反應目標的扭曲
Hu矩:目標區域往往伴隨著空間變換(平移,尺度,旋轉),所以需要在普通矩的基礎上構造出具備不變性的矩組
更多關于矩的知識可以參考https://www.cnblogs.com/ronny/p/3985810.html
'''
import numpy as np
import cv2 as cv
img = cv.imread("G:\sundries\CVpictures\practice1.jpg")
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
img_gray = cv.Canny(img_gray, 100, 300)
ret, thresh = cv.threshold(img_gray, 127, 255, cv.THRESH_BINARY)
contours, hierarchy = cv.findContours(thresh, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)
cnt = contours[0]
M = cv.moments(cnt)
#求影像面積
area = cv.contourArea(cnt)
#求影像周長
perimeter = cv.arcLength(cnt,True)
#第二引數可以用來指定物件的形狀是閉合的(True)還是打開的(一條曲線)
print(perimeter)
print( M )
print(area)
#program 4.輪廓近似
import numpy as np
import cv2 as cv
img = cv.imread("G:\sundries\CVpictures\practice1.jpg")
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
img_gray = cv.Canny(img_gray, 100, 300)
ret, thresh = cv.threshold(img_gray, 127, 255, cv.THRESH_BINARY)
contours, hierarchy = cv.findContours(thresh, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)
cnt = contours[0]
#引數設定
epsilon = 0.1*cv.arcLength(cnt,True)
approx = cv.approxPolyDP(cnt,epsilon,True)# 第三個函式引數若為true,則說明近似曲線是閉合的,它的首位都是相連,反之,若為false,則斷開,
cv.imshow('approx',img)
cv.waitKey(0) & 0xFF
cv.destroyAllWindows()
#program 5.凸包
import numpy as np
import cv2 as cv
img = cv.imread("G:\sundries\CVpictures\practice1.jpg")
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
img_gray = cv.Canny(img_gray, 100, 300)
ret, thresh = cv.threshold(img_gray, 127, 255, cv.THRESH_BINARY)
contours, hierarchy = cv.findContours(thresh, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)
cnt = contours[0]
img_result = img.copy()
#獲取連通域
cont = get_contours(img_src)
cv.drawContours(img_result, cont, -1, (0, 0, 255), 2)
#獲取凸包點,連接點
hull_points = cv.convexHull(cont)#檢查一個曲線的凸性缺陷并進行修正
cv.polylines(img_result, [hull_points], True, (0, 255, 0), 2)
cv.imshow("img_result", img_result)
cv.waitKey(0) & 0xFF
cv.destroyAllWindows()
#program 6.規則圖形的擬合:矩形、旋轉矩形、圓、橢圓
import numpy as np
import cv2 as cv
img = cv.imread("G:\sundries\CVpictures\practice1.jpg")
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
img_gray = cv.Canny(img_gray, 100, 300)
ret, thresh = cv.threshold(img_gray, 127, 255, cv.THRESH_BINARY)
contours, hierarchy = cv.findContours(thresh, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)
cnt = contours[0]
x,y,w,h = cv.boundingRect(cnt)
#擬合矩形
img1 = cv.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
cv.imshow("rectangle", img1)
cv.waitKey(0) & 0xFF
cv.destroyAllWindows()
#擬合旋轉矩形
rect = cv.minAreaRect(cnt)
box = cv.boxPoints(rect)
box = np.int0(box)
img2 = cv.drawContours(img,[box],0,(0,0,255),2)
cv.imshow("rotarec", img2)
cv.waitKey(0) & 0xFF
cv.destroyAllWindows()
#擬合影像輪廓的最小閉合圈
(x,y),radius = cv.minEnclosingCircle(cnt)
center = (int(x),int(y))
radius = int(radius)#取整
img3 = cv.circle(img,center,radius,(0,255,0),2)
cv.imshow("rectangle", img3)
cv.waitKey(0) & 0xFF
cv.destroyAllWindows()
#擬合影像輪廓的最小閉合橢圓
ellipse = cv.fitEllipse(cnt)
img4 = cv.ellipse(img,ellipse,(0,255,0),2)
cv.imshow("rectangle", img4)
cv.waitKey(0) & 0xFF
cv.destroyAllWindows()
#program 7.輪廓屬性的提取與運用
import numpy as np
import cv2 as cv
img = cv.imread("G:\sundries\CVpictures\practice1.jpg")
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
img_gray = cv.Canny(img_gray, 100, 300)
ret, thresh = cv.threshold(img_gray, 127, 255, cv.THRESH_BINARY)
contours, hierarchy = cv.findContours(thresh, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)
cnt = contours[0]
x,y,w,h = cv.boundingRect(cnt)
area = cv.contourArea(cnt)
#求輪廓的長寬比
aspect_ratio = float(w)/h
print(aspect_ratio)
#求輪廓的范圍:輪廓區域與邊界區域比值
rect_area = w*h
extent = float(area)/rect_area
print(extent)
#求輪廓的堅實度:等高線面積與其凸包面積之比
hull = cv.convexHull(cnt)
hull_area = cv.contourArea(hull)
solidity = float(area)/hull_area
print(solidity)
#求輪廓的等效直徑:面積與輪廓面積相同的圓的直徑
equi_diameter = np.sqrt(4*area/np.pi)
print(equi_diameter)
#求輪廓的取向:物體指向的角度
(x,y),(MA,ma),angle = cv.fitEllipse(cnt)
#MA為主軸長度,ma為負軸長度
print(MA)
print(ma)
print(angle)
#找到構成物件的所有點
mask = np.zeros(img_gray.shape,np.uint8)
cv.drawContours(mask,[cnt],0,255,-1)
pixelpoints = cv.findNonZero(mask)
#可以用numpy的 pixelpoints = np.transpose(np.nonzero(mask)) 來替換這一句
print(pixelpoints)
#找到這些點的最大值,最小值和它們的位置
min_val, max_val, min_loc, max_loc = cv.minMaxLoc(img_gray,mask = mask)
print(min_val)
print(max_val)
print(min_loc)
print(max_loc)
#program 8.找到物件的平均顏色或灰值影像的平均強度
import numpy as np
import cv2 as cv
img = cv.imread("G:\sundries\CVpictures\practice1.jpg")
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
img_gray = cv.Canny(img_gray, 100, 300)
ret, thresh = cv.threshold(img_gray, 127, 255, cv.THRESH_BINARY)
contours, hierarchy = cv.findContours(thresh, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)
cnt = contours[0]
mean_val = cv.mean(img,mask = mask)
print(mean_val)
#program 9.找到影像的極端點
import numpy as np
import cv2 as cv
img = cv.imread("G:\sundries\CVpictures\practice1.jpg")
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
img_gray = cv.Canny(img_gray, 100, 300)
ret, thresh = cv.threshold(img_gray, 127, 255, cv.THRESH_BINARY)
contours, hierarchy = cv.findContours(thresh, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)
cnt = contours[0]
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])
print(leftmost,rightmost,topmost,bottommost)
#program 10.修正凸性缺陷
import numpy as np
import cv2 as cv
img = cv.imread("G:\sundries\CVpictures\practice1.jpg")
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
img_gray = cv.Canny(img_gray, 100, 300)
contours, hierarchy = cv.findContours(thresh, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)
cnt = contours[0]
ret, thresh = cv.threshold(cv.cvtColor(img.copy(), cv.COLOR_BGR2GRAY) , 127, 255, cv.THRESH_BINARY)
black = cv.cvtColor(np.zeros((img.shape[1], img.shape[0]), dtype=np.uint8), cv.COLOR_GRAY2BGR)
#引數cv2.RETR_EXTERNAL是獲取最外層輪廓
hull = cv.convexHull(cnt)
cv.drawContours(black, [hull], -1, (0, 0, 255), 2)
#修正凸性缺陷的輪廓區域
cv.imshow("hull", black)
cv.waitKey(0)
cv.destroyAllWindows()
#program 11.點多邊形測驗
import numpy as np
import cv2 as cv
img = cv.imread("G:\sundries\CVpictures\practice1.jpg")
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
img_gray = cv.Canny(img_gray, 100, 300)
ret, thresh = cv.threshold(img_gray, 127, 255, cv.THRESH_BINARY)
contours, hierarchy = cv.findContours(thresh, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)
cnt = contours[0]
dist = cv.pointPolygonTest(cnt,(50,50),True)
'''
第三個引數是measureDist,如果它是真的,它會找到有符號的距離
如果為假,則查找該點是在輪廓線內部還是外部(分別回傳+1、-1和0)
如果不想找到距離,第三個引數為False,可使速度提高2-3倍
''''
#program 12.形狀匹配
#cv.matchShapes(),比較兩個形狀或兩個輪廓,并回傳一個顯示相似性的度量,結果越低,匹配越好,它是根據矩值計算出來的
import cv2 as cv
import numpy as np
img1 = cv.imread('G:\sundries\CVpictures\stars1.jpg',0)
img2 = cv.imread('G:\sundries\CVpictures\stars2.jpg',0)
ret, thresh = cv.threshold(img1, 127, 255,0)
ret, thresh2 = cv.threshold(img2, 127, 255,0)
contours,hierarchy = cv.findContours(thresh,2,1)
cnt1 = contours[0]
contours,hierarchy = cv.findContours(thresh2,2,1)
cnt2 = contours[0]
ret = cv.matchShapes(cnt1,cnt2,1,0.0)
print( ret )
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/281646.html
標籤:python
下一篇:網路美女爬取
