简体   繁体   中英

Recursive function does not work as desired

I read the attached image with cv2.imread and want to find the contours of the image object. If the threshold is too large, ie if cv2.findContours finds several outlines, the threshold should be reduced piece by piece so that only one contour is found at the end. That's why I wrote the recursive function thresholdloop , but unfortunately it doesn't do what it should.

import cv2   

b = cv2.imread("test.tiff")

thresh_factor = 140


imgray_b = cv2.cvtColor(b,cv2.COLOR_BGR2GRAY)
ret_b,thresh_b = cv2.threshold(imgray_b,thresh_factor,255,0)

_, cb, _ = cv2.findContours(thresh_b, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)


def thresholdloop(cb, thresh_factor, X):

    while X == False:
        if len(cb) > 1:
            thresh_factor = thresh_factor - 5
            ret_b, thresh_b = cv2.threshold(imgray_b, thresh_factor, 255, 0)
            _, cb, _ = cv2.findContours(thresh_b, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)
            X = False
            return thresholdloop(cb, thresh_factor, X)
        else:
            X = True

X = False
thresholdloop(cb, thresh_factor, X)

依恋

The problem seems to be that your function tries to modify global variables without using the global keyword. You could fix it by removing all the parameters from the function and instead doing

def thresholdloop():
    global ret_b
    global cb
    global thresh_b
    global thresh_factor
    # rest of function

But instead I'd suggest using a simple while loop in the global scope itself (ie no function)

# after first calculation of cb
while len(cb) > 1:
    thresh_factor = thresh_factor - 5
    ret_b, thresh_b = cv2.threshold(imgray_b, thresh_factor, 255, 0)
    _, cb, _ = cv2.findContours(thresh_b, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)

Or like this, so you don't have to replicate the code for calculating cb inside the loop and before

b = cv2.imread("test.tiff")
thresh_factor = 145  # + 5
imgray_b = cv2.cvtColor(b,cv2.COLOR_BGR2GRAY)
while True:
    thresh_factor = thresh_factor - 5
    ret_b, thresh_b = cv2.threshold(imgray_b, thresh_factor, 255, 0)
    _, cb, _ = cv2.findContours(thresh_b, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)
    if len(cb) == 1:
        break

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM