Search code examples
pythonopencvcontour

How to change bounding rect values of contour in OpenCV Python?


I want to change the value of the width of the next contour. I tried to do it this way but it turns out that it still retains the original values of contours. How do I do this? Thank you in advance.

UPDATE: This is the actual code I am working on.

temp = 0; #Holds the last element we iterated replaced value
for i,c in enumerate(contours2):
    [x, y, w, h] = cv2.boundingRect(contours2[i])

    if i in percentiles: #if the current index is in the percentiles array
        [i, j, k, l] = cv2.boundingRect(contours2[temp]) #Get contour values of element to overwrite
        k = (x+w)-i 
        temp=i+1;   
#DRAW
for c in contours2: #when I draw it the k value of the overwritten elements doesn't change,why?
    [x, y, w, h] = cv2.boundingRect(c)
    cv2.rectangle(image, (x, y), (x + w, y + h), (255, 0, 0), 2)

Solution

  • There's a misconception here, purely with Python that has nothing to do with OpenCV. Check the following code:

    >>> a = 5
    >>> b = a
    >>> a = 7
    >>> a
    7
    >>> b
    5
    

    When I set b = a, I'm setting b to have the same current value as a, but I'm not actually creating a new name for a. That means that later if I change the value of a, it doesn't affect the value of b. This is relevant because in your code, you're writing:

    [i, j, k, l] = cv2.boundingRect(contours2[temp])
    k = (x+w)-i 
    

    as if this modifies the contour. It doesn't; it just modifies the variable k. And you're simply overwriting k at each iteration of the loop.

    Further, the bounding box is not the same thing as the contour. The contour hasn't been changed at all, because you're not modifying the contours2 variable. You need to know whether you actually want the bounding box or the contour. The contour is a list of points which outline the contour shape. The bounding box is just that, the minimum size vertical/horizontal box that fits over your contour points. If you want to take the bounding box and modify it, then you should store the bounding box into a variable; in particular, if you're storing multiple bounding boxes, you'll want to store them into a list. For example:

    bounding_boxes = []
    for c in contours2:
        [x, y, w, h] = cv2.boundingRect(c)
        bounding_boxes.append([x, y, w, h])
    

    This will give you a list where the ith element is the bounding box around the ith contour. If you wanted to modify the bounding box that is stored, simply do it before you append it to the list:

    bounding_boxes = []
    for c in contours2:
        [x, y, w, h] = cv2.boundingRect(c)
        w = w*2
        bounding_boxes.append([x, y, w, h])
    

    What your code should be doing isn't completely clear to me, so I can't give you a fixed version, but hopefully this will get you headed in the right direction.