html5 開發(fā)網站網站排名提升軟件
文章目錄
- 1、功能描述
- 2、代碼實現
- 3、完整代碼
- 4、結果展示
- 5、涉及到的庫函數
- 5.1、cv2.Canny
- 5.2 cv2.boxPoints
- 6、參考
1、功能描述
找出圖片中的輪廓,擬合輪廓外接橢圓和外接矩陣
2、代碼實現
導入必要的庫,固定好隨機種子
import cv2 as cv
import numpy as np
import argparse
import random as rngrng.seed(12345)
讀取輸入圖片,判定圖片是否讀入成功
parser = argparse.ArgumentParser(description='Code for Creating Bounding rotated boxes and ellipses for contours tutorial.')
parser.add_argument('--input', help='Path to input image.', default='1.png')
args = parser.parse_args()
src = cv.imread(cv.samples.findFile(args.input))if src is None:print('Could not open or find the image:', args.input)exit(0)
灰度化圖片,并平滑
# Convert image to gray and blur it
src_gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
src_gray = cv.blur(src_gray, (3, 3))
source_window = 'Source'
cv.namedWindow(source_window)
cv.imshow(source_window, src)
創(chuàng)建滾動條,動態(tài)配置參數,隨著滑動條的滑動實現不同的算法效果
max_thresh = 255
thresh = 100 # initial threshold
cv.createTrackbar('Canny Thresh:', source_window, thresh, max_thresh, thresh_callback)
thresh_callback(thresh)
cv.waitKey()
算法核心函數 thresh_callback
,下面具體看看細節(jié)
def thresh_callback(val):global src_graythreshold = valsrc_gray = cv.GaussianBlur(src_gray, (3, 3), 0.1)canny_output = cv.Canny(src_gray, threshold, threshold * 2)
高斯模糊,canny 算子
contours, _ = cv.findContours(canny_output, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)# Find the rotated rectangles and ellipses for each contourminRect = [None] * len(contours)minEllipse = [None] * len(contours)for i, c in enumerate(contours):minRect[i] = cv.minAreaRect(c)if c.shape[0] > 5:minEllipse[i] = cv.fitEllipse(c)# Draw contours + rotated rects + ellipses
找出輪廓,遍歷輪廓,最小外接矩形框直接調用 cv2.minAreaRect
即可
如果輪廓多于 5 個點,cv2.fiEllipse
找橢圓
# Draw contours + rotated rects + ellipsesdrawing = np.zeros((canny_output.shape[0], canny_output.shape[1], 3), dtype=np.uint8)for i, c in enumerate(contours):color = (rng.randint(0, 256), rng.randint(0, 256), rng.randint(0, 256))# contourcv.drawContours(drawing, contours, i, color)# ellipseif c.shape[0] > 5:cv.ellipse(drawing, minEllipse[i], color, 2)# rotated rectanglebox = cv.boxPoints(minEllipse[i])# box = cv.boxPoints(minRect[i])box = np.intp(box) # np.intp: Integer used for indexing (same as C ssize_t; normally either int32 or int64)# box = np.int0(box) # normally either int32 or int64)cv.drawContours(drawing, [box], 0, color)cv.imshow('Contours', drawing)cv.imshow("Canny", canny_output)
繪制輪廓,輪廓外接矩陣,輪廓擬合出來的橢圓,隨機顏色
注意 box = cv.boxPoints(minEllipse[i])
繪制的是橢圓的外接矩陣,而 box = cv.boxPoints(minRect[i])
繪制輪廓的外接矩陣被注釋掉了
3、完整代碼
import cv2 as cv
import numpy as np
import argparse
import random as rngrng.seed(12345)def thresh_callback(val):global src_graythreshold = valsrc_gray = cv.GaussianBlur(src_gray, (3, 3), 0.1)canny_output = cv.Canny(src_gray, threshold, threshold * 2)contours, _ = cv.findContours(canny_output, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)# Find the rotated rectangles and ellipses for each contourminRect = [None] * len(contours)minEllipse = [None] * len(contours)for i, c in enumerate(contours):minRect[i] = cv.minAreaRect(c)if c.shape[0] > 5:minEllipse[i] = cv.fitEllipse(c)# Draw contours + rotated rects + ellipsesdrawing = np.zeros((canny_output.shape[0], canny_output.shape[1], 3), dtype=np.uint8)for i, c in enumerate(contours):color = (rng.randint(0, 256), rng.randint(0, 256), rng.randint(0, 256))# contourcv.drawContours(drawing, contours, i, color)# ellipseif c.shape[0] > 5:cv.ellipse(drawing, minEllipse[i], color, 2)# rotated rectanglebox = cv.boxPoints(minEllipse[i])# box = cv.boxPoints(minRect[i])box = np.intp(box) # np.intp: Integer used for indexing (same as C ssize_t; normally either int32 or int64)# box = np.int0(box) # normally either int32 or int64)cv.drawContours(drawing, [box], 0, color)cv.imshow('Contours', drawing)cv.imshow("Canny", canny_output)parser = argparse.ArgumentParser(description='Code for Creating Bounding rotated boxes and ellipses for contours tutorial.')
parser.add_argument('--input', help='Path to input image.', default='1.png')
args = parser.parse_args()
src = cv.imread(cv.samples.findFile(args.input))if src is None:print('Could not open or find the image:', args.input)exit(0)# Convert image to gray and blur it
src_gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
src_gray = cv.blur(src_gray, (3, 3))
source_window = 'Source'
cv.namedWindow(source_window)
cv.imshow(source_window, src)
max_thresh = 255
thresh = 100 # initial threshold
cv.createTrackbar('Canny Thresh:', source_window, thresh, max_thresh, thresh_callback)
thresh_callback(thresh)
cv.waitKey()
4、結果展示
Canny Thresh:0
Canny Thresh:5
Canny Thresh:15
Canny Thresh:25
Canny Thresh:35
Canny Thresh:45
Canny Thresh:100
Canny Thresh:150
Canny Thresh:200
Canny Thresh:255
5、涉及到的庫函數
5.1、cv2.Canny
cv2.Canny
是 OpenCV 庫中用于邊緣檢測的一個函數,它實現了 Canny 邊緣檢測算法。Canny 邊緣檢測是一種非常流行的邊緣檢測算法,由 John F. Canny 在 1986 年提出。這個算法旨在尋找圖像中的最優(yōu)邊緣,它通過應用多尺度高斯濾波來減少噪聲,然后計算圖像梯度,接著通過非極大值抑制和滯后閾值化來檢測邊緣。
edges = cv2.Canny(image, threshold1, threshold2[, edges[, apertureSize[, L2gradient]]])
- image:輸入的灰度圖像。在進行 Canny 邊緣檢測之前,通常需要先將圖像轉換為灰度圖像。
- threshold1:第一個閾值,用于滯后閾值化中的低閾值。
- threshold2:第二個閾值,用于滯后閾值化中的高閾值。只有那些梯度值高于 threshold2 的像素才會被當作邊緣,而梯度值位于 threshold1 和 threshold2 之間的像素只有在它們連接到高閾值邊緣時才會被接受。
- edges:輸出參數,用于存儲檢測到的邊緣。如果不指定,則會自動創(chuàng)建一個同大小的輸出圖像。
- apertureSize:Sobel 算子的大小,默認為 3。這個參數影響梯度計算的精度,但增加大小也會增加計算時間。
- L2gradient:一個布爾值,指示是否使用更精確的 L2 范數來計算圖像梯度幅值。默認值為 False,即使用 L1 范數(即簡單地將梯度在 x 和 y 方向的分量相加)。
返回值:
- edges:一個二值圖像,其中檢測到的邊緣像素被設置為白色(255),其他像素被設置為黑色(0)。
Canny 邊緣檢測的優(yōu)點在于它能夠有效地抑制噪聲,并且檢測到的邊緣通常是連續(xù)的。然而,它的效果也依賴于所選的閾值,因此在實際應用中,可能需要根據具體情況調整 threshold1 和 threshold2 的值。
5.2 cv2.boxPoints
cv2.boxPoints
用于計算給定矩形旋轉后的頂點坐標。這個函數在需要處理旋轉矩形時非常有用,比如在圖像中繪制旋轉的邊界框時。
points = cv2.boxPoints(box[, rotMat])
參數解釋:
- box:表示矩形的參數。這可以是一個包含四個元素的元組或列表 (center_x, center_y, width, height),其中 (center_x, center_y) 是矩形中心的坐標,width 和 height 分別是矩形的寬度和高度(注意:這里的寬度和高度是按照矩形的原始大小,不考慮旋轉)。在某些版本的 OpenCV 中,box 也可能是一個 cv2.RotatedRect 對象。
- rotMat:可選參數,表示旋轉矩陣。這是一個 2x3 的浮點數數組,用于指定對矩形進行額外旋轉的角度。如果未提供此參數,則矩形不會被額外旋轉,只返回根據 box 參數計算出的四個頂點坐標。
返回值:
- points:一個包含四個點的 NumPy 數組,每個點都是一個包含兩個元素的元組或列表 (x, y),表示旋轉后矩形的頂點坐標。
需要注意的是,如果 box 是一個 cv2.RotatedRect 對象,那么它本身就包含了旋轉信息(即旋轉角度和中心點),此時 rotMat 參數將被忽略,因為 cv2.RotatedRect 已經定義了矩形的旋轉狀態(tài)。
示例代碼:
import cv2
import numpy as np # 定義一個中心點、寬度、高度的矩形
center = (100, 100)
width = 200
height = 100
angle = 45 # 旋轉角度(以度為單位) # 創(chuàng)建一個旋轉矩形對象
rect = cv2.RotatedRect(center, (width, height), angle) # 獲取旋轉矩形的頂點
points = cv2.boxPoints(rect)
points = np.intp(points) # 將坐標轉換為整數類型,以便在圖像上繪制 # 創(chuàng)建一個黑色圖像
image = np.zeros((256, 256, 3), dtype=np.uint8) # 在圖像上繪制旋轉矩形的邊
for i in range(4): cv2.line(image, tuple(points[i]), tuple(points[(i+1)%4]), (255, 0, 0), 2)
# 顯示圖像
cv2.imshow('Rotated Rectangle', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
在這個示例中,我們首先定義了一個矩形的中心點、寬度、高度和旋轉角度,然后創(chuàng)建了一個 cv2.RotatedRect 對象來表示這個旋轉矩形。接著,我們使用 cv2.boxPoints 函數來獲取旋轉矩形的頂點坐標,并在一個黑色圖像上繪制了這個矩形的邊。最后,我們顯示了包含旋轉矩形的圖像。
6、參考
- 根據輪廓創(chuàng)建旋轉框和橢圓
- 【python】OpenCV—findContours(4.2)