pyhton opencv中cv2.findContours與cv2.drawContours

最近在做關於圖像識別的東西,用到了尋找輪廓函數cv2.findContours和繪製輪廓函數cv2.drawContours
先看看cv2.findContours的定義:
如果嫌囉嗦(不想看英語),直接下拉,下面我有寫用法與總結

def findContours(image, mode, method, contours=None, hierarchy=None, offset=None): # real signature unknown; restored from __doc__
    """
    findContours(image, mode, method[, contours[, hierarchy[, offset]]]) -> contours, hierarchy
    .   @brief Finds contours in a binary image.
    .   
    .   The function retrieves contours from the binary image using the algorithm @cite Suzuki85 . The contours
    .   are a useful tool for shape analysis and object detection and recognition. See squares.cpp in the
    .   OpenCV sample directory.
    .   @note Since opencv 3.2 source image is not modified by this function.
    .   
    .   @param image Source, an 8-bit single-channel image. Non-zero pixels are treated as 1's. Zero
    .   pixels remain 0's, so the image is treated as binary . You can use #compare, #inRange, #threshold ,
    .   #adaptiveThreshold, #Canny, and others to create a binary image out of a grayscale or color one.
    .   If mode equals to #RETR_CCOMP or #RETR_FLOODFILL, the input can also be a 32-bit integer image of labels (CV_32SC1).
    .   @param contours Detected contours. Each contour is stored as a vector of points (e.g.
    .   std::vector<std::vector<cv::Point> >).
    .   @param hierarchy Optional output vector (e.g. std::vector<cv::Vec4i>), containing information about the image topology. It has
    .   as many elements as the number of contours. For each i-th contour contours[i], the elements
    .   hierarchy[i][0] , hierarchy[i][1] , hierarchy[i][2] , and hierarchy[i][3] are set to 0-based indices
    .   in contours of the next and previous contours at the same hierarchical level, the first child
    .   contour and the parent contour, respectively. If for the contour i there are no next, previous,
    .   parent, or nested contours, the corresponding elements of hierarchy[i] will be negative.
    .   @param mode Contour retrieval mode, see #RetrievalModes
    .   @param method Contour approximation method, see #ContourApproximationModes
    .   @param offset Optional offset by which every contour point is shifted. This is useful if the
    .   contours are extracted from the image ROI and then they should be analyzed in the whole image
    .   context.
    """
    pass

cv2.drawContours的定義:

def drawContours(image, contours, contourIdx, color, thickness=None, lineType=None, hierarchy=None, maxLevel=None, offset=None): # real signature unknown; restored from __doc__
    """
    drawContours(image, contours, contourIdx, color[, thickness[, lineType[, hierarchy[, maxLevel[, offset]]]]]) -> image
    .   @brief Draws contours outlines or filled contours.
    .   
    .   The function draws contour outlines in the image if \f$\texttt{thickness} \ge 0\f$ or fills the area
    .   bounded by the contours if \f$\texttt{thickness}<0\f$ . The example below shows how to retrieve
    .   connected components from the binary image and label them: :
    .   @include snippets/imgproc_drawContours.cpp
    .   
    .   @param image Destination image.
    .   @param contours All the input contours. Each contour is stored as a point vector.
    .   @param contourIdx Parameter indicating a contour to draw. If it is negative, all the contours are drawn.
    .   @param color Color of the contours.
    .   @param thickness Thickness of lines the contours are drawn with. If it is negative (for example,
    .   thickness=#FILLED ), the contour interiors are drawn.
    .   @param lineType Line connectivity. See #LineTypes
    .   @param hierarchy Optional information about hierarchy. It is only needed if you want to draw only
    .   some of the contours (see maxLevel ).
    .   @param maxLevel Maximal level for drawn contours. If it is 0, only the specified contour is drawn.
    .   If it is 1, the function draws the contour(s) and all the nested contours. If it is 2, the function
    .   draws the contours, all the nested contours, all the nested-to-nested contours, and so on. This
    .   parameter is only taken into account when there is hierarchy available.
    .   @param offset Optional contour shift parameter. Shift all the drawn contours by the specified
    .   \f$\texttt{offset}=(dx,dy)\f$ .
    .   @note When thickness=#FILLED, the function is designed to handle connected components with holes correctly
    .   even when no hierarchy date is provided. This is done by analyzing all the outlines together
    .   using even-odd rule. This may give incorrect results if you have a joint collection of separately retrieved
    .   contours. In order to solve this problem, you need to call #drawContours separately for each sub-group
    .   of contours, or iterate over the collection using contourIdx parameter.
    """
    pass

好吧,一堆英文,看的頭蒙。我來總結一下吧
cv2.findContours一共有:

def findContours(image, mode, method, contours=None, hierarchy=None, offset=None):

這麼幾個參數:
image : 傳入的圖像,
注意一定要是二值圖像,(cv2讀圖片時,用 cv2.imread(imgpath , 0) 即可,注意第二個參數是0)

mode : 輪廓檢索方式
cv2.RETR_TREE:建立一個等級樹結構的輪廓
cv2.RETR_EXTERNAL:只檢測外輪廓
cv2.RETR_LIST:檢測的輪廓不建立等級關係
cv2.RETR_CCOMP:建立兩個等級的輪廓,上面一層爲外邊界,裏面一層爲內孔的邊界信息

method : 輪廓近似方法

cv2.CHAIN_APPROX_NONE: 存儲所有邊界點
cv2.CHAIN_APPROX_SIMPLE: 壓縮垂直、水平、對角方向,只保留端點
cv2.CHAIN_APPROX_TX89_L1: 使用teh-Chini近似算法
cv2.CHAIN_APPROX_TC89_KCOS: 使用teh-Chini近似算法

返回值:注意,在opencv3.2後返回值只有兩個:contours, hierarchy,之前的返回值有三個image, contours, hierarchy

一般這樣搭配使用:

contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

當使用cv2.CHAIN_APPROX_NONE存儲所有輪廓點時,返回的contours是一個列表,每一項是一個輪廓信息,每一個輪廓信息是一個(n , 1 , 2)維的numpy.ndarray,n是座標的個數。
在這裏插入圖片描述
利用cv2.drawContours可以將之前找到的輪廓畫出來

def drawContours(image, contours, contourIdx, color, thickness=None, lineType=None, hierarchy=None, maxLevel=None, offset=None):

別看有這麼多參數,實際上用的最多的是前幾個:
image
傳入的圖像,在這張圖上畫,注意,drawContours本身會直接修改image,不需要返回值,所以在傳入圖片前先備份一下原圖,一般用:img = image * 1,這裏image是np.array,乘一相當於複製了一份,注注意:如果img = image這樣直接賦值,是沒有用的,修改img照樣會修改image,這是因爲深拷貝與淺拷貝的不同,這裏image * 1是一個小技巧,但正規的深拷貝應該用copy這個函數,(還得導包,所以偷個懶,直接乘 1)

contours:
這個是一個列表,注意是一個列表是一個列表是一個列表,可以直接將剛纔用findContours找出來的contours給他,也可以是自己給出的一組座標信息。

contourIdx:顧名思義,就是要畫的輪廓下標, -1表示畫出全部的輪廓。比如剛纔找出來的contours,在將-1給到contourIdx,就會把所有輪廓畫出來。

color:畫線的顏色:例如(0,0,255)

thickness: 畫線的粗細,-1則爲填充

一般用法:

cv2.drawContours(img, contours, -1, (255, 255, 255), -1)

注意:如果想畫contours中的某個輪廓,一定要取出來放到列表裏,像這樣:

c = []
c.append(contours[3])
cv2.drawContours(img, c, -1, (255, 255, 255), -1)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章