Improve contour detection with OpenCV (Python)

后端 未结 2 1795
孤街浪徒
孤街浪徒 2021-01-31 05:52

I am trying to identify cards from a photo. I managed to do what I wanted on ideal photos, but I am now having hard time applying the same procedure with slightly different ligh

2条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2021-01-31 06:36

    Why not just use Canny and apply perspective correction after finding the contours (because it seems to blur the edges)? For example, using the small image you provided in your question (the result could be better on a bigger one):

    Based on some parts of your code:

    import numpy as np
    import cv2
    
    import math
    
    img = cv2.imread('image.bmp')
    
    # Prepocess
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    flag, thresh = cv2.threshold(gray, 120, 255, cv2.THRESH_BINARY)
    
    # Find contours
    img2, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    contours = sorted(contours, key=cv2.contourArea, reverse=True) 
    
    # Select long perimeters only
    perimeters = [cv2.arcLength(contours[i],True) for i in range(len(contours))]
    listindex=[i for i in range(15) if perimeters[i]>perimeters[0]/2]
    numcards=len(listindex)
    
    card_number = -1 #just so happened that this is the worst case
    stencil = np.zeros(img.shape).astype(img.dtype)
    cv2.drawContours(stencil, [contours[listindex[card_number]]], 0, (255, 255, 255), cv2.FILLED)
    res = cv2.bitwise_and(img, stencil)
    cv2.imwrite("out.bmp", res)
    canny = cv2.Canny(res, 100, 200)
    cv2.imwrite("canny.bmp", canny)
    

    First, remove everything except a single card for simplicity, then apply Canny edge detector:

    Then you can dilate/erode, correct perspective, remove the largest contour etc.

提交回复
热议问题