【OpenCV+Python】輪廓特徵中階

2021-02-21 電子產品世界

本次我們將討論OpenCV中圖像輪廓的另一些特徵,它們將非常有用。

有兩類邊界矩形。

▶直邊界矩形

一個直矩形(就是沒有旋轉的矩形)。它不會考慮對象是否旋轉。所以邊界矩形的面積不是最小的。可以使用函數cv2.boundingRect()查找得到,我們來看函數原型:

x,y,w,h=cv2.boundingRect(cnt)

(x,y)為矩形左上角的坐標;(w,h)是矩形的寬和高,通常情況下,cnt代表識別的輪廓。

之後我們利用cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2)畫出矩形。

參數解釋:

第一個參數:img是原圖。

第二個參數:(x,y)是矩陣的左上點坐標。

第三個參數:(x+w,y+h)是矩陣的右下點坐標。

第四個參數:(0,255,0)是畫線對應的rgb顏色。

第五個參數:2是所畫的線的寬度。

我們來看代碼:

import cv2
# 讀取圖片並轉至灰度模式img = cv2.imread("tubao.png", 1)gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 二值化,取閾值為235ret, thresh = cv2.threshold(gray, 235, 255, cv2.THRESH_BINARY)
# 尋找圖像中的輪廓contours, hierarchy = cv2.findContours(thresh, 2, 1)
cnt = contours[0]x, y, w, h = cv2.boundingRect(cnt)cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)
cv2.imshow('finger', img)cv2.waitKey()

可以看到一個外接矩形,但是它不是最小的外接矩形,接下來我們討論最小外接矩形。

▶旋轉的邊界矩形

這個邊界矩形是面積最小的,因為它考慮了對象的旋轉。

用到的函數為:

cv2.minAreaRect(cnt)

在這裡的cnt仍然跟上面的相同,該函數返回的是一個Box2D結構。

Box2D結構:

rect:(最小外接矩形的中心(x,y),(寬度,高度),旋轉角度)

但是要繪製此矩形,我們需要矩形的4個角。它是通過函cv2.boxPoints()獲得的。

我們來看代碼:

import cv2import numpy as np
# 讀取圖片並轉至灰度模式img = cv2.imread("tubao.png", 1)gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 二值化,取閾值為235ret, thresh = cv2.threshold(gray, 235, 255, cv2.THRESH_BINARY)
# 尋找圖像中的輪廓contours, hierarchy = cv2.findContours(thresh, 2, 1)
cnt = contours[0]
rect = cv2.minAreaRect(cnt)box = cv2.boxPoints(rect)box = np.int0(box)cv2.drawContours(img,[box],0,(0,0,255),2)
cv2.imshow('finger', img)cv2.waitKey()

可以看到,這裡得出的結果是最小外接矩形。

跟之前一樣,輪廓可以外接矩形,同時也可以外接圓形。接下來,我們使用函數cv.minEnclosingCircle()找到對象的外接圓。它是一個以最小面積完全覆蓋對象的圓圈。

函數原型:

center, radius=cv.minEnclosingCircle(points)

直接來看代碼:

import cv2import numpy as np
# 讀取圖片並轉至灰度模式img = cv2.imread("tubao.png", 1)gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 二值化,取閾值為235ret, thresh = cv2.threshold(gray, 235, 255, cv2.THRESH_BINARY)
# 尋找圖像中的輪廓contours, hierarchy = cv2.findContours(thresh, 2, 1)
cnt = contours[0]
(x, y), radius = cv2.minEnclosingCircle(cnt)center = (int(x), int(y))radius = int(radius)cv2.circle(img, center, radius, (0, 255, 0), 2)
cv2.imshow('finger', img)cv2.waitKey()

▶橢圓擬合

輪廓同樣也可以進行橢圓擬合,函數原型:

retval=cv.fitEllipse(points)

輸入參數跟之前的外界矩形是一樣的,就不一一詳述了。

代碼:

import cv2import numpy as np
# 讀取圖片並轉至灰度模式img = cv2.imread("tubao.png", 1)gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 二值化,取閾值為235ret, thresh = cv2.threshold(gray, 235, 255, cv2.THRESH_BINARY)
# 尋找圖像中的輪廓contours, hierarchy = cv2.findContours(thresh, 2, 1)
cnt = contours[0]
ellipse = cv2.fitEllipse(cnt)cv2.ellipse(img,ellipse,(0,255,0),2)
cv2.imshow('finger', img)cv2.waitKey()

▶直線擬合

同樣,我們可以將一條直線擬合到一組點。下圖包含一組白點,我們可以近似一條直線。

函數原型:

output=cv2.fitLine(InputArray  points, distType, param, reps, aeps)

InputArray Points: 待擬合的直線的集合,必須是矩陣形式.

distType: 距離類型。fitline為距離最小化函數,擬合直線時,要使輸入點到擬合直線的距離和最小化。這裡的距離的類型有以下幾種:

cv2.DIST_USER : User defined distance

cv2.DIST_L1: distance = |x1-x2| + |y1-y2|

cv2.DIST_L2: 歐式距離,此時與最小二乘法相同

cv2.DIST_C:distance = max(|x1-x2|,|y1-y2|)

cv2.DIST_L12:L1-L2 metric: distance = 2(sqrt(1+x*x/2) - 1))

cv2.DIST_FAIR:distance = c^2(|x|/c-log(1+|x|/c)), c = 1.3998

cv2.DIST_WELSCH: distance = c2/2(1-exp(-(x/c)2)), c = 2.9846

cv2.DIST_HUBER:distance = |x|<c |x^2/2 : c(|x|-c/2), c=1.345

param:距離參數,跟所選的距離類型有關,值可以設置為0。

reps, aeps:第5/6個參數用於表示擬合直線所需要的徑向和角度精度,通常情況下兩個值均被設定為1e-2。

output :對於二維直線,輸出output為4維,前兩維代表擬合出的直線的方向,後兩位代表直線上的一點。(即通常說的點斜式直線)。

代碼:

import cv2import numpy as np
# 讀取圖片並轉至灰度模式img = cv2.imread("tubao.png", 1)gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 二值化,取閾值為235ret, thresh = cv2.threshold(gray, 235, 255, cv2.THRESH_BINARY)
# 尋找圖像中的輪廓contours, hierarchy = cv2.findContours(thresh, 2, 1)
cnt = contours[0]
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)
cv2.imshow('finger', img)cv2.waitKey()

現在我們可以來一個實戰部分,用橢圓擬合來進行人眼識別之後標註出來,首先我們需要安裝dlib庫,這種一個人臉特徵檢測庫,接下來我們設置特徵檢測器,dlib有已經訓練的好的需要下載,也可以自己根據需要訓練:

下載連結

http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2

下載完之後解壓,將路徑放到根目錄裡面,當然了,下載是需要科學上網的,否則下載速度非常慢。

我們使用圖片:

代碼:

import cv2  import dlib  import numpy as np
detector = dlib.get_frontal_face_detector()landmark_predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')
img = cv2.imread("min.jpg")faces = detector(img,1)left_eye = []right_eye = []if ( len(faces) > 0): for k,d in enumerate(faces): shape = landmark_predictor(img,d) for i in range(36,42): right_eye.append([shape.part(i).x,shape.part(i).y]) for i in range(42,48): left_eye.append([shape.part(i).x,shape.part(i).y])ellipse_left = cv2.fitEllipse(np.array(left_eye))ellipse_right = cv2.fitEllipse(np.array(right_eye))cv2.ellipse(img, ellipse_left, (0,255,0), 1)cv2.ellipse(img, ellipse_right, (0,255,0), 1)
ellipse_left((275.1310119628906, 197.24081420898438),(13.491097450256348, 47.203433990478516),84.19256591796875)
center = ellipse_left[0]size = ellipse_left[1]angle = ellipse_left[2]
cv2.imshow('PIC',img)cv2.waitKey(0)

可以看到,人眼已經識別出來,並用橢圓進行了擬合,是不是很有趣。

本次我們主要討論輪廓的外界圖形,事實上它們都是非常有用的,下次我們將討論輪廓特徵的一些高階方法。

相關焦點

  • opencv-python圖像預處理-濾波
    頻率域是指從函數的頻率角度出發分析函數,對圖像進行傅立葉變換可以將圖像由圖像空間轉換到頻域空間,然後在頻率域中對圖像的頻譜作分析處理,以改變圖像的頻率特徵。空間域與頻率域是兩種不同的技術,都可以實現對圖像的濾波、增強,只是有些處理方式更適合在空間域完成,而有些則更適合在頻率域中完成。
  • OpenCV-Python 輪廓特徵|二十二
    目標在本文中,我們將學習如何找到輪廓的不同特徵,例如面積,周長,質心,邊界框等。您將看到大量與輪廓有關的功能。1. 特徵矩特徵矩可以幫助您計算一些特徵,例如物體的質心,物體的面積等。請查看特徵矩上的維基百科頁面。函數cv.moments()提供了所有計算出的矩值的字典。
  • 如何快速簡單的安裝opencv-python
    這樣就會從清華鏡像安裝opencv-contrib-python庫。目前opencv最新版本為4.1.1 ----2019-8-28在opencv-contrib-python 版本中含有額外模塊( Extra modules ),而 opencv-python 版本中只含有基礎模塊。
  • 使用OpenCV和Python構建自己的車輛檢測模型
    utm_source=blog&utm_medium=vehicle-detection-opencv-python)利用深度學習的計算機視覺(https://courses.analyticsvidhya.com/courses/computer-vision-using-deep-learning-version2?
  • 「python opencv視覺零基礎」十、圖片效果毛玻璃
    一、學習目標了解高斯模糊的使用方法了解毛玻璃的圖片效果添加了解如何自己做一個噪聲圖片目錄「python opencv 計算機視覺零基礎實戰」 第一節「python opencv視覺入門到實戰」二、格式與攝像頭「python opencv 視覺入門到實戰」 三、圖像編輯「python opencv視覺入門到實戰
  • 「python opencv視覺零基礎」十四、直方圖反向投影
    前文提醒:博主正在參加博客之星評比,成功入選Top200,現在暫居第九歡迎各位點擊了解更多幫我投票,非常感謝~目錄「python opencv 計算機視覺零基礎實戰」 第一節「python opencv視覺入門到實戰」二、格式與攝像頭「python opencv 視覺入門到實戰」 三、圖像編輯「python
  • 基於opencv 的圖像處理入門教程
    /opencv_noteshttps://github.com/ccc013/CodesNotes/blob/master/opencv_notes/opencv_image_process_tutorial.ipynb1.
  • OpenCV中的快速直線檢測
    本文範例運行環境FastLineDetectors運行必要條件FastLineDetectors屬於opencv-contrib中的模塊,需要安裝opencv-contrib-python。在python的opencv相關的安裝包中,opencv-python 包含主要模塊,opencv-contrib-python 包含主要模塊以及一些擴展模塊。但這兩個模塊並不兼容,如果已經安裝過opencv-python,需要先卸載,再安裝opencv-contrib-python。
  • 「python opencv視覺零基礎實戰」七邏輯運算應用
    一、學習目標了解opencv中圖像的邏輯運算了解opencv中邏輯運算的應用如有錯誤歡迎指出~目錄「python opencv 計算機視覺零基礎實戰」 第一節「python opencv視覺入門到實戰」二、格式與攝像頭「python opencv 視覺入門到實戰」 三、圖像編輯「python
  • 「python opencv計算機視覺零基礎到實戰」九模糊
    一、學習目標了解什麼是卷積了解模糊的使用方法與應用目錄「python opencv 計算機視覺零基礎實戰」 第一節「python opencv視覺入門到實戰」二、格式與攝像頭「python opencv 視覺入門到實戰」 三、圖像編輯「python opencv視覺入門到實戰」 第四節色彩空間
  • Python中如何利用Opencv打開視頻或圖像並用PyQt控制項顯示
    一、python中opencv打開圖像方法:import cv2filename='dog.jpg'img=cv2.imread(filename)cv2.imshow('Main Window',img)cv2.waitKey() #任意鍵退出cv2.destroyAllWindows()二、python中用opencv打開視頻頭的方法:
  • opencv-python獲取圖像:面向對象與面向過程
    這裡需要注意以下,opencv讀取圖片默認通道為BGR的格式,當在其他UI用戶界面顯示圖像時注意轉換一下通道順序,例如BGR轉換成RGB:Image1=cv2.cvtColor(image, cv2.COLOR_BGR2RGB)下面讀取一張圖片並顯示
  • 「python opencv視覺零到實戰」八、圖片選區操作
    一、學習目標了解什麼是ROI了解floodFill的使用方法如有錯誤歡迎指出~目錄「python opencv 計算機視覺零基礎實戰」 第一節「python opencv視覺入門到實戰」二、格式與攝像頭「python opencv 視覺入門到實戰」 三、圖像編輯「python opencv視覺入門到實戰
  • 資料| Practical Python and OpenCV 一周時間帶你入門CV
  • OpenCV(四)邊緣檢測
    邊緣檢測的方法有很多,但是絕大部分都可以分為兩大類,第一類是基於搜索,也就是通過尋找圖像一階導數中的最大值和最小值來檢測邊界,通常是定位在梯度最大的方向。其次是基於零穿越的方法,其通過尋找圖像二階導數零穿越來尋找便捷,通常是Laplacian過零點或者非線性差分表示的過零點。
  • OpenCV特徵點檢測——ORB特徵
    這個特徵描述子是由EPFL的Calonder在ECCV2010上提出的。主要思路就是在特徵點附近隨機選取若干點對,將這些點對的灰度值的大小,組合成一個二進位串,並將這個二進位串作為該特徵點的特徵描述子。
  • OpenCV測量物體的尺寸技能 get~
    實際上相當於參考物的作用,例如已知圖上的參考物多大,我們便可以利用這個參考物體換算到圖上其他物體的尺寸大小。edged = cv2.Canny(gray, 50, 100)edged = cv2.dilate(edged, None, iterations=1)edged = cv2.erode(edged, None, iterations=1)# 在邊緣圖中查找輪廓cnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL,
  • OpenCV-Python 輪廓屬性|二十三
    更多的功能可以在Matlab regionprops文檔中找到。(注:質心、面積、周長等也屬於這一類,但我們在上一章已經見過)1. 長寬比它是對象邊界矩形的寬度與高度的比值。x,y,w,h = cv.boundingRect(cnt)aspect_ratio = float(w)/h2. 範圍範圍是輪廓區域與邊界矩形區域的比值。
  • 基於python+OpenCV模塊的人臉識別定位技術
    本文將基於OpenCV模塊,在windows作業系統上,利用python語言,進行人臉識別技術的研究。當然OpenCV的應用領域很廣,除了人臉識別之外,它還支持圖像分割、動作識別、視頻處理等技術。代碼第1行導入opencv模塊。代碼的第3行(以上圖為準,空行也算一行),導入別人已經訓練好的臉部識別資料庫。這裡用到的數據是在github上開源的已經訓練好的分類器,如圖所示:需要將對應的數據文件(.xml文件)下載到指定目錄(代碼中的示例,展示的是與.py文件同一目錄下)。
  • 基於OpenCv 和 Python 的手指識別及追蹤
    翻譯 | 餘杭 Lamaric 校對 | 吳曉曼 審核 | 餘杭詳細代碼參考:https://github.com/amarlearning/opencv手指追蹤是許多計算機視覺應用的重要特徵。在該應用中,使用基於直方圖的方法將手與背景幀分離。