'Opencv rotate camera mode

I want to rotate the camera view by 90 degree clockwise with an interrupt button. But the button's state goes back to it's default state when I click once and unpress the button. As a result, on clicking the button, the camera rotates for an instance and then goes back to the default mode in the while loop. How to solve this issue?

Here is my snippet:

import cv2

cap = cv2. VideoCapture(0) 

while True:
    ret, frame = cap.read()
    cv2.imshow('null', frame)
    
    if (button):
        frame = cv2.rotate(frame, cv2.ROTATE_90_CLOCKWISE)
        cv2.imshow('null', frame)

    if cv2.waitKey(5) & 0xFF == 27:
        break
cap.release()

Any help would be appreciated.



Solution 1:[1]

You should use extra variable - rotate = False - to keep this state

rotate = False

while True:

    ret, frame = cap.read()
    # without imshow()

    if button_a.is_pressed(): 
         rotate = True

    if rotate:
         frame = cv2.rotate(frame, cv2.ROTATE_90_CLOCKWISE)

    # outside `if`
    cv2.imshow('null', frame)

This way it changes rotate from False to True but never from True to False


EDIT:

If next press should rotate another 90 degrees (to 180) then it would need more complex code. It would check if is_pressed() in previous loop was False and in current loop is True - to run it only once when button is pressed long time.

Something like this.

I used normal space to test it.

import cv2

cap = cv2.VideoCapture(0)

rotate = 0

is_pressed = False

previous = False
current  = False

while True:

    ret, frame = cap.read()
    # without imshow()

    current = is_pressed
    if (previous is False) and (current is True): 
         rotate = (rotate + 90) % 360
         print(rotate)
    previous = current

    if rotate == 90:
         frame = cv2.rotate(frame, cv2.ROTATE_90_CLOCKWISE)
    elif rotate == 180:
         frame = cv2.rotate(frame, cv2.ROTATE_180)
    elif rotate == 270:
         frame = cv2.rotate(frame, cv2.ROTATE_90_COUNTERCLOCKWISE)

    # outside `if`
    cv2.imshow('null', frame)
    
    key = cv2.waitKey(40) & 0xff
    
    if key == 27:
        break
    
    is_pressed = (key == 32)
        
cv2.destroyAllWindows()
cap.release()

Solution 2:[2]

import cv2

cap = cv2. VideoCapture(0) 
button_is_pressed = false;

while True:
    ret, frame = cap.read()
    
    if (button):
        button_is_pressed = not button_is_pressed 

    if(button_is_pressed)
        frame = cv2.rotate(frame, cv2.ROTATE_90_CLOCKWISE)
        cv2.imshow('null', frame)
        
cap.release()

I would try something like this, when you press the button it changes the state of variable button_is_pressed, while still unchanged it keeps rotating image.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 pedro_bb7