
example
import cv2 as cv
import numpy as np
def edge_demo(image):
blurred = cv.GaussianBlur(image, (3, 3), 0)
gray = cv.cvtColor(blurred, cv.COLOR_BGR2GRAY)
grad_x = cv.Sobel(gray, cv.CV_16SC1, 1, 0)
grad_y = cv.Sobel(gray, cv.CV_16SC1, 0, 1)
# edge_output = cv.Canny(grad_x, grad_y, 30, 150)
edge_output = cv.Canny(gray, 50, 150)
return edge_output
def contours_demo(image):
"""
. 輪廓可以簡單認為成將連續的點(連着邊界)連在一起的曲線,具有相同 的顏色或者灰度。
輪廓在形狀分析和物體的檢測和識別中很有用。
. 為了更加准確,要使用二值化圖像。在尋找輪廓之前,要進行閾值化處理或者 Canny 邊界檢測
. 查找輪廓的函數會修改原始圖像。如果你在找到輪廓之后還想使用原始圖像的話,
你應該將原始圖像存儲到其他變量中.
. 在 OpenCV 中,查找輪廓就像在黑色背景中超白色物體。要找的物體應該是白色而背景應該是黑色。
"""
# dst = cv.GaussianBlur(image, (3, 3), 0)
# gray = cv.cvtColor(dst, cv.COLOR_BGR2GRAY)
# ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
# cv.imshow("binary image", binary)
binary = edge_demo(image)
"""
• 函數 cv2.findContours() 有三個參數, 第一個是輸入圖像,第二個是輪廓檢索模式,第三個是輪廓近似方法。
• 檢索模式:
• CV_RETR_EXTERNAL - 只提取外層的輪廓
• CV_RETR_LIST - 提取所有輪廓,並且放置在 list 中
• CV_RETR_CCOMP - 提取所有輪廓,並且將其組織為兩層的 hierarchy:
頂層為連通域的 外圍邊界,次層為洞的內層邊界。
• CV_RETR_TREE - 提取所有輪廓,並且重構嵌套輪廓的全部 hierarchy
• 逼近方法 (對所有節點, 不包括使用內部逼近的 CV_RETR_RUNS). 點的存貯情況,是不是都被存貯
• CV_CHAIN_CODE - Freeman 鏈碼的輸出輪廓. 其它方法輸出多邊形(定點序列).
• CV_CHAIN_APPROX_NONE - 將所有點由鏈碼形式翻譯為點序列形式
• CV_CHAIN_APPROX_SIMPLE - 壓縮水平、垂直和對角分割,即函數只保留末端的象素 點;
• CV_CHAIN_APPROX_TC89_L1, CV_CHAIN_APPROX_TC89_KCOS - 應用 Teh-Chin 鏈逼近算法.
• CV_LINK_RUNS - 通過連接為 1 的水平碎片使用完全不同的輪廓提取算法。僅有 CV_RETR_LIST 提取模式可以在本方法中應用.
• offset:每一個輪廓點的偏移量. 當輪廓是從圖像 ROI 中提取出來的時候,使用偏移量有用,因為可以從整個圖像上下文來對輪廓做分析.
• 返回值有三個,第一個是圖像,第二個是輪廓,第三個是(輪廓的)層析結構。
輪廓(第二個返回值)是一個 Python 列表,其中存儲這圖像中的所有輪廓。
每一個輪廓都是一個 Numpy 數組,包含對象邊界點(x,y)的坐標。
"""
contours, hierarchy= cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
for i, contour in enumerate(contours):
# 函數 cv2.drawContours() 可以被用來繪制輪廓。它可以根據你提供的邊界點繪制任何形狀。
# 它的第一個參數是原始圖像,第二個參數是輪廓,一個 Python 列表。
# 第三個參數是輪廓的索引(在繪制獨立輪廓是很有用,當設 置為 -1 時繪制所有輪廓)。
# 接下來的參數是輪廓的顏色和厚度等。
cv.drawContours(image, contours, i, (0, 0, 255), 2) # 2為像素大小,-1時填充輪廓
print(i)
cv.imshow("detect contours", image)
cv.imwrite("a.jpg", image)
def main():
src = cv.imread("../images/CrystalLiu2.jpg")
cv.imshow("demo", src)
contours_demo(src)
cv.waitKey(0) # 等有鍵輸入或者1000ms后自動將窗口消除,0表示只用鍵輸入結束窗口
cv.destroyAllWindows() # 關閉所有窗口
if __name__ == '__main__':
main()